]> git.lizzy.rs Git - rust.git/commitdiff
fix box icing when it has aggregate abi
authorDrMeepster <19316085+DrMeepster@users.noreply.github.com>
Sun, 27 Feb 2022 08:48:17 +0000 (00:48 -0800)
committerDrMeepster <19316085+DrMeepster@users.noreply.github.com>
Sun, 27 Feb 2022 08:48:17 +0000 (00:48 -0800)
compiler/rustc_codegen_ssa/src/mir/place.rs
src/test/ui/box/issue-81270-ice.rs [new file with mode: 0644]

index 6976999c0e4f7a4b457601959465a54ae995db1e..aee385ab050e4cd08725e985de4c9274c7a04955 100644 (file)
@@ -453,7 +453,18 @@ pub fn codegen_place(
         };
         for elem in place_ref.projection[base..].iter() {
             cg_base = match elem.clone() {
-                mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
+                mir::ProjectionElem::Deref => {
+                    // custom allocators can change box's abi, making it unable to be derefed directly
+                    if cg_base.layout.ty.is_box()
+                        && matches!(cg_base.layout.abi, Abi::Aggregate { .. })
+                    {
+                        let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
+
+                        bx.load_operand(ptr).deref(bx.cx())
+                    } else {
+                        bx.load_operand(cg_base).deref(bx.cx())
+                    }
+                }
                 mir::ProjectionElem::Field(ref field, _) => {
                     cg_base.project_field(bx, field.index())
                 }
diff --git a/src/test/ui/box/issue-81270-ice.rs b/src/test/ui/box/issue-81270-ice.rs
new file mode 100644 (file)
index 0000000..fb42aed
--- /dev/null
@@ -0,0 +1,22 @@
+// check-pass
+#![feature(allocator_api)]
+
+use std::alloc::Allocator;
+
+struct BigAllocator([usize; 2]);
+
+unsafe impl Allocator for BigAllocator {
+    fn allocate(
+        &self,
+        _: std::alloc::Layout,
+    ) -> Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError> {
+        todo!()
+    }
+    unsafe fn deallocate(&self, _: std::ptr::NonNull<u8>, _: std::alloc::Layout) {
+        todo!()
+    }
+}
+
+fn main() {
+    Box::new_in((), BigAllocator([0; 2]));
+}