about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-04-04 20:08:37 +0000
committerGitHub <noreply@github.com>2022-04-04 20:08:37 +0000
commit5a6918f1c4e9d4f0c6a655e6283470f64edd64cf (patch)
treee9422571206c51fe83d65d3a0b891a5676607028
parentbf6303df3721119090dfb50340f6cccc71d5ccc8 (diff)
parent86665e50c2072725802f58e9dd1cd28d4644eb9f (diff)
downloadrust-5a6918f1c4e9d4f0c6a655e6283470f64edd64cf.tar.gz
rust-5a6918f1c4e9d4f0c6a655e6283470f64edd64cf.zip
Merge #11899
11899: fix: Skip match check on patterns of unexpected TyKind::FnDef r=Veykril a=iDawer

Match checking does not expect patterns of `TyKind::FnDef` type.
It seems that in _rustc_ match checking is ruled out due to such type errors at the typecheck stage.

Spotted in #11319

Co-authored-by: iDawer <ilnur.iskhakov.oss@outlook.com>
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs19
-rw-r--r--crates/ide_diagnostics/src/handlers/missing_match_arms.rs16
2 files changed, 30 insertions, 5 deletions
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 87a85797613..d21ea32d9e4 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -11,7 +11,7 @@ pub(crate) mod deconstruct_pat;
 pub(crate) mod usefulness;
 
 use hir_def::{body::Body, expr::PatId, EnumVariantId, LocalFieldId, VariantId};
-use stdx::never;
+use stdx::{always, never};
 
 use crate::{
     db::HirDatabase, infer::BindingMode, InferenceResult, Interner, Substitution, Ty, TyKind,
@@ -127,7 +127,11 @@ impl<'a> PatCtxt<'a> {
             hir_def::expr::Pat::Tuple { ref args, ellipsis } => {
                 let arity = match *ty.kind(Interner) {
                     TyKind::Tuple(arity, _) => arity,
-                    _ => panic!("unexpected type for tuple pattern: {:?}", ty),
+                    _ => {
+                        never!("unexpected type for tuple pattern: {:?}", ty);
+                        self.errors.push(PatternError::UnexpectedType);
+                        return Pat { ty: ty.clone(), kind: PatKind::Wild.into() };
+                    }
                 };
                 let subpatterns = self.lower_tuple_subpats(args, arity, ellipsis);
                 PatKind::Leaf { subpatterns }
@@ -227,11 +231,16 @@ impl<'a> PatCtxt<'a> {
             Some(variant_id) => {
                 if let VariantId::EnumVariantId(enum_variant) = variant_id {
                     let substs = match ty.kind(Interner) {
-                        TyKind::Adt(_, substs) | TyKind::FnDef(_, substs) => substs.clone(),
-                        TyKind::Error => {
+                        TyKind::Adt(_, substs) => substs.clone(),
+                        kind => {
+                            always!(
+                                matches!(kind, TyKind::FnDef(..) | TyKind::Error),
+                                "inappropriate type for def: {:?}",
+                                ty
+                            );
+                            self.errors.push(PatternError::UnexpectedType);
                             return PatKind::Wild;
                         }
-                        _ => panic!("inappropriate type for def: {:?}", ty),
                     };
                     PatKind::Variant { substs, enum_variant, subpatterns }
                 } else {
diff --git a/crates/ide_diagnostics/src/handlers/missing_match_arms.rs b/crates/ide_diagnostics/src/handlers/missing_match_arms.rs
index 3fb84c9f3c2..3eb4cf60a96 100644
--- a/crates/ide_diagnostics/src/handlers/missing_match_arms.rs
+++ b/crates/ide_diagnostics/src/handlers/missing_match_arms.rs
@@ -931,6 +931,22 @@ fn f(ty: Enum) {
         );
     }
 
+    #[test]
+    fn unexpected_ty_fndef() {
+        cov_mark::check!(validate_match_bailed_out);
+        check_diagnostics(
+            r"
+enum Exp {
+    Tuple(()),
+}
+fn f() {
+    match __unknown {
+        Exp::Tuple => {}
+    }
+}",
+        );
+    }
+
     mod false_negatives {
         //! The implementation of match checking here is a work in progress. As we roll this out, we
         //! prefer false negatives to false positives (ideally there would be no false positives). This