Refactor infer_assignment code to be more future-proof

It's generally a bad idea to use equality on enum variants because this won't trigger any compiler errors in the future yet could have hazardous effects if adding new variants. So it's usually preferrable to use exauhstive pattern matching and let the compiler warn missing cases in places where it matters.
This commit is contained in:
KtorZ 2023-03-16 15:25:53 +01:00 committed by Lucas
parent 5bea2d163d
commit 45ea7acc6a
1 changed files with 42 additions and 37 deletions

View File

@ -969,46 +969,51 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
// We currently only do limited exhaustiveness checking of custom types
// at the top level of patterns.
// Do not perform exhaustiveness checking if user explicitly used `assert`.
if kind != AssignmentKind::Expect {
if let Err(unmatched) = self.environment.check_exhaustiveness(
vec![pattern.clone()],
collapse_links(value_typ.clone()),
location,
) {
return Err(Error::NotExhaustivePatternMatch {
location,
unmatched,
is_let: true,
});
}
} else if !value_is_data
&& !value_typ.is_list()
&& self
.environment
.check_exhaustiveness(
match kind {
AssignmentKind::Let => {
if let Err(unmatched) = self.environment.check_exhaustiveness(
vec![pattern.clone()],
collapse_links(value_typ.clone()),
location,
)
.is_ok()
{
self.environment
.warnings
.push(Warning::SingleConstructorExpect {
location: Span {
start: location.start,
end: location.start + kind.location_offset(),
},
pattern_location: untyped_pattern.location(),
value_location: untyped_value.location(),
sample: UntypedExpr::Assignment {
location: Span::empty(),
value: Box::new(untyped_value),
pattern: untyped_pattern,
kind: AssignmentKind::Let,
annotation: None,
},
})
) {
return Err(Error::NotExhaustivePatternMatch {
location,
unmatched,
is_let: true,
});
}
}
AssignmentKind::Expect => {
let is_exaustive_pattern = self
.environment
.check_exhaustiveness(
vec![pattern.clone()],
collapse_links(value_typ.clone()),
location,
)
.is_ok();
if !value_is_data && !value_typ.is_list() && is_exaustive_pattern {
self.environment
.warnings
.push(Warning::SingleConstructorExpect {
location: Span {
start: location.start,
end: location.start + kind.location_offset(),
},
pattern_location: untyped_pattern.location(),
value_location: untyped_value.location(),
sample: UntypedExpr::Assignment {
location: Span::empty(),
value: Box::new(untyped_value),
pattern: untyped_pattern,
kind: AssignmentKind::Let,
annotation: None,
},
});
}
}
}
Ok(TypedExpr::Assignment {