Skip to content

Commit 38249be

Browse files
committed
Don't retag the PtrMetadata(&raw const *_n) in slice indexing
1 parent 612adbb commit 38249be

File tree

5 files changed

+29
-9
lines changed

5 files changed

+29
-9
lines changed

compiler/rustc_const_eval/src/interpret/step.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_middle::ty::layout::FnAbiOf;
99
use rustc_middle::ty::{self, Instance, Ty};
1010
use rustc_middle::{bug, mir, span_bug};
1111
use rustc_span::source_map::Spanned;
12+
use rustc_span::{DesugaringKind, Span};
1213
use rustc_target::callconv::FnAbi;
1314
use tracing::{info, instrument, trace};
1415

@@ -80,7 +81,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
8081
use rustc_middle::mir::StatementKind::*;
8182

8283
match &stmt.kind {
83-
Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
84+
Assign(box (place, rvalue)) => {
85+
self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
86+
}
8487

8588
SetDiscriminant { place, variant_index } => {
8689
let dest = self.eval_place(**place)?;
@@ -159,6 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
159162
&mut self,
160163
rvalue: &mir::Rvalue<'tcx>,
161164
place: mir::Place<'tcx>,
165+
span: Span,
162166
) -> InterpResult<'tcx> {
163167
let dest = self.eval_place(place)?;
164168
// FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -250,8 +254,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
250254
let src = self.eval_place(place)?;
251255
let place = self.force_allocation(&src)?;
252256
let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
253-
if !place_base_raw {
257+
if !place_base_raw
258+
&& span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
259+
{
254260
// If this was not already raw, it needs retagging.
261+
// Unless it's the `PtrMetadata(&raw const *_n)` from indexing.
255262
val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
256263
}
257264
self.write_immediate(*val, &dest)?;

compiler/rustc_mir_build/src/build/expr/as_place.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
1111
use rustc_middle::thir::*;
1212
use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
1313
use rustc_middle::{bug, span_bug};
14-
use rustc_span::Span;
14+
use rustc_span::{DesugaringKind, Span};
1515
use tracing::{debug, instrument, trace};
1616

1717
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -668,11 +668,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
668668
// the MIR we're building here needs to pass NLL later.
669669
Operand::Copy(Place::from(place.local))
670670
} else {
671+
let len_span = self.tcx.with_stable_hashing_context(|hcx| {
672+
let span = source_info.span;
673+
span.mark_with_reason(
674+
None,
675+
DesugaringKind::IndexBoundsCheckReborrow,
676+
span.edition(),
677+
hcx,
678+
)
679+
});
671680
let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
672681
let slice_ptr = self.temp(ptr_ty, span);
673682
self.cfg.push_assign(
674683
block,
675-
source_info,
684+
SourceInfo { span: len_span, ..source_info },
676685
slice_ptr,
677686
Rvalue::RawPtr(Mutability::Not, place),
678687
);

compiler/rustc_span/src/hygiene.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,9 @@ pub enum DesugaringKind {
11631163
WhileLoop,
11641164
/// `async Fn()` bound modifier
11651165
BoundModifier,
1166+
/// Marks a `&raw const *_1` needed as part of getting the length of a mutable
1167+
/// slice for the bounds check, so that MIRI's retag handling can recognize it.
1168+
IndexBoundsCheckReborrow,
11661169
}
11671170

11681171
impl DesugaringKind {
@@ -1179,6 +1182,7 @@ impl DesugaringKind {
11791182
DesugaringKind::ForLoop => "`for` loop",
11801183
DesugaringKind::WhileLoop => "`while` loop",
11811184
DesugaringKind::BoundModifier => "trait bound modifier",
1185+
DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
11821186
}
11831187
}
11841188
}

src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn main() {
1313
let v1 = safe::as_mut_slice(&v);
1414
let v2 = safe::as_mut_slice(&v);
1515
v1[1] = 5;
16-
//~[stack]^ ERROR: /trying to retag .+ for SharedReadOnly permission .+ tag does not exist in the borrow stack for this location/
16+
//~[stack]^ ERROR: /write access .* tag does not exist in the borrow stack/
1717
v2[1] = 7;
1818
//~[tree]^ ERROR: /write access through .* is forbidden/
1919
}

src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
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
1+
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
22
--> tests/fail/both_borrows/buggy_as_mut_slice.rs:LL:CC
33
|
44
LL | v1[1] = 5;
5-
| ^^^^^
5+
| ^^^^^^^^^
66
| |
7-
| trying to retag from <TAG> for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
8-
| this error occurs as part of retag at ALLOC[0x0..0xc]
7+
| attempting a write access using <TAG> at ALLOC[0x4], but that tag does not exist in the borrow stack for this location
8+
| this error occurs as part of an access at ALLOC[0x4..0x8]
99
|
1010
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
1111
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information

0 commit comments

Comments
 (0)