mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge pull request #20232 from ShoyuVanilla/issue-20225
fix: Normalize projection types before calculating memory maps
This commit is contained in:
commit
a489123e80
@ -795,6 +795,14 @@ fn render_const_scalar(
|
|||||||
let Some(bytes) = memory_map.get(addr, size_one * count) else {
|
let Some(bytes) = memory_map.get(addr, size_one * count) else {
|
||||||
return f.write_str("<ref-data-not-available>");
|
return f.write_str("<ref-data-not-available>");
|
||||||
};
|
};
|
||||||
|
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("<layout-error>");
|
||||||
|
}
|
||||||
f.write_str("&[")?;
|
f.write_str("&[")?;
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
|
@ -31,8 +31,8 @@ use syntax::{SyntaxNodePtr, TextRange};
|
|||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId, Interner,
|
AliasTy, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, FnDefId,
|
||||||
MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
|
Interner, MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
|
||||||
consteval::{ConstEvalError, intern_const_scalar, try_const_usize},
|
consteval::{ConstEvalError, intern_const_scalar, try_const_usize},
|
||||||
db::{HirDatabase, InternedClosure},
|
db::{HirDatabase, InternedClosure},
|
||||||
display::{ClosureStyle, DisplayTarget, HirDisplay},
|
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) {
|
let len = match try_const_usize(this.db, len) {
|
||||||
Some(it) => it as usize,
|
Some(it) => it as usize,
|
||||||
None => not_supported!("non evaluatable array len in patching addresses"),
|
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)?;
|
let layout = this.layout(ty)?;
|
||||||
for (id, ty) in subst.iter(Interner).enumerate() {
|
for (id, ty) in subst.iter(Interner).enumerate() {
|
||||||
let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
|
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) => {
|
AdtId::StructId(s) => {
|
||||||
let data = s.fields(this.db);
|
let data = s.fields(this.db);
|
||||||
let layout = this.layout(ty)?;
|
let layout = this.layout(ty)?;
|
||||||
@ -2280,6 +2280,10 @@ impl Evaluator<'_> {
|
|||||||
}
|
}
|
||||||
AdtId::UnionId(_) => (),
|
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(())
|
Ok(())
|
||||||
|
@ -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])
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user