about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2024-12-13 02:00:20 -0800
committerScott McMurray <scottmcm@users.noreply.github.com>2024-12-13 02:00:20 -0800
commit38249be509101e87ea4ac10951b1b4ce554f1cc0 (patch)
tree9e090fcb0ebad1290811af2cc560604c3cdbb80d
parent612adbb6bf88ecf549fb93cb1f4edcf793bca88e (diff)
downloadrust-38249be509101e87ea4ac10951b1b4ce554f1cc0.tar.gz
rust-38249be509101e87ea4ac10951b1b4ce554f1cc0.zip
Don't retag the `PtrMetadata(&raw const *_n)` in slice indexing
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs11
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs13
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs2
-rw-r--r--src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr8
5 files changed, 29 insertions, 9 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index b61865be667..f6d2e476738 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,6 +9,7 @@ use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::source_map::Spanned;
+use rustc_span::{DesugaringKind, Span};
 use rustc_target::callconv::FnAbi;
 use tracing::{info, instrument, trace};
 
@@ -80,7 +81,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         use rustc_middle::mir::StatementKind::*;
 
         match &stmt.kind {
-            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
+            Assign(box (place, rvalue)) => {
+                self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
+            }
 
             SetDiscriminant { place, variant_index } => {
                 let dest = self.eval_place(**place)?;
@@ -159,6 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         &mut self,
         rvalue: &mir::Rvalue<'tcx>,
         place: mir::Place<'tcx>,
+        span: Span,
     ) -> InterpResult<'tcx> {
         let dest = self.eval_place(place)?;
         // FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -250,8 +254,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
                 let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
-                if !place_base_raw {
+                if !place_base_raw
+                    && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
+                {
                     // If this was not already raw, it needs retagging.
+                    // Unless it's the `PtrMetadata(&raw const *_n)` from indexing.
                     val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
                 }
                 self.write_immediate(*val, &dest)?;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 9f377f792ef..70a74910a68 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
 use rustc_middle::{bug, span_bug};
-use rustc_span::Span;
+use rustc_span::{DesugaringKind, Span};
 use tracing::{debug, instrument, trace};
 
 use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -668,11 +668,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     // the MIR we're building here needs to pass NLL later.
                     Operand::Copy(Place::from(place.local))
                 } else {
+                    let len_span = self.tcx.with_stable_hashing_context(|hcx| {
+                        let span = source_info.span;
+                        span.mark_with_reason(
+                            None,
+                            DesugaringKind::IndexBoundsCheckReborrow,
+                            span.edition(),
+                            hcx,
+                        )
+                    });
                     let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
                     let slice_ptr = self.temp(ptr_ty, span);
                     self.cfg.push_assign(
                         block,
-                        source_info,
+                        SourceInfo { span: len_span, ..source_info },
                         slice_ptr,
                         Rvalue::RawPtr(Mutability::Not, place),
                     );
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index a5826137181..3cdae437b7d 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1163,6 +1163,9 @@ pub enum DesugaringKind {
     WhileLoop,
     /// `async Fn()` bound modifier
     BoundModifier,
+    /// Marks a `&raw const *_1` needed as part of getting the length of a mutable
+    /// slice for the bounds check, so that MIRI's retag handling can recognize it.
+    IndexBoundsCheckReborrow,
 }
 
 impl DesugaringKind {
@@ -1179,6 +1182,7 @@ impl DesugaringKind {
             DesugaringKind::ForLoop => "`for` loop",
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
+            DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
         }
     }
 }
diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs
index 6027b5c0f5f..6d535a14c04 100644
--- a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs
+++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs
@@ -13,7 +13,7 @@ fn main() {
     let v1 = safe::as_mut_slice(&v);
     let v2 = safe::as_mut_slice(&v);
     v1[1] = 5;
-    //~[stack]^ ERROR: /trying to retag .+ for SharedReadOnly permission .+ tag does not exist in the borrow stack for this location/
+    //~[stack]^ ERROR: /write access .* tag does not exist in the borrow stack/
     v2[1] = 7;
     //~[tree]^ ERROR: /write access through .* is forbidden/
 }
diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr
index c5488a537a2..4e5355f5653 100644
--- a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr
@@ -1,11 +1,11 @@
-error: Undefined Behavior: trying to retag from <TAG> for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
+error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[0x4], but that tag does not exist in the borrow stack for this location
   --> tests/fail/both_borrows/buggy_as_mut_slice.rs:LL:CC
    |
 LL |     v1[1] = 5;
-   |     ^^^^^
+   |     ^^^^^^^^^
    |     |
-   |     trying to retag from <TAG> for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
-   |     this error occurs as part of retag at ALLOC[0x0..0xc]
+   |     attempting a write access using <TAG> at ALLOC[0x4], but that tag does not exist in the borrow stack for this location
+   |     this error occurs as part of an access at ALLOC[0x4..0x8]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information