Skip to content

slightly improve protector-related error messages #2513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions src/stacked_borrows/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use smallvec::SmallVec;
use std::fmt;

use rustc_middle::mir::interpret::{alloc_range, AllocId, AllocRange};
use rustc_span::{Span, SpanData};
use rustc_span::{Span, SpanData, DUMMY_SP};
use rustc_target::abi::Size;

use crate::helpers::CurrentSpan;
Expand Down Expand Up @@ -91,6 +91,7 @@ impl fmt::Display for InvalidationCause {

#[derive(Clone, Debug)]
struct Protection {
/// The parent tag from which this protected tag was derived.
orig_tag: ProvenanceExtra,
tag: SbTag,
span: Span,
Expand Down Expand Up @@ -342,32 +343,39 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir

let protected = protector_tag
.and_then(|protector| {
self.history.protectors.iter().find_map(|protection| {
if protection.tag == protector {
Some((protection.orig_tag, protection.span.data()))
} else {
None
}
self.history.protectors.iter().find(|protection| {
protection.tag == protector
})
})
.and_then(|(tag, call_span)| {
.and_then(|protection| {
self.history.creations.iter().rev().find_map(|event| {
if ProvenanceExtra::Concrete(event.retag.new_tag) == tag {
Some((event.retag.orig_tag, event.span.data(), call_span))
if ProvenanceExtra::Concrete(event.retag.new_tag) == protection.orig_tag {
Some((protection, event))
} else {
None
}
})
})
.map(|(protecting_tag, protecting_tag_span, protection_span)| {
.map(|(protection, protection_parent)| {
let protected_tag = protection.tag;
[
(
format!(
"{tag:?} was protected due to {protecting_tag:?} which was created here"
"{tag:?} cannot be used for memory access because that would remove protected tag {protected_tag:?}, protected by this function call",
),
protecting_tag_span,
protection.span.data(),
),
(format!("this protector is live for this call"), protection_span),
if protection_parent.retag.new_tag == tag {
(format!("{protected_tag:?} was derived from {tag:?}, the tag used for this memory access"), DUMMY_SP.data())
} else {
(
format!(
"{protected_tag:?} was derived from {protected_parent_tag:?}, which in turn was created here",
protected_parent_tag = protection_parent.retag.new_tag,
),
protection_parent.span.data()
)
}
]
});

Expand Down
8 changes: 2 additions & 6 deletions tests/fail/stacked_borrows/aliasing_mut1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@ help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
LL | let xraw: *mut i32 = unsafe { mem::transmute(&mut x) };
| ^^^^^^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/aliasing_mut1.rs:LL:CC
|
LL | let xraw: *mut i32 = unsafe { mem::transmute(&mut x) };
| ^^^^^^
help: this protector is live for this call
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/aliasing_mut1.rs:LL:CC
|
LL | pub fn safe(_x: &mut i32, _y: &mut i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: <TAG> was derived from <TAG>, the tag used for this memory access
= note: backtrace:
= note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC
note: inside `main` at $DIR/aliasing_mut1.rs:LL:CC
Expand Down
12 changes: 6 additions & 6 deletions tests/fail/stacked_borrows/aliasing_mut2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
LL | let xref = &mut x;
| ^^^^^^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/aliasing_mut2.rs:LL:CC
|
LL | safe_raw(xshr, xraw);
| ^^^^
help: this protector is live for this call
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/aliasing_mut2.rs:LL:CC
|
LL | pub fn safe(_x: &i32, _y: &mut i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <TAG> was derived from <TAG>, which in turn was created here
--> $DIR/aliasing_mut2.rs:LL:CC
|
LL | safe_raw(xshr, xraw);
| ^^^^
= note: backtrace:
= note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC
note: inside `main` at $DIR/aliasing_mut2.rs:LL:CC
Expand Down
12 changes: 6 additions & 6 deletions tests/fail/stacked_borrows/aliasing_mut4.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
LL | let xref = &mut x;
| ^^^^^^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/aliasing_mut4.rs:LL:CC
|
LL | safe_raw(xshr, xraw as *mut _);
| ^^^^
help: this protector is live for this call
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/aliasing_mut4.rs:LL:CC
|
LL | pub fn safe(_x: &i32, _y: &mut Cell<i32>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <TAG> was derived from <TAG>, which in turn was created here
--> $DIR/aliasing_mut4.rs:LL:CC
|
LL | safe_raw(xshr, xraw as *mut _);
| ^^^^
= note: backtrace:
= note: inside `safe` at $DIR/aliasing_mut4.rs:LL:CC
note: inside `main` at $DIR/aliasing_mut4.rs:LL:CC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
= note: inside `alloc::alloc::box_free::<i32, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
= note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
note: inside closure at $DIR/deallocate_against_barrier1.rs:LL:CC
--> $DIR/deallocate_against_barrier1.rs:LL:CC
note: inside closure at $DIR/deallocate_against_protector1.rs:LL:CC
--> $DIR/deallocate_against_protector1.rs:LL:CC
|
LL | drop(unsafe { Box::from_raw(raw) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: inside `<[closure@$DIR/deallocate_against_barrier1.rs:LL:CC] as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
note: inside `inner` at $DIR/deallocate_against_barrier1.rs:LL:CC
--> $DIR/deallocate_against_barrier1.rs:LL:CC
= note: inside `<[closure@$DIR/deallocate_against_protector1.rs:LL:CC] as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
note: inside `inner` at $DIR/deallocate_against_protector1.rs:LL:CC
--> $DIR/deallocate_against_protector1.rs:LL:CC
|
LL | f(x)
| ^^^^
note: inside `main` at $DIR/deallocate_against_barrier1.rs:LL:CC
--> $DIR/deallocate_against_barrier1.rs:LL:CC
note: inside `main` at $DIR/deallocate_against_protector1.rs:LL:CC
--> $DIR/deallocate_against_protector1.rs:LL:CC
|
LL | / inner(Box::leak(Box::new(0)), |x| {
LL | | let raw = x as *mut _;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
= note: inside `alloc::alloc::box_free::<NotUnpin, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `std::ptr::drop_in_place::<std::boxed::Box<NotUnpin>> - shim(Some(std::boxed::Box<NotUnpin>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
= note: inside `std::mem::drop::<std::boxed::Box<NotUnpin>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
note: inside closure at $DIR/deallocate_against_barrier2.rs:LL:CC
--> $DIR/deallocate_against_barrier2.rs:LL:CC
note: inside closure at $DIR/deallocate_against_protector2.rs:LL:CC
--> $DIR/deallocate_against_protector2.rs:LL:CC
|
LL | drop(unsafe { Box::from_raw(raw) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: inside `<[closure@$DIR/deallocate_against_barrier2.rs:LL:CC] as std::ops::FnOnce<(&mut NotUnpin,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
note: inside `inner` at $DIR/deallocate_against_barrier2.rs:LL:CC
--> $DIR/deallocate_against_barrier2.rs:LL:CC
= note: inside `<[closure@$DIR/deallocate_against_protector2.rs:LL:CC] as std::ops::FnOnce<(&mut NotUnpin,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
note: inside `inner` at $DIR/deallocate_against_protector2.rs:LL:CC
--> $DIR/deallocate_against_protector2.rs:LL:CC
|
LL | f(x)
| ^^^^
note: inside `main` at $DIR/deallocate_against_barrier2.rs:LL:CC
--> $DIR/deallocate_against_barrier2.rs:LL:CC
note: inside `main` at $DIR/deallocate_against_protector2.rs:LL:CC
--> $DIR/deallocate_against_protector2.rs:LL:CC
|
LL | / inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| {
LL | | let raw = x as *mut _;
Expand Down
12 changes: 6 additions & 6 deletions tests/fail/stacked_borrows/illegal_write6.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
LL | let p = x as *mut u32;
| ^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/illegal_write6.rs:LL:CC
|
LL | foo(x, p);
| ^
help: this protector is live for this call
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/illegal_write6.rs:LL:CC
|
LL | / fn foo(a: &mut u32, y: *mut u32) -> u32 {
Expand All @@ -26,6 +21,11 @@ LL | | unsafe { *y = 2 };
LL | | return *a;
LL | | }
| |_^
help: <TAG> was derived from <TAG>, which in turn was created here
--> $DIR/illegal_write6.rs:LL:CC
|
LL | foo(x, p);
| ^
= note: backtrace:
= note: inside `foo` at $DIR/illegal_write6.rs:LL:CC
note: inside `main` at $DIR/illegal_write6.rs:LL:CC
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
error: Undefined Behavior: not granting access to tag <TAG> because incompatible item [Unique for <TAG>] is protected by call ID
--> $DIR/invalidate_against_barrier1.rs:LL:CC
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
LL | let _val = unsafe { *x };
| ^^ not granting access to tag <TAG> because incompatible item [Unique for <TAG>] is protected by 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: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
--> $DIR/invalidate_against_barrier1.rs:LL:CC
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
LL | let xraw = &mut x as *mut _;
| ^^^^^^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/invalidate_against_barrier1.rs:LL:CC
|
LL | inner(xraw, xref);
| ^^^^
help: this protector is live for this call
--> $DIR/invalidate_against_barrier1.rs:LL:CC
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
LL | / fn inner(x: *mut i32, _y: &mut i32) {
LL | | // If `x` and `y` alias, retagging is fine with this... but we really
Expand All @@ -26,10 +21,15 @@ LL | | // unique for the duration of this call.
LL | | let _val = unsafe { *x };
LL | | }
| |_^
help: <TAG> was derived from <TAG>, which in turn was created here
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
LL | inner(xraw, xref);
| ^^^^
= note: backtrace:
= note: inside `inner` at $DIR/invalidate_against_barrier1.rs:LL:CC
note: inside `main` at $DIR/invalidate_against_barrier1.rs:LL:CC
--> $DIR/invalidate_against_barrier1.rs:LL:CC
= note: inside `inner` at $DIR/invalidate_against_protector1.rs:LL:CC
note: inside `main` at $DIR/invalidate_against_protector1.rs:LL:CC
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
LL | inner(xraw, xref);
| ^^^^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
error: Undefined Behavior: not granting access to tag <TAG> because incompatible item [SharedReadOnly for <TAG>] is protected by call ID
--> $DIR/invalidate_against_barrier2.rs:LL:CC
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
LL | unsafe { *x = 0 };
| ^^^^^^ not granting access to tag <TAG> because incompatible item [SharedReadOnly for <TAG>] is protected by 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: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
--> $DIR/invalidate_against_barrier2.rs:LL:CC
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
LL | let xraw = &mut x as *mut _;
| ^^^^^^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/invalidate_against_barrier2.rs:LL:CC
|
LL | inner(xraw, xref);
| ^^^^
help: this protector is live for this call
--> $DIR/invalidate_against_barrier2.rs:LL:CC
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
LL | / fn inner(x: *mut i32, _y: &i32) {
LL | | // If `x` and `y` alias, retagging is fine with this... but we really
Expand All @@ -26,10 +21,15 @@ LL | | // immutable for the duration of this call.
LL | | unsafe { *x = 0 };
LL | | }
| |_^
help: <TAG> was derived from <TAG>, which in turn was created here
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
LL | inner(xraw, xref);
| ^^^^
= note: backtrace:
= note: inside `inner` at $DIR/invalidate_against_barrier2.rs:LL:CC
note: inside `main` at $DIR/invalidate_against_barrier2.rs:LL:CC
--> $DIR/invalidate_against_barrier2.rs:LL:CC
= note: inside `inner` at $DIR/invalidate_against_protector2.rs:LL:CC
note: inside `main` at $DIR/invalidate_against_protector2.rs:LL:CC
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
LL | inner(xraw, xref);
| ^^^^^^^^^^^^^^^^^
Expand Down
12 changes: 6 additions & 6 deletions tests/fail/stacked_borrows/newtype_retagging.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
LL | let ptr = Box::into_raw(Box::new(0i32));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <TAG> was protected due to <TAG> which was created here
--> $DIR/newtype_retagging.rs:LL:CC
|
LL | Newtype(&mut *ptr),
| ^^^^^^^^^^^^^^^^^^
help: this protector is live for this call
help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/newtype_retagging.rs:LL:CC
|
LL | / fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
LL | | dealloc();
LL | | }
| |_^
help: <TAG> was derived from <TAG>, which in turn was created here
--> $DIR/newtype_retagging.rs:LL:CC
|
LL | Newtype(&mut *ptr),
| ^^^^^^^^^^^^^^^^^^
= note: backtrace:
= note: inside `std::boxed::Box::<i32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC
= note: inside `std::boxed::Box::<i32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC
Expand Down