debuginfo: Fix debuginfo for Box<T> where T is unsized.

Before this fix, the debuginfo for the fields was generated from the
struct defintion of Box<T>, but (at least at the moment) the compiler
pretends that Box<T> is just a (fat) pointer, so the fields need to be
`pointer` and `vtable` instead of `__0: Unique<T>` and `__1: Allocator`.

This is meant as a temporary mitigation until we can make sure that
simply treating Box as a regular struct in debuginfo does not cause too
much breakage in the ecosystem.
This commit is contained in:
Michael Woerister 2022-03-24 10:59:28 +01:00
parent 600a80dedf
commit e169261a6f
2 changed files with 33 additions and 5 deletions

View file

@ -166,6 +166,13 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
pointee_type: Ty<'tcx>,
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
// The debuginfo generated by this function is only valid if `ptr_type` is really just
// a (fat) pointer. Make sure it is not called for e.g. `Box<T, NonZSTAllocator>`.
debug_assert_eq!(
cx.size_and_align_of(ptr_type),
cx.size_and_align_of(cx.tcx.mk_mut_ptr(pointee_type))
);
let pointee_type_di_node = type_di_node(cx, pointee_type);
return_if_di_node_created_in_meantime!(cx, unique_type_id);
@ -212,7 +219,17 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
DIFlags::FlagZero,
),
|cx, owner| {
let layout = cx.layout_of(ptr_type);
// FIXME: If this fat pointer is a `Box` then we don't want to use its
// type layout and instead use the layout of the raw pointer inside
// of it.
// The proper way to handle this is to not treat Box as a pointer
// at all and instead emit regular struct debuginfo for it. We just
// need to make sure that we don't break existing debuginfo consumers
// by doing that (at least not without a warning period).
let layout_type =
if ptr_type.is_box() { cx.tcx.mk_mut_ptr(pointee_type) } else { ptr_type };
let layout = cx.layout_of(layout_type);
let addr_field = layout.field(cx, abi::FAT_PTR_ADDR);
let extra_field = layout.field(cx, abi::FAT_PTR_EXTRA);