feat(tipo): add new error for redundant clauses

This commit is contained in:
rvcas 2023-07-28 17:56:56 -04:00 committed by Lucas
parent 0061bcf78d
commit de2791fe82
3 changed files with 29 additions and 14 deletions

View File

@ -540,6 +540,22 @@ Maybe you meant to turn it public using the '{keyword_pub}' keyword?"#
leaked: Type, leaked: Type,
}, },
#[error(
"{}\n",
format!(
"I discovered a '{keyword_when}/{keyword_is}' expression with a redundant clause.",
keyword_is = "is".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(code("redundant_pattern_match"))]
#[diagnostic(help("You can safely remove this clause."))]
RedundantMatchClause {
#[label]
location: 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")]
#[diagnostic(url( #[diagnostic(url(
"https://aiken-lang.org/language-tour/variables-and-constants#type-annotations" "https://aiken-lang.org/language-tour/variables-and-constants#type-annotations"

View File

@ -428,7 +428,15 @@ fn simplify(environment: &mut Environment, value: &ast::TypedPattern) -> Result<
Ok(Pattern::Constructor(name.to_string(), alts, args)) Ok(Pattern::Constructor(name.to_string(), alts, args))
} }
ast::Pattern::Tuple { .. } => todo!(), ast::Pattern::Tuple { elems, .. } => {
let mut p = Pattern::Constructor(NIL_NAME.to_string(), list_constructors(), vec![]);
for hd in elems.iter().rev() {
p = Pattern::Constructor(CONS_NAME.to_string(), list_constructors(), vec![simplify(environment, hd)?, p]);
}
Ok(p)
},
ast::Pattern::Var { .. } | ast::Pattern::Discard { .. } => Ok(Pattern::Wildcard), ast::Pattern::Var { .. } | ast::Pattern::Discard { .. } => Ok(Pattern::Wildcard),
} }
} }
@ -452,8 +460,7 @@ pub(crate) fn compute_match_usefulness(
if matrix.is_useful(&pattern_stack) { if matrix.is_useful(&pattern_stack) {
matrix.push(pattern_stack); matrix.push(pattern_stack);
} else { } else {
dbg!(&pattern_stack); return Err(Error::RedundantMatchClause { location: unchecked_pattern.location() })
todo!("redudant")
} }
} }

View File

@ -48,7 +48,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
subject: &Type, subject: &Type,
typed_clauses: &[TypedClause], typed_clauses: &[TypedClause],
_location: Span, _location: Span,
) -> Result<(), Vec<String>> { ) -> Result<(), Error> {
let _value_typ = collapse_links(Arc::new(subject.clone())); let _value_typ = collapse_links(Arc::new(subject.clone()));
// Currently guards in exhaustiveness checking are assumed that they can fail, // Currently guards in exhaustiveness checking are assumed that they can fail,
@ -66,7 +66,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
} }
} }
let _ = dbg!(compute_match_usefulness(self.environment, &patterns)); compute_match_usefulness(self.environment, &patterns)?;
// self.environment // self.environment
// .check_exhaustiveness(patterns, value_typ, location) // .check_exhaustiveness(patterns, value_typ, location)
@ -1881,15 +1881,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
} }
} }
if let Err(unmatched) = self.check_when_exhaustiveness(&subject_type, &typed_clauses, location)?;
self.check_when_exhaustiveness(&subject_type, &typed_clauses, location)
{
return Err(Error::NotExhaustivePatternMatch {
location,
unmatched,
is_let: false,
});
}
Ok(TypedExpr::When { Ok(TypedExpr::When {
location, location,