about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-07-25 11:35:24 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-07-25 12:47:49 +0000
commit7ef2ba8f7b2b3076d906567bb107b0437c45be48 (patch)
tree6681d75d5d1bddcb4059fd703b3ca976016d3672
parent39ee14d25346aa82e75e9818e92e3c43571c6757 (diff)
downloadrust-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.rs11
-rw-r--r--example/std_example.rs19
-rw-r--r--src/intrinsics/mod.rs8
-rw-r--r--src/unsize.rs6
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