Unnamed repository; edit this file 'description' to name the repository.
Fix invalid `pattern_matching_variant` lowering due to recovery
| -rw-r--r-- | crates/hir-ty/src/mir/lower/pattern_matching.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/lower/tests.rs | 16 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/unused_variables.rs | 13 |
3 files changed, 24 insertions, 13 deletions
diff --git a/crates/hir-ty/src/mir/lower/pattern_matching.rs b/crates/hir-ty/src/mir/lower/pattern_matching.rs index 66b51a0e95..bd1ad70fe6 100644 --- a/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -602,6 +602,14 @@ impl<'db> MirLowerCtx<'_, 'db> { shape: AdtPatternShape<'_>, mode: MatchingMode, ) -> Result<'db, (BasicBlockId, Option<BasicBlockId>)> { + let place_ty = cond_place.ty(&self.result, &self.infcx, self.env).ty; + let Some((place_adt, _)) = place_ty.as_adt() else { + return Err(MirLowerError::TypeError("non ADT type matched with ADT pattern")); + }; + if place_adt != variant.adt_id(self.db) { + return Err(MirLowerError::TypeError("ADT pattern does not match place type")); + } + Ok(match variant { VariantId::EnumVariantId(v) => { if mode == MatchingMode::Check { diff --git a/crates/hir-ty/src/mir/lower/tests.rs b/crates/hir-ty/src/mir/lower/tests.rs index d8f7d549d6..cd49549388 100644 --- a/crates/hir-ty/src/mir/lower/tests.rs +++ b/crates/hir-ty/src/mir/lower/tests.rs @@ -134,3 +134,19 @@ fn alias<T: Tr>(x: T::A) { "#, ); } + +#[test] +fn borrowck_opaque_downcast_recovery_does_not_panic() { + check_borrowck( + r#" +//- minicore: option, sized +struct PathBuf; +fn opaque<T>(path: T) -> impl Sized { + Some(path) +} +fn caller(path: &PathBuf) { + let Some(value) = opaque(path) else { return }; +} + "#, + ); +} diff --git a/crates/ide-diagnostics/src/handlers/unused_variables.rs b/crates/ide-diagnostics/src/handlers/unused_variables.rs index afc74445f4..dede3b4aad 100644 --- a/crates/ide-diagnostics/src/handlers/unused_variables.rs +++ b/crates/ide-diagnostics/src/handlers/unused_variables.rs @@ -378,19 +378,6 @@ fn main() { ); } - // regression test as we used to panic in this scenario - #[test] - fn unknown_struct_pattern_param_type() { - check_diagnostics( - r#" -struct S { field : u32 } -fn f(S { field }: error) { - // ^^^^^ 💡 warn: unused variable -} -"#, - ); - } - #[test] fn crate_attrs_lint_smoke_test() { check_diagnostics( |