diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 61d626504537..b3760e3a3822 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -795,6 +795,14 @@ fn render_const_scalar( let Some(bytes) = memory_map.get(addr, size_one * count) else { return f.write_str(""); }; + let expected_len = count * size_one; + if bytes.len() < expected_len { + never!( + "Memory map size is too small. Expected {expected_len}, got {}", + bytes.len(), + ); + return f.write_str(""); + } f.write_str("&[")?; let mut first = true; for i in 0..count { diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 1ec55a820928..829771f4c4f0 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 c3afd7da2df4..c5480217a91e 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]) + ``` + "#]], + ); +}