Unnamed repository; edit this file 'description' to name the repository.
fix: Normalize projection types before calculating memory maps
Shoyu Vanilla 9 months ago
parent eaeee0b · commit 4b25930
-rw-r--r--crates/hir-ty/src/mir/eval.rs14
-rw-r--r--crates/ide/src/hover/tests.rs38
2 files changed, 47 insertions, 5 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 1ec55a8209..829771f4c4 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -31,8 +31,8 @@ use syntax::{SyntaxNodePtr, TextRange};
use triomphe::Arc;
use crate::{
- CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId, Interner,
- MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
+ AliasTy, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId,
+ Interner, MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
consteval::{ConstEvalError, intern_const_scalar, try_const_usize},
db::{HirDatabase, InternedClosure},
display::{ClosureStyle, DisplayTarget, HirDisplay},
@@ -2195,7 +2195,7 @@ impl Evaluator<'_> {
}
}
}
- chalk_ir::TyKind::Array(inner, len) => {
+ TyKind::Array(inner, len) => {
let len = match try_const_usize(this.db, len) {
Some(it) => it as usize,
None => not_supported!("non evaluatable array len in patching addresses"),
@@ -2213,7 +2213,7 @@ impl Evaluator<'_> {
)?;
}
}
- chalk_ir::TyKind::Tuple(_, subst) => {
+ TyKind::Tuple(_, subst) => {
let layout = this.layout(ty)?;
for (id, ty) in subst.iter(Interner).enumerate() {
let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
@@ -2229,7 +2229,7 @@ impl Evaluator<'_> {
)?;
}
}
- chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
+ TyKind::Adt(adt, subst) => match adt.0 {
AdtId::StructId(s) => {
let data = s.fields(this.db);
let layout = this.layout(ty)?;
@@ -2280,6 +2280,10 @@ impl Evaluator<'_> {
}
AdtId::UnionId(_) => (),
},
+ TyKind::Alias(AliasTy::Projection(proj)) => {
+ let ty = this.db.normalize_projection(proj.clone(), this.trait_env.clone());
+ rec(this, bytes, &ty, locals, mm, stack_depth_limit - 1)?;
+ }
_ => (),
}
Ok(())
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index c3afd7da2d..c5480217a9 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -10985,3 +10985,41 @@ fn has_docs$0() {}
"#]],
);
}
+
+#[test]
+fn regression_20225() {
+ check(
+ r#"
+//- minicore: coerce_unsized
+trait Trait {
+ type Type<'a, T: ?Sized + 'a>;
+}
+
+enum Borrowed {}
+
+impl Trait for Borrowed {
+ type Type<'a, T: ?Sized + 'a> = &'a T;
+}
+
+enum Enum<'a, T: Trait + 'a> {
+ Variant1(T::Type<'a, [Enum<'a, T>]>),
+ Variant2,
+}
+
+impl Enum<'_, Borrowed> {
+ const CONSTANT$0: Self = Self::Variant1(&[Self::Variant2]);
+}
+ "#,
+ expect![[r#"
+ *CONSTANT*
+
+ ```rust
+ ra_test_fixture::Enum
+ ```
+
+ ```rust
+ const CONSTANT: Self = Variant1(&[Variant2])
+ ```
+ "#]],
+ );
+}