Skip to content

Commit 7ef2ba8

Browse files
committed
Fix size_of_val and min_align_of_val for truly unsized types
1 parent 39ee14d commit 7ef2ba8

File tree

4 files changed

+37
-7
lines changed

4 files changed

+37
-7
lines changed

example/mini_core_hello_world.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,17 @@ fn main() {
330330
static REF1: &u8 = &42;
331331
static REF2: &u8 = REF1;
332332
assert_eq!(*REF1, *REF2);
333+
334+
extern "C" {
335+
type A;
336+
}
337+
338+
fn main() {
339+
let x: &A = unsafe { &*(1usize as *const A) };
340+
341+
assert_eq!(unsafe { intrinsics::size_of_val(x) }, 0);
342+
assert_eq!(unsafe { intrinsics::min_align_of_val(x) }, 1);
343+
}
333344
}
334345

335346
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]

example/std_example.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,25 @@ fn main() {
128128
0 => loop {},
129129
v => panic(v),
130130
};
131+
132+
if black_box(false) {
133+
// Based on https://github.com/rust-lang/rust/blob/2f320a224e827b400be25966755a621779f797cc/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
134+
let _ = Foo::<dyn Send>::new();
135+
136+
#[allow(dead_code)]
137+
struct Foo<T: ?Sized> {
138+
base: Never,
139+
value: T,
140+
}
141+
142+
impl<T: ?Sized> Foo<T> {
143+
pub fn new() -> Box<Foo<T>> {
144+
todo!()
145+
}
146+
}
147+
148+
enum Never {}
149+
}
131150
}
132151

133152
fn panic(_: u128) {

src/intrinsics/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
404404
};
405405
size_of_val, (c ptr) {
406406
let layout = fx.layout_of(substs.type_at(0));
407-
let size = if layout.is_unsized() {
407+
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
408+
// branch
409+
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
408410
let (_ptr, info) = ptr.load_scalar_pair(fx);
409411
let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
410412
size
@@ -418,7 +420,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
418420
};
419421
min_align_of_val, (c ptr) {
420422
let layout = fx.layout_of(substs.type_at(0));
421-
let align = if layout.is_unsized() {
423+
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
424+
// branch
425+
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
422426
let (_ptr, info) = ptr.load_scalar_pair(fx);
423427
let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
424428
align

src/unsize.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
153153
layout: TyAndLayout<'tcx>,
154154
info: Value,
155155
) -> (Value, Value) {
156-
if !layout.is_unsized() {
157-
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
158-
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
159-
return (size, align);
160-
}
156+
assert!(layout.is_unsized() || layout.abi == Abi::Uninhabited);
161157
match layout.ty.kind() {
162158
ty::Dynamic(..) => {
163159
// load size/align from vtable

0 commit comments

Comments
 (0)