Skip to content

Commit 194710e

Browse files
committed
no barriers for boxes
1 parent 5830995 commit 194710e

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

src/stacked_borrows.rs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -673,19 +673,27 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
673673
fn_entry: bool,
674674
place: PlaceTy<'tcx, Borrow>
675675
) -> EvalResult<'tcx> {
676+
// Determine mutability and whether to add a barrier.
677+
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
678+
// making it useless.
679+
fn qualify(ty: ty::Ty<'_>, fn_entry: bool) -> Option<(Mutability, bool)> {
680+
match ty.sty {
681+
// References are simple
682+
ty::Ref(_, _, mutbl) => Some((mutbl, fn_entry)),
683+
// Boxes do not get a barrier: Barriers reflect that references outlive the call
684+
// they were passed in to; that's just not the case for boxes.
685+
ty::Adt(..) if ty.is_box() => Some((MutMutable, false)),
686+
_ => None,
687+
}
688+
}
689+
676690
// We need a visitor to visit all references. However, that requires
677691
// a `MemPlace`, so we have a fast path for reference types that
678692
// avoids allocating.
679-
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
680-
// making it useless.
681-
if let Some(mutbl) = match place.layout.ty.sty {
682-
ty::Ref(_, _, mutbl) => Some(mutbl),
683-
ty::Adt(..) if place.layout.ty.is_box() => Some(MutMutable),
684-
_ => None, // handled with the general case below
685-
} {
693+
if let Some((mutbl, barrier)) = qualify(place.layout.ty, fn_entry) {
686694
// fast path
687695
let val = self.read_immediate(self.place_to_op(place)?)?;
688-
let val = self.retag_reference(val, mutbl, fn_entry)?;
696+
let val = self.retag_reference(val, mutbl, barrier)?;
689697
self.write_immediate(val, place)?;
690698
return Ok(());
691699
}
@@ -716,14 +724,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
716724
{
717725
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
718726
// making it useless.
719-
let mutbl = match place.layout.ty.sty {
720-
ty::Ref(_, _, mutbl) => mutbl,
721-
ty::Adt(..) if place.layout.ty.is_box() => MutMutable,
722-
_ => return Ok(()), // nothing to do
723-
};
724-
let val = self.ecx.read_immediate(place.into())?;
725-
let val = self.ecx.retag_reference(val, mutbl, self.fn_entry)?;
726-
self.ecx.write_immediate(val, place.into())?;
727+
if let Some((mutbl, barrier)) = qualify(place.layout.ty, self.fn_entry) {
728+
let val = self.ecx.read_immediate(place.into())?;
729+
let val = self.ecx.retag_reference(val, mutbl, barrier)?;
730+
self.ecx.write_immediate(val, place.into())?;
731+
}
727732
Ok(())
728733
}
729734
}

tests/compile-fail-fullmir/stacked_borrows/box_exclusive_violation1.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn demo_mut_advanced_unique(mut our: Box<i32>) -> i32 {
88
unknown_code_2();
99

1010
// We know this will return 5
11-
*our
11+
*our //~ ERROR does not exist on the stack
1212
}
1313

1414
// Now comes the evil context
@@ -21,7 +21,7 @@ fn unknown_code_1(x: &i32) { unsafe {
2121
} }
2222

2323
fn unknown_code_2() { unsafe {
24-
*LEAK = 7; //~ ERROR barrier
24+
*LEAK = 7;
2525
} }
2626

2727
fn main() {

0 commit comments

Comments
 (0)