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