feat(exhaustiveness): show both clauses in redundant error
This commit is contained in:
parent
ef2fc57ca9
commit
b6ac39f322
|
@ -1434,8 +1434,8 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that the given patterns are exhaustive for given type.
|
/// Checks that the given patterns are exhaustive for given type.
|
||||||
/// Currently only performs exhaustiveness checking for custom types,
|
/// https://github.com/elm/compiler/blob/047d5026fe6547c842db65f7196fed3f0b4743ee/compiler/src/Nitpick/PatternMatches.hs#L397-L475
|
||||||
/// only at the top level (without recursing into constructor arguments).
|
/// http://moscova.inria.fr/~maranget/papers/warn/index.html
|
||||||
pub fn check_exhaustiveness(
|
pub fn check_exhaustiveness(
|
||||||
&mut self,
|
&mut self,
|
||||||
unchecked_patterns: &[&TypedPattern],
|
unchecked_patterns: &[&TypedPattern],
|
||||||
|
@ -1451,8 +1451,19 @@ impl<'a> Environment<'a> {
|
||||||
if matrix.is_useful(&pattern_stack) {
|
if matrix.is_useful(&pattern_stack) {
|
||||||
matrix.push(pattern_stack);
|
matrix.push(pattern_stack);
|
||||||
} else {
|
} else {
|
||||||
|
let index = matrix
|
||||||
|
.flatten()
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, p)| p == pattern_stack.head())
|
||||||
|
.map(|(i, _)| i)
|
||||||
|
.expect("should find index");
|
||||||
|
|
||||||
|
let typed_pattern = unchecked_patterns[index];
|
||||||
|
|
||||||
return Err(Error::RedundantMatchClause {
|
return Err(Error::RedundantMatchClause {
|
||||||
location: unchecked_pattern.location(),
|
original: typed_pattern.location(),
|
||||||
|
redundant: unchecked_pattern.location(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,17 +543,19 @@ Maybe you meant to turn it public using the '{keyword_pub}' keyword?"#
|
||||||
#[error(
|
#[error(
|
||||||
"{}\n",
|
"{}\n",
|
||||||
format!(
|
format!(
|
||||||
"I discovered a '{keyword_when}/{keyword_is}' expression with a redundant clause.",
|
"I discovered a '{keyword_when}/{keyword_is}' expression with a redundant pattern.",
|
||||||
keyword_is = "is".if_supports_color(Stdout, |s| s.purple()),
|
keyword_is = "is".if_supports_color(Stdout, |s| s.purple()),
|
||||||
keyword_when = "when".if_supports_color(Stdout, |s| s.purple())
|
keyword_when = "when".if_supports_color(Stdout, |s| s.purple())
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[diagnostic(url("https://aiken-lang.org/language-tour/control-flow#matching"))]
|
#[diagnostic(url("https://aiken-lang.org/language-tour/control-flow#matching"))]
|
||||||
#[diagnostic(code("redundant_pattern_match"))]
|
#[diagnostic(code("redundant_pattern_match"))]
|
||||||
#[diagnostic(help("You can safely remove this clause."))]
|
#[diagnostic(help("Double check these patterns and then remove one of the clauses."))]
|
||||||
RedundantMatchClause {
|
RedundantMatchClause {
|
||||||
#[label]
|
#[label("first found here")]
|
||||||
location: Span,
|
original: Span,
|
||||||
|
#[label("redundant")]
|
||||||
|
redundant: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I couldn't figure out the type of a record you're trying to access.\n")]
|
#[error("I couldn't figure out the type of a record you're trying to access.\n")]
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl PatternStack {
|
||||||
self.0.insert(index, element);
|
self.0.insert(index, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn head(&self) -> &Pattern {
|
pub(super) fn head(&self) -> &Pattern {
|
||||||
&self.0[0]
|
&self.0[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ pub(crate) enum Complete {
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub(crate) enum Pattern {
|
pub(crate) enum Pattern {
|
||||||
Wildcard,
|
Wildcard,
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
|
|
Loading…
Reference in New Issue