diff options
Diffstat (limited to 'crates/hir_ty/src/diagnostics/match_check.rs')
-rw-r--r-- | crates/hir_ty/src/diagnostics/match_check.rs | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs index 5a5cdcbf3..34291578a 100644 --- a/crates/hir_ty/src/diagnostics/match_check.rs +++ b/crates/hir_ty/src/diagnostics/match_check.rs | |||
@@ -539,7 +539,7 @@ impl Matrix { | |||
539 | if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) { | 539 | if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) { |
540 | // Or patterns are expanded here | 540 | // Or patterns are expanded here |
541 | for pat_id in pat_ids { | 541 | for pat_id in pat_ids { |
542 | self.0.push(PatStack::from_pattern(pat_id)); | 542 | self.0.push(row.replace_head_with([pat_id].iter())); |
543 | } | 543 | } |
544 | } else { | 544 | } else { |
545 | self.0.push(row); | 545 | self.0.push(row); |
@@ -626,7 +626,7 @@ pub(super) fn is_useful( | |||
626 | // - enum with no variants | 626 | // - enum with no variants |
627 | // - `!` type | 627 | // - `!` type |
628 | // In those cases, no match arm is useful. | 628 | // In those cases, no match arm is useful. |
629 | match cx.infer[cx.match_expr].strip_references().interned(&Interner) { | 629 | match cx.infer[cx.match_expr].strip_references().kind(&Interner) { |
630 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { | 630 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { |
631 | if cx.db.enum_data(*enum_id).variants.is_empty() { | 631 | if cx.db.enum_data(*enum_id).variants.is_empty() { |
632 | return Ok(Usefulness::NotUseful); | 632 | return Ok(Usefulness::NotUseful); |
@@ -792,7 +792,10 @@ fn pat_constructor(cx: &MatchCheckCtx, pat: PatIdOrWild) -> MatchCheckResult<Opt | |||
792 | Pat::Tuple { .. } => { | 792 | Pat::Tuple { .. } => { |
793 | let pat_id = pat.as_id().expect("we already know this pattern is not a wild"); | 793 | let pat_id = pat.as_id().expect("we already know this pattern is not a wild"); |
794 | Some(Constructor::Tuple { | 794 | Some(Constructor::Tuple { |
795 | arity: cx.infer.type_of_pat[pat_id].as_tuple().ok_or(MatchCheckErr::Unknown)?.len(), | 795 | arity: cx.infer.type_of_pat[pat_id] |
796 | .as_tuple() | ||
797 | .ok_or(MatchCheckErr::Unknown)? | ||
798 | .len(&Interner), | ||
796 | }) | 799 | }) |
797 | } | 800 | } |
798 | Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] { | 801 | Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] { |
@@ -1085,6 +1088,20 @@ fn main() { | |||
1085 | } | 1088 | } |
1086 | 1089 | ||
1087 | #[test] | 1090 | #[test] |
1091 | fn or_pattern_no_diagnostic() { | ||
1092 | check_diagnostics( | ||
1093 | r#" | ||
1094 | enum Either {A, B} | ||
1095 | |||
1096 | fn main() { | ||
1097 | match (Either::A, Either::B) { | ||
1098 | (Either::A | Either::B, _) => (), | ||
1099 | } | ||
1100 | }"#, | ||
1101 | ) | ||
1102 | } | ||
1103 | |||
1104 | #[test] | ||
1088 | fn mismatched_types() { | 1105 | fn mismatched_types() { |
1089 | // Match statements with arms that don't match the | 1106 | // Match statements with arms that don't match the |
1090 | // expression pattern do not fire this diagnostic. | 1107 | // expression pattern do not fire this diagnostic. |
@@ -1336,30 +1353,6 @@ fn bang(never: !) { | |||
1336 | } | 1353 | } |
1337 | 1354 | ||
1338 | #[test] | 1355 | #[test] |
1339 | fn or_pattern_panic() { | ||
1340 | check_diagnostics( | ||
1341 | r#" | ||
1342 | pub enum Category { Infinity, Zero } | ||
1343 | |||
1344 | fn panic(a: Category, b: Category) { | ||
1345 | match (a, b) { | ||
1346 | (Category::Zero | Category::Infinity, _) => (), | ||
1347 | (_, Category::Zero | Category::Infinity) => (), | ||
1348 | } | ||
1349 | |||
1350 | // FIXME: This is a false positive, but the code used to cause a panic in the match checker, | ||
1351 | // so this acts as a regression test for that. | ||
1352 | match (a, b) { | ||
1353 | //^^^^^^ Missing match arm | ||
1354 | (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => (), | ||
1355 | (Category::Infinity | Category::Zero, _) => (), | ||
1356 | } | ||
1357 | } | ||
1358 | "#, | ||
1359 | ); | ||
1360 | } | ||
1361 | |||
1362 | #[test] | ||
1363 | fn unknown_type() { | 1356 | fn unknown_type() { |
1364 | check_diagnostics( | 1357 | check_diagnostics( |
1365 | r#" | 1358 | r#" |