From 6fbf6ef514876e68d98211051ef54d0dcd2b8550 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Sat, 10 Jun 2023 02:10:52 +0330 Subject: [PATCH] Fix panic in displaying const trait objects --- crates/hir-ty/src/display.rs | 16 ++++++++++++++++ crates/hir-ty/src/mir/eval.rs | 18 +++++++++++++----- crates/ide/src/hover/tests.rs | 23 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index f90e025c7cc..9d5cf47da8d 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -536,6 +536,22 @@ fn render_const_scalar( } 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(""); + }; + let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else { + return f.write_str(""); + }; + let size = layout.size.bytes_usize(); + let Some(bytes) = memory_map.get(addr, size) else { + return f.write_str(""); + }; + f.write_str("&")?; + render_const_scalar(f, bytes, memory_map, t) + } _ => { let addr = usize::from_le_bytes(b.try_into().unwrap()); let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else { diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index ce14f6dbad5..9acf9d39e56 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -77,7 +77,7 @@ fn id(&mut self, ty: Ty) -> usize { 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)) } @@ -1571,16 +1571,24 @@ fn rec( } None => { let mut check_inner = None; + let (addr, meta) = bytes.split_at(bytes.len() / 2); let element_size = match t.kind(Interner) { TyKind::Str => 1, TyKind::Slice(t) => { check_inner = Some(t); 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 addr = Address::from_bytes(addr)?; let b = this.read_memory(addr, size)?; @@ -1588,7 +1596,7 @@ fn rec( if let Some(ty) = check_inner { for i in 0..count { 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)?; } } } diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index a2f96977581..22bbdf37a8e 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -4422,6 +4422,29 @@ enum Enum { ); } +#[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] fn hover_const_eval_slice() { check(