mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-16 15:14:02 +00:00
Fix panic in displaying const trait objects
This commit is contained in:
parent
2796851961
commit
6fbf6ef514
3 changed files with 52 additions and 5 deletions
|
@ -536,6 +536,22 @@ fn render_const_scalar(
|
||||||
}
|
}
|
||||||
f.write_str("]")
|
f.write_str("]")
|
||||||
}
|
}
|
||||||
|
TyKind::Dyn(_) => {
|
||||||
|
let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
|
||||||
|
let ty_id = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
|
||||||
|
let Ok(t) = memory_map.vtable.ty(ty_id) else {
|
||||||
|
return f.write_str("<ty-missing-in-vtable-map>");
|
||||||
|
};
|
||||||
|
let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
|
||||||
|
return f.write_str("<layout-error>");
|
||||||
|
};
|
||||||
|
let size = layout.size.bytes_usize();
|
||||||
|
let Some(bytes) = memory_map.get(addr, size) else {
|
||||||
|
return f.write_str("<ref-data-not-available>");
|
||||||
|
};
|
||||||
|
f.write_str("&")?;
|
||||||
|
render_const_scalar(f, bytes, memory_map, t)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let addr = usize::from_le_bytes(b.try_into().unwrap());
|
let addr = usize::from_le_bytes(b.try_into().unwrap());
|
||||||
let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
|
let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl VTableMap {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty(&self, id: usize) -> Result<&Ty> {
|
pub(crate) fn ty(&self, id: usize) -> Result<&Ty> {
|
||||||
self.id_to_ty.get(id).ok_or(MirEvalError::InvalidVTableId(id))
|
self.id_to_ty.get(id).ok_or(MirEvalError::InvalidVTableId(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1571,16 +1571,24 @@ impl Evaluator<'_> {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut check_inner = None;
|
let mut check_inner = None;
|
||||||
|
let (addr, meta) = bytes.split_at(bytes.len() / 2);
|
||||||
let element_size = match t.kind(Interner) {
|
let element_size = match t.kind(Interner) {
|
||||||
TyKind::Str => 1,
|
TyKind::Str => 1,
|
||||||
TyKind::Slice(t) => {
|
TyKind::Slice(t) => {
|
||||||
check_inner = Some(t);
|
check_inner = Some(t);
|
||||||
this.size_of_sized(t, locals, "slice inner type")?
|
this.size_of_sized(t, locals, "slice inner type")?
|
||||||
}
|
}
|
||||||
_ => return Ok(()), // FIXME: support other kind of unsized types
|
TyKind::Dyn(_) => {
|
||||||
|
let t = this.vtable_map.ty_of_bytes(meta)?;
|
||||||
|
check_inner = Some(t);
|
||||||
|
this.size_of_sized(t, locals, "dyn concrete type")?
|
||||||
|
}
|
||||||
|
_ => return Ok(()),
|
||||||
|
};
|
||||||
|
let count = match t.kind(Interner) {
|
||||||
|
TyKind::Dyn(_) => 1,
|
||||||
|
_ => from_bytes!(usize, meta),
|
||||||
};
|
};
|
||||||
let (addr, meta) = bytes.split_at(bytes.len() / 2);
|
|
||||||
let count = from_bytes!(usize, meta);
|
|
||||||
let size = element_size * count;
|
let size = element_size * count;
|
||||||
let addr = Address::from_bytes(addr)?;
|
let addr = Address::from_bytes(addr)?;
|
||||||
let b = this.read_memory(addr, size)?;
|
let b = this.read_memory(addr, size)?;
|
||||||
|
@ -1588,7 +1596,7 @@ impl Evaluator<'_> {
|
||||||
if let Some(ty) = check_inner {
|
if let Some(ty) = check_inner {
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
let offset = element_size * i;
|
let offset = element_size * i;
|
||||||
rec(this, &b[offset..offset + element_size], ty, locals, mm)?;
|
rec(this, &b[offset..offset + element_size], &ty, locals, mm)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4422,6 +4422,29 @@ const FOO$0: Option<&i32> = Some(2).as_ref();
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hover_const_eval_dyn_trait() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- minicore: fmt, coerce_unsized, builtin_impls
|
||||||
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
const FOO$0: &dyn Debug = &2i32;
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*FOO*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const FOO: &dyn Debug = &2
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hover_const_eval_slice() {
|
fn hover_const_eval_slice() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Reference in a new issue