diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-19 18:46:38 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-19 18:46:38 +0100 |
commit | c7196620abd5e9bab4fbd53388da361f0f6987a1 (patch) | |
tree | 3511921f52d08ea88da3d650cfb835dffef2c8de /crates/hir_ty/src/diagnostics/expr.rs | |
parent | 1cf0794f5eac5de7a3829fe93a1b99f4d22fd2f0 (diff) | |
parent | e2b1c69f7488b942360bb3c398a1c831510d1afc (diff) |
Merge #8875
8875: fix: false positive "Missing match arm" when an or-pattern has mismatched types r=flodiebold a=iDawer
![Screenshot_20210519_114510](https://user-images.githubusercontent.com/7803845/118768935-19e12c00-b86f-11eb-90c4-1eed3f2bf57f.jpg)
`InferenceResult` now records pattern type mismatches.
Co-authored-by: Dawer <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/diagnostics/expr.rs')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 47709c1e8..b9a69b79c 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -211,7 +211,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
211 | 211 | ||
212 | // FIXME: Due to shortcomings in the current type system implementation, only emit this | 212 | // FIXME: Due to shortcomings in the current type system implementation, only emit this |
213 | // diagnostic if there are no type mismatches in the containing function. | 213 | // diagnostic if there are no type mismatches in the containing function. |
214 | if self.infer.type_mismatches.iter().next().is_some() { | 214 | if self.infer.expr_type_mismatches().next().is_some() { |
215 | return; | 215 | return; |
216 | } | 216 | } |
217 | 217 | ||
@@ -311,11 +311,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
311 | // necessary. | 311 | // necessary. |
312 | // | 312 | // |
313 | // FIXME we should use the type checker for this. | 313 | // FIXME we should use the type checker for this. |
314 | if pat_ty == match_expr_ty | 314 | if (pat_ty == match_expr_ty |
315 | || match_expr_ty | 315 | || match_expr_ty |
316 | .as_reference() | 316 | .as_reference() |
317 | .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty) | 317 | .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty) |
318 | .unwrap_or(false) | 318 | .unwrap_or(false)) |
319 | && types_of_subpatterns_do_match(pat, &cx.body, &infer) | ||
319 | { | 320 | { |
320 | // If we had a NotUsefulMatchArm diagnostic, we could | 321 | // If we had a NotUsefulMatchArm diagnostic, we could |
321 | // check the usefulness of each pattern as we added it | 322 | // check the usefulness of each pattern as we added it |
@@ -496,6 +497,21 @@ pub fn record_pattern_missing_fields( | |||
496 | Some((variant_def, missed_fields, exhaustive)) | 497 | Some((variant_def, missed_fields, exhaustive)) |
497 | } | 498 | } |
498 | 499 | ||
500 | fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult) -> bool { | ||
501 | fn walk(pat: PatId, body: &Body, infer: &InferenceResult, has_type_mismatches: &mut bool) { | ||
502 | match infer.type_mismatch_for_pat(pat) { | ||
503 | Some(_) => *has_type_mismatches = true, | ||
504 | None => { | ||
505 | body[pat].walk_child_pats(|subpat| walk(subpat, body, infer, has_type_mismatches)) | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | |||
510 | let mut has_type_mismatches = false; | ||
511 | walk(pat, body, infer, &mut has_type_mismatches); | ||
512 | !has_type_mismatches | ||
513 | } | ||
514 | |||
499 | #[cfg(test)] | 515 | #[cfg(test)] |
500 | mod tests { | 516 | mod tests { |
501 | use crate::diagnostics::tests::check_diagnostics; | 517 | use crate::diagnostics::tests::check_diagnostics; |