Skip to content

Commit 5a6918f

Browse files
bors[bot]iDawer
andauthored
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 <[email protected]>
2 parents bf6303d + 86665e5 commit 5a6918f

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

crates/hir_ty/src/diagnostics/match_check.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub(crate) mod deconstruct_pat;
1111
pub(crate) mod usefulness;
1212

1313
use hir_def::{body::Body, expr::PatId, EnumVariantId, LocalFieldId, VariantId};
14-
use stdx::never;
14+
use stdx::{always, never};
1515

1616
use crate::{
1717
db::HirDatabase, infer::BindingMode, InferenceResult, Interner, Substitution, Ty, TyKind,
@@ -127,7 +127,11 @@ impl<'a> PatCtxt<'a> {
127127
hir_def::expr::Pat::Tuple { ref args, ellipsis } => {
128128
let arity = match *ty.kind(Interner) {
129129
TyKind::Tuple(arity, _) => arity,
130-
_ => panic!("unexpected type for tuple pattern: {:?}", ty),
130+
_ => {
131+
never!("unexpected type for tuple pattern: {:?}", ty);
132+
self.errors.push(PatternError::UnexpectedType);
133+
return Pat { ty: ty.clone(), kind: PatKind::Wild.into() };
134+
}
131135
};
132136
let subpatterns = self.lower_tuple_subpats(args, arity, ellipsis);
133137
PatKind::Leaf { subpatterns }
@@ -227,11 +231,16 @@ impl<'a> PatCtxt<'a> {
227231
Some(variant_id) => {
228232
if let VariantId::EnumVariantId(enum_variant) = variant_id {
229233
let substs = match ty.kind(Interner) {
230-
TyKind::Adt(_, substs) | TyKind::FnDef(_, substs) => substs.clone(),
231-
TyKind::Error => {
234+
TyKind::Adt(_, substs) => substs.clone(),
235+
kind => {
236+
always!(
237+
matches!(kind, TyKind::FnDef(..) | TyKind::Error),
238+
"inappropriate type for def: {:?}",
239+
ty
240+
);
241+
self.errors.push(PatternError::UnexpectedType);
232242
return PatKind::Wild;
233243
}
234-
_ => panic!("inappropriate type for def: {:?}", ty),
235244
};
236245
PatKind::Variant { substs, enum_variant, subpatterns }
237246
} else {

crates/ide_diagnostics/src/handlers/missing_match_arms.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,22 @@ fn f(ty: Enum) {
931931
);
932932
}
933933

934+
#[test]
935+
fn unexpected_ty_fndef() {
936+
cov_mark::check!(validate_match_bailed_out);
937+
check_diagnostics(
938+
r"
939+
enum Exp {
940+
Tuple(()),
941+
}
942+
fn f() {
943+
match __unknown {
944+
Exp::Tuple => {}
945+
}
946+
}",
947+
);
948+
}
949+
934950
mod false_negatives {
935951
//! The implementation of match checking here is a work in progress. As we roll this out, we
936952
//! prefer false negatives to false positives (ideally there would be no false positives). This

0 commit comments

Comments
 (0)