about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs28
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs2
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs31
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs22
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/sys/unix/fs.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/linkchecker/main.rs1
-rw-r--r--tests/rustdoc-gui/search-error.goml6
13 files changed, 82 insertions, 46 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 64c6d17469b..e7c3906d977 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -441,7 +441,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             LocalRef::Place(place) => place,
             LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
             LocalRef::Operand(..) => {
-                if place_ref.has_deref() {
+                if place_ref.is_indirect_first_projection() {
                     base = 1;
                     let cg_base = self.codegen_consume(
                         bx,
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 0ef5522729a..a6edc6fb363 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -247,7 +247,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
             AddressOf(_, place) => {
                 // Figure out whether this is an addr_of of an already raw place.
-                let place_base_raw = if place.has_deref() {
+                let place_base_raw = if place.is_indirect_first_projection() {
                     let ty = self.frame().body.local_decls[place.local].ty;
                     ty.is_unsafe_ptr()
                 } else {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index c1f87d79b83..ddb5e248cdc 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1592,14 +1592,13 @@ impl<'tcx> Place<'tcx> {
         self.projection.iter().any(|elem| elem.is_indirect())
     }
 
-    /// If MirPhase >= Derefered and if projection contains Deref,
-    /// It's guaranteed to be in the first place
-    pub fn has_deref(&self) -> bool {
-        // To make sure this is not accidentally used in wrong mir phase
-        debug_assert!(
-            self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
-        );
-        self.projection.first() == Some(&PlaceElem::Deref)
+    /// Returns `true` if this `Place`'s first projection is `Deref`.
+    ///
+    /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
+    /// `Deref` projections can only occur as the first projection. In that case this method
+    /// is equivalent to `is_indirect`, but faster.
+    pub fn is_indirect_first_projection(&self) -> bool {
+        self.as_ref().is_indirect_first_projection()
     }
 
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -1672,9 +1671,16 @@ impl<'tcx> PlaceRef<'tcx> {
         self.projection.iter().any(|elem| elem.is_indirect())
     }
 
-    /// If MirPhase >= Derefered and if projection contains Deref,
-    /// It's guaranteed to be in the first place
-    pub fn has_deref(&self) -> bool {
+    /// Returns `true` if this `Place`'s first projection is `Deref`.
+    ///
+    /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
+    /// `Deref` projections can only occur as the first projection. In that case this method
+    /// is equivalent to `is_indirect`, but faster.
+    pub fn is_indirect_first_projection(&self) -> bool {
+        // To make sure this is not accidentally used in wrong mir phase
+        debug_assert!(
+            self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
+        );
         self.projection.first() == Some(&PlaceElem::Deref)
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 8d78ec04821..17bb8fc37ad 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -839,7 +839,7 @@ impl Map {
         tail_elem: Option<TrackElem>,
         f: &mut impl FnMut(ValueIndex),
     ) {
-        if place.has_deref() {
+        if place.is_indirect_first_projection() {
             // We do not track indirect places.
             return;
         }
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index d9e7339f1b2..75473ca53fb 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
         let basic_blocks = body.basic_blocks.as_mut();
         let local_decls = &body.local_decls;
         let needs_retag = |place: &Place<'tcx>| {
-            !place.has_deref() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
+            !place.is_indirect_first_projection() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
                 && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
                 && !local_decls[place.local].is_deref_temp()
         };
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index 47d9f52bfb5..9a3798eea3b 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -154,7 +154,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
         if let Operand::Move(place) = *operand
             // A move out of a projection of a copy is equivalent to a copy of the original projection.
-            && !place.has_deref()
+            && !place.is_indirect_first_projection()
             && !self.fully_moved.contains(place.local)
         {
             *operand = Operand::Copy(place);
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index c4bdec0ee28..e377843cdb4 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1063,3 +1063,34 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::BoundTy {
         BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) }
     }
 }
+
+impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
+    type T = stable_mir::ty::Allocation;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let size = self.size();
+        let mut bytes: Vec<Option<u8>> = self
+            .inspect_with_uninit_and_ptr_outside_interpreter(0..size.bytes_usize())
+            .iter()
+            .copied()
+            .map(Some)
+            .collect();
+        for (i, b) in bytes.iter_mut().enumerate() {
+            if !self.init_mask().get(rustc_target::abi::Size::from_bytes(i)) {
+                *b = None;
+            }
+        }
+        stable_mir::ty::Allocation {
+            bytes: bytes,
+            provenance: {
+                let mut ptrs = Vec::new();
+                for (size, prov) in self.provenance().ptrs().iter() {
+                    ptrs.push((size.bytes_usize(), opaque(prov)));
+                }
+                stable_mir::ty::ProvenanceMap { ptrs }
+            },
+            align: self.align.bytes(),
+            mutability: self.mutability.stable(tables),
+        }
+    }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 025225b8d19..df28fc4eed9 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -242,3 +242,25 @@ pub struct BoundTy {
     pub var: usize,
     pub kind: BoundTyKind,
 }
+
+pub type Bytes = Vec<Option<u8>>;
+pub type Size = usize;
+pub type Prov = Opaque;
+pub type Align = u64;
+pub type InitMaskMaterialized = Vec<u64>;
+
+/// Stores the provenance information of pointers stored in memory.
+#[derive(Clone, Debug)]
+pub struct ProvenanceMap {
+    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
+    /// bytes. Two entries in this map are always at least a pointer size apart.
+    pub ptrs: Vec<(Size, Prov)>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Allocation {
+    pub bytes: Bytes,
+    pub provenance: ProvenanceMap,
+    pub align: Align,
+    pub mutability: Mutability,
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 2f9cd7bc0ca..31481de8495 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -298,6 +298,7 @@
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(maybe_uninit_write_slice)]
+#![feature(offset_of)]
 #![feature(panic_can_unwind)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index fbc7f04ce9a..7dc809a038b 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -7,17 +7,6 @@ use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
-#[cfg(any(
-    target_os = "android",
-    target_os = "linux",
-    target_os = "solaris",
-    target_os = "fuchsia",
-    target_os = "redox",
-    target_os = "illumos",
-    target_os = "nto",
-    target_os = "vita",
-))]
-use crate::mem::MaybeUninit;
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
 use crate::path::{Path, PathBuf};
 use crate::ptr;
@@ -712,22 +701,10 @@ impl Iterator for ReadDir {
                 // requires the full extent of *entry_ptr to be in bounds of the same
                 // allocation, which is not necessarily the case here.
                 //
-                // Absent any other way to obtain a pointer to `(*entry_ptr).d_name`
-                // legally in Rust analogously to how it would be done in C, we instead
-                // need to make our own non-libc allocation that conforms to the weird
-                // imaginary definition of dirent64, and use that for a field offset
-                // computation.
+                // Instead we must access fields individually through their offsets.
                 macro_rules! offset_ptr {
                     ($entry_ptr:expr, $field:ident) => {{
-                        const OFFSET: isize = {
-                            let delusion = MaybeUninit::<dirent64>::uninit();
-                            let entry_ptr = delusion.as_ptr();
-                            unsafe {
-                                ptr::addr_of!((*entry_ptr).$field)
-                                    .cast::<u8>()
-                                    .offset_from(entry_ptr.cast::<u8>())
-                            }
-                        };
+                        const OFFSET: isize = mem::offset_of!(dirent64, $field) as isize;
                         if true {
                             // Cast to the same type determined by the else branch.
                             $entry_ptr.byte_offset(OFFSET).cast::<_>()
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 137bd9c9451..bc011a6c354 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1170,7 +1170,7 @@ fn referent_used_exactly_once<'tcx>(
         && let [location] = *local_assignments(mir, local).as_slice()
         && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
         && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
-        && !place.has_deref()
+        && !place.is_indirect_first_projection()
         // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
         && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
     {
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index c8a370085a0..7f73cac63cb 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -368,7 +368,6 @@ impl Checker {
             return;
         }
         // Search for intra-doc links that rustdoc didn't warn about
-        // FIXME(#77199, 77200) Rustdoc should just warn about these directly.
         // NOTE: only looks at one line at a time; in practice this should find most links
         for (i, line) in source.lines().enumerate() {
             for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) {
diff --git a/tests/rustdoc-gui/search-error.goml b/tests/rustdoc-gui/search-error.goml
index d21905e90ae..70aeda1769a 100644
--- a/tests/rustdoc-gui/search-error.goml
+++ b/tests/rustdoc-gui/search-error.goml
@@ -20,20 +20,20 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "error_background": "rgb(79, 76, 76)",
+        "error_background": "#4f4c4c",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "error_background": "rgb(72, 72, 72)",
+        "error_background": "#484848",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "error_background": "rgb(208, 204, 204)",
+        "error_background": "#d0cccc",
     },
 )