Skip to content

Commit 6b03a46

Browse files
authored
Rollup merge of #94242 - compiler-errors:fat-uninhabitable-pointer, r=michaelwoerister
properly handle fat pointers to uninhabitable types Calculate the pointee metadata size by using `tcx.struct_tail_erasing_lifetimes` instead of duplicating the logic in `fat_pointer_kind`. Open to alternatively suggestions on how to fix this. Fixes #94149 r? ````@michaelwoerister```` since you touched this code last, I think!
2 parents 7fb55b4 + c73a2f8 commit 6b03a46

File tree

4 files changed

+49
-18
lines changed

4 files changed

+49
-18
lines changed

Diff for: compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,10 @@ fn pointer_or_reference_metadata<'ll, 'tcx>(
449449
// This is a thin pointer. Create a regular pointer type and give it the correct name.
450450
debug_assert_eq!(
451451
(thin_pointer_size, thin_pointer_align),
452-
cx.size_and_align_of(ptr_type)
452+
cx.size_and_align_of(ptr_type),
453+
"ptr_type={}, pointee_type={}",
454+
ptr_type,
455+
pointee_type,
453456
);
454457

455458
unsafe {

Diff for: compiler/rustc_codegen_llvm/src/debuginfo/utils.rs

+16-17
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use super::namespace::item_namespace;
44
use super::CrateDebugContext;
55

66
use rustc_hir::def_id::DefId;
7-
use rustc_middle::ty::layout::LayoutOf;
7+
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
88
use rustc_middle::ty::{self, DefIdTree, Ty};
9-
use rustc_target::abi::Variants;
9+
use tracing::trace;
1010

1111
use crate::common::CodegenCx;
1212
use crate::llvm;
@@ -63,38 +63,37 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
6363
cx: &CodegenCx<'ll, 'tcx>,
6464
pointee_ty: Ty<'tcx>,
6565
) -> Option<FatPtrKind> {
66-
let layout = cx.layout_of(pointee_ty);
66+
let pointee_tail_ty = cx.tcx.struct_tail_erasing_lifetimes(pointee_ty, cx.param_env());
67+
let layout = cx.layout_of(pointee_tail_ty);
68+
trace!(
69+
"fat_pointer_kind: {:?} has layout {:?} (is_unsized? {})",
70+
pointee_tail_ty,
71+
layout,
72+
layout.is_unsized()
73+
);
6774

6875
if !layout.is_unsized() {
6976
return None;
7077
}
7178

72-
match *pointee_ty.kind() {
79+
match *pointee_tail_ty.kind() {
7380
ty::Str | ty::Slice(_) => Some(FatPtrKind::Slice),
7481
ty::Dynamic(..) => Some(FatPtrKind::Dyn),
75-
ty::Adt(..) | ty::Tuple(..) if matches!(layout.variants, Variants::Single { .. }) => {
76-
let last_field_index = layout.fields.count() - 1;
77-
debug_assert!(
78-
(0..last_field_index)
79-
.all(|field_index| { !layout.field(cx, field_index).is_unsized() })
80-
);
81-
82-
let unsized_field = layout.field(cx, last_field_index);
83-
debug_assert!(unsized_field.is_unsized());
84-
fat_pointer_kind(cx, unsized_field.ty)
85-
}
8682
ty::Foreign(_) => {
8783
// Assert that pointers to foreign types really are thin:
8884
debug_assert_eq!(
89-
cx.size_of(cx.tcx.mk_imm_ptr(pointee_ty)),
85+
cx.size_of(cx.tcx.mk_imm_ptr(pointee_tail_ty)),
9086
cx.size_of(cx.tcx.mk_imm_ptr(cx.tcx.types.u8))
9187
);
9288
None
9389
}
9490
_ => {
9591
// For all other pointee types we should already have returned None
9692
// at the beginning of the function.
97-
panic!("fat_pointer_kind() - Encountered unexpected `pointee_ty`: {:?}", pointee_ty)
93+
panic!(
94+
"fat_pointer_kind() - Encountered unexpected `pointee_tail_ty`: {:?}",
95+
pointee_tail_ty
96+
)
9897
}
9998
}
10099
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// check-pass
2+
// compile-flags: -Cdebuginfo=2
3+
// fixes issue #94149
4+
5+
#![allow(dead_code)]
6+
7+
pub fn main() {
8+
let _ = Foo::<dyn FooTrait>::new();
9+
}
10+
11+
pub struct Foo<T: FooTrait + ?Sized> {
12+
base: FooBase,
13+
value: T,
14+
}
15+
16+
impl<T: FooTrait + ?Sized> Foo<T> {
17+
pub fn new() -> Box<Foo<T>> {
18+
todo!()
19+
}
20+
}
21+
22+
pub trait FooTrait {}
23+
24+
pub struct FooBase {
25+
cls: Bar,
26+
}
27+
28+
// Bar *must* be a fieldless enum
29+
pub enum Bar {}

0 commit comments

Comments
 (0)