diff --git a/src/stacked_borrows/diagnostics.rs b/src/stacked_borrows/diagnostics.rs index b8e777717e..461715cedd 100644 --- a/src/stacked_borrows/diagnostics.rs +++ b/src/stacked_borrows/diagnostics.rs @@ -332,7 +332,7 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir // this allocation. if self.history.base.0.tag() == tag { Some(( - format!("{:?} was created here, as a base tag for {:?}", tag, self.history.id), + format!("{:?} was created here, as the base tag for {:?}", tag, self.history.id), self.history.base.1.data() )) } else { diff --git a/tests/fail/stacked_borrows/invalidate_against_protector3.rs b/tests/fail/stacked_borrows/invalidate_against_protector3.rs new file mode 100644 index 0000000000..634eb97217 --- /dev/null +++ b/tests/fail/stacked_borrows/invalidate_against_protector3.rs @@ -0,0 +1,15 @@ +use std::alloc::{alloc, Layout}; + +fn inner(x: *mut i32, _y: &i32) { + // If `x` and `y` alias, retagging is fine with this... but we really + // shouldn't be allowed to write to `x` at all because `y` was assumed to be + // immutable for the duration of this call. + unsafe { *x = 0 }; //~ ERROR: protect +} + +fn main() { + unsafe { + let ptr = alloc(Layout::for_value(&0i32)) as *mut i32; + inner(ptr, &*ptr); + }; +} diff --git a/tests/fail/stacked_borrows/invalidate_against_protector3.stderr b/tests/fail/stacked_borrows/invalidate_against_protector3.stderr new file mode 100644 index 0000000000..afda15ea16 --- /dev/null +++ b/tests/fail/stacked_borrows/invalidate_against_protector3.stderr @@ -0,0 +1,30 @@ +error: Undefined Behavior: not granting access to tag because that would remove [SharedReadOnly for ] which is protected because it is an argument of call ID + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | unsafe { *x = 0 }; + | ^^^^^^ not granting access to tag because that would remove [SharedReadOnly for ] which is protected because it is an argument of call ID + | + = 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 +help: was created here, as the base tag for ALLOC + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | let ptr = alloc(Layout::for_value(&0i32)) as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: is this argument + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^ + = note: BACKTRACE: + = note: inside `inner` at $DIR/invalidate_against_protector3.rs:LL:CC +note: inside `main` at $DIR/invalidate_against_protector3.rs:LL:CC + --> $DIR/invalidate_against_protector3.rs:LL:CC + | +LL | inner(ptr, &*ptr); + | ^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error +