about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/ty
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-06 02:18:22 +0000
committerbors <bors@rust-lang.org>2024-03-06 02:18:22 +0000
commitb77e0184a95d60080f0d0605e2a3b337e904c21e (patch)
tree02f234cb3efa0a393b0e72e8a688e6a3d57d68b4 /compiler/rustc_middle/src/ty
parent62415e2a95a3b0f137636f86f6a904b8ed85798e (diff)
parent4f73d2a53c74428bd6e4fdda63b1dcc9fdf18353 (diff)
downloadrust-b77e0184a95d60080f0d0605e2a3b337e904c21e.tar.gz
rust-b77e0184a95d60080f0d0605e2a3b337e904c21e.zip
Auto merge of #122045 - matthiaskrgr:rollup-5l3vpn7, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #121065 (Add basic i18n guidance for `Display`)
 - #121744 (Stop using Bubble in coherence and instead emulate it with an intercrate check)
 - #121829 (Dummy tweaks (attempt 2))
 - #121857 (Implement async closure signature deduction)
 - #121894 (const_eval_select: make it safe but be careful with what we expose on stable for now)
 - #122014 (Change some attributes to only_local.)
 - #122016 (will_wake tests fail on Miri and that is expected)
 - #122018 (only set noalias on Box with the global allocator)
 - #122028 (Remove some dead code)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_middle/src/ty')
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs20
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs21
2 files changed, 33 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 5a0e2aa691d..dda41f70f06 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -969,6 +969,8 @@ where
         }
     }
 
+    /// Compute the information for the pointer stored at the given offset inside this type.
+    /// This will recurse into fields of ADTs to find the inner pointer.
     fn ty_and_layout_pointee_info_at(
         this: TyAndLayout<'tcx>,
         cx: &C,
@@ -1068,15 +1070,17 @@ where
                     }
                 }
 
-                // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
+                // Fixup info for the first field of a `Box`. Recursive traversal will have found
+                // the raw pointer, so size and align are set to the boxed type, but `pointee.safe`
+                // will still be `None`.
                 if let Some(ref mut pointee) = result {
-                    if let ty::Adt(def, _) = this.ty.kind() {
-                        if def.is_box() && offset.bytes() == 0 {
-                            let optimize = tcx.sess.opts.optimize != OptLevel::No;
-                            pointee.safe = Some(PointerKind::Box {
-                                unpin: optimize && this.ty.boxed_ty().is_unpin(tcx, cx.param_env()),
-                            });
-                        }
+                    if offset.bytes() == 0 && this.ty.is_box() {
+                        debug_assert!(pointee.safe.is_none());
+                        let optimize = tcx.sess.opts.optimize != OptLevel::No;
+                        pointee.safe = Some(PointerKind::Box {
+                            unpin: optimize && this.ty.boxed_ty().is_unpin(tcx, cx.param_env()),
+                            global: this.ty.is_box_global(tcx),
+                        });
                     }
                 }
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 4b349e7836c..a0baaa3ce28 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1999,6 +1999,27 @@ impl<'tcx> Ty<'tcx> {
         }
     }
 
+    /// Tests whether this is a Box using the global allocator.
+    #[inline]
+    pub fn is_box_global(self, tcx: TyCtxt<'tcx>) -> bool {
+        match self.kind() {
+            Adt(def, args) if def.is_box() => {
+                let Some(alloc) = args.get(1) else {
+                    // Single-argument Box is always global. (for "minicore" tests)
+                    return true;
+                };
+                if let Some(alloc_adt) = alloc.expect_ty().ty_adt_def() {
+                    let global_alloc = tcx.require_lang_item(LangItem::GlobalAlloc, None);
+                    alloc_adt.did() == global_alloc
+                } else {
+                    // Allocator is not an ADT...
+                    false
+                }
+            }
+            _ => false,
+        }
+    }
+
     /// Panics if called on any type other than `Box<T>`.
     pub fn boxed_ty(self) -> Ty<'tcx> {
         match self.kind() {