Unnamed repository; edit this file 'description' to name the repository.
Propogate error types in mir type projections
Lukas Wirth 2025-02-12
parent 8aa4ae5 · commit 5af2d6a
-rw-r--r--crates/hir-ty/src/mir.rs11
-rw-r--r--crates/ide-diagnostics/src/handlers/unused_variables.rs13
2 files changed, 22 insertions, 2 deletions
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index 84d8950b1a..41304bbd8a 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -10,7 +10,7 @@ use crate::{
lang_items::is_box,
mapping::ToChalk,
CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap,
- Substitution, TraitEnvironment, Ty, TyKind,
+ Substitution, TraitEnvironment, Ty, TyExt, TyKind,
};
use base_db::CrateId;
use chalk_ir::Mutability;
@@ -144,6 +144,13 @@ impl<V, T> ProjectionElem<V, T> {
closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
krate: CrateId,
) -> Ty {
+ // we only bail on mir building when there are type mismatches
+ // but error types may pop up resulting in us still attempting to build the mir
+ // so just propagate the error type
+ if base.is_unknown() {
+ return TyKind::Error.intern(Interner);
+ }
+
if matches!(base.kind(Interner), TyKind::Alias(_) | TyKind::AssociatedType(..)) {
base = normalize(
db,
@@ -166,7 +173,7 @@ impl<V, T> ProjectionElem<V, T> {
TyKind::Error.intern(Interner)
}
},
- ProjectionElem::Field(Either::Left(f)) => match &base.kind(Interner) {
+ ProjectionElem::Field(Either::Left(f)) => match base.kind(Interner) {
TyKind::Adt(_, subst) => {
db.field_types(f.parent)[f.local_id].clone().substitute(Interner, subst)
}
diff --git a/crates/ide-diagnostics/src/handlers/unused_variables.rs b/crates/ide-diagnostics/src/handlers/unused_variables.rs
index 67ece56694..d5caf4de33 100644
--- a/crates/ide-diagnostics/src/handlers/unused_variables.rs
+++ b/crates/ide-diagnostics/src/handlers/unused_variables.rs
@@ -263,4 +263,17 @@ 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
+}
+"#,
+ );
+ }
}