diff options
| author | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2022-07-25 11:35:24 +0000 |
|---|---|---|
| committer | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2022-07-25 12:47:49 +0000 |
| commit | 7ef2ba8f7b2b3076d906567bb107b0437c45be48 (patch) | |
| tree | 6681d75d5d1bddcb4059fd703b3ca976016d3672 | |
| parent | 39ee14d25346aa82e75e9818e92e3c43571c6757 (diff) | |
| download | rust-7ef2ba8f7b2b3076d906567bb107b0437c45be48.tar.gz rust-7ef2ba8f7b2b3076d906567bb107b0437c45be48.zip | |
Fix size_of_val and min_align_of_val for truly unsized types
| -rw-r--r-- | example/mini_core_hello_world.rs | 11 | ||||
| -rw-r--r-- | example/std_example.rs | 19 | ||||
| -rw-r--r-- | src/intrinsics/mod.rs | 8 | ||||
| -rw-r--r-- | src/unsize.rs | 6 |
4 files changed, 37 insertions, 7 deletions
diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 6111e035282..aa1f239bae2 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -330,6 +330,17 @@ fn main() { static REF1: &u8 = &42; static REF2: &u8 = REF1; assert_eq!(*REF1, *REF2); + + extern "C" { + type A; + } + + fn main() { + let x: &A = unsafe { &*(1usize as *const A) }; + + assert_eq!(unsafe { intrinsics::size_of_val(x) }, 0); + assert_eq!(unsafe { intrinsics::min_align_of_val(x) }, 1); +} } #[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))] diff --git a/example/std_example.rs b/example/std_example.rs index 0a2bce2621d..0b5b6cd55d7 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -128,6 +128,25 @@ fn main() { 0 => loop {}, v => panic(v), }; + + if black_box(false) { + // Based on https://github.com/rust-lang/rust/blob/2f320a224e827b400be25966755a621779f797cc/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs + let _ = Foo::<dyn Send>::new(); + + #[allow(dead_code)] + struct Foo<T: ?Sized> { + base: Never, + value: T, + } + + impl<T: ?Sized> Foo<T> { + pub fn new() -> Box<Foo<T>> { + todo!() + } + } + + enum Never {} + } } fn panic(_: u128) { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index eb58cfbb356..537aade8b86 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -404,7 +404,9 @@ fn codegen_regular_intrinsic_call<'tcx>( }; size_of_val, (c ptr) { let layout = fx.layout_of(substs.type_at(0)); - let size = if layout.is_unsized() { + // Note: Can't use is_unsized here as truly unsized types need to take the fixed size + // branch + let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi { let (_ptr, info) = ptr.load_scalar_pair(fx); let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info); size @@ -418,7 +420,9 @@ fn codegen_regular_intrinsic_call<'tcx>( }; min_align_of_val, (c ptr) { let layout = fx.layout_of(substs.type_at(0)); - let align = if layout.is_unsized() { + // Note: Can't use is_unsized here as truly unsized types need to take the fixed size + // branch + let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi { let (_ptr, info) = ptr.load_scalar_pair(fx); let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info); align diff --git a/src/unsize.rs b/src/unsize.rs index fd63c3ecddb..052ca0a082b 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -153,11 +153,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>( layout: TyAndLayout<'tcx>, info: Value, ) -> (Value, Value) { - if !layout.is_unsized() { - let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64); - let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64); - return (size, align); - } + assert!(layout.is_unsized() || layout.abi == Abi::Uninhabited); match layout.ty.kind() { ty::Dynamic(..) => { // load size/align from vtable |
