Check patterns for type match recursively.

This commit is contained in:
Dawer 2021-05-19 10:57:10 +05:00
parent 472317c008
commit e2b1c69f74
2 changed files with 30 additions and 2 deletions

View file

@ -311,11 +311,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
// necessary. // necessary.
// //
// FIXME we should use the type checker for this. // FIXME we should use the type checker for this.
if pat_ty == match_expr_ty if (pat_ty == match_expr_ty
|| match_expr_ty || match_expr_ty
.as_reference() .as_reference()
.map(|(match_expr_ty, ..)| match_expr_ty == pat_ty) .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
.unwrap_or(false) .unwrap_or(false))
&& types_of_subpatterns_do_match(pat, &cx.body, &infer)
{ {
// If we had a NotUsefulMatchArm diagnostic, we could // If we had a NotUsefulMatchArm diagnostic, we could
// check the usefulness of each pattern as we added it // check the usefulness of each pattern as we added it
@ -496,6 +497,21 @@ pub fn record_pattern_missing_fields(
Some((variant_def, missed_fields, exhaustive)) Some((variant_def, missed_fields, exhaustive))
} }
fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult) -> bool {
fn walk(pat: PatId, body: &Body, infer: &InferenceResult, has_type_mismatches: &mut bool) {
match infer.type_mismatch_for_pat(pat) {
Some(_) => *has_type_mismatches = true,
None => {
body[pat].walk_child_pats(|subpat| walk(subpat, body, infer, has_type_mismatches))
}
}
}
let mut has_type_mismatches = false;
walk(pat, body, infer, &mut has_type_mismatches);
!has_type_mismatches
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::diagnostics::tests::check_diagnostics; use crate::diagnostics::tests::check_diagnostics;

View file

@ -1127,6 +1127,18 @@ fn main() {
); );
} }
#[test]
fn mismatched_types_in_or_patterns() {
check_diagnostics(
r#"
fn main() {
match false { true | () => {} }
match (false,) { (true | (),) => {} }
}
"#,
);
}
#[test] #[test]
fn malformed_match_arm_tuple_enum_missing_pattern() { fn malformed_match_arm_tuple_enum_missing_pattern() {
// We are testing to be sure we don't panic here when the match // We are testing to be sure we don't panic here when the match