diff --git a/README.md b/README.md index d318222f7f..a78cc9d931 100644 --- a/README.md +++ b/README.md @@ -457,9 +457,6 @@ to Miri failing to detect cases of undefined behavior in a program. casts are not supported in this mode, but that may change in the future. * `-Zmiri-force-page-size=` overrides the default page size for an architecture, in multiples of 1k. `4` is default for most targets. This value should always be a power of 2 and nonzero. -* `-Zmiri-unique-is-unique` performs additional aliasing checks for `core::ptr::Unique` to ensure - that it could theoretically be considered `noalias`. This flag is experimental and has - an effect only when used with `-Zmiri-tree-borrows`. [function ABI]: https://doc.rust-lang.org/reference/items/functions.html#extern-function-qualifier diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 411f9191bd..69aa035fdc 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -554,8 +554,6 @@ fn main() { } else if arg == "-Zmiri-tree-borrows" { miri_config.borrow_tracker = Some(BorrowTrackerMethod::TreeBorrows); miri_config.provenance_mode = ProvenanceMode::Strict; - } else if arg == "-Zmiri-unique-is-unique" { - miri_config.unique_is_unique = true; } else if arg == "-Zmiri-disable-data-race-detector" { miri_config.data_race_detector = false; miri_config.weak_memory_emulation = false; @@ -722,14 +720,6 @@ fn main() { rustc_args.push(arg); } } - // `-Zmiri-unique-is-unique` should only be used with `-Zmiri-tree-borrows`. - if miri_config.unique_is_unique - && !matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows)) - { - show_error!( - "-Zmiri-unique-is-unique only has an effect when -Zmiri-tree-borrows is also used" - ); - } // Tree Borrows implies strict provenance, and is not compatible with native calls. if matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows)) { if miri_config.provenance_mode != ProvenanceMode::Strict { diff --git a/src/borrow_tracker/mod.rs b/src/borrow_tracker/mod.rs index 9808102f4b..b66c561d2b 100644 --- a/src/borrow_tracker/mod.rs +++ b/src/borrow_tracker/mod.rs @@ -102,8 +102,6 @@ pub struct GlobalStateInner { tracked_pointer_tags: FxHashSet, /// Whether to recurse into datatypes when searching for pointers to retag. retag_fields: RetagFields, - /// Whether `core::ptr::Unique` gets special (`Box`-like) handling. - unique_is_unique: bool, } impl VisitProvenance for GlobalStateInner { @@ -164,7 +162,6 @@ impl GlobalStateInner { borrow_tracker_method: BorrowTrackerMethod, tracked_pointer_tags: FxHashSet, retag_fields: RetagFields, - unique_is_unique: bool, ) -> Self { GlobalStateInner { borrow_tracker_method, @@ -173,7 +170,6 @@ impl GlobalStateInner { protected_tags: FxHashMap::default(), tracked_pointer_tags, retag_fields, - unique_is_unique, } } @@ -239,7 +235,6 @@ impl BorrowTrackerMethod { self, config.tracked_pointer_tags.clone(), config.retag_fields, - config.unique_is_unique, )) } } diff --git a/src/borrow_tracker/tree_borrows/mod.rs b/src/borrow_tracker/tree_borrows/mod.rs index ce7d7ab25d..1993d6bdce 100644 --- a/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/borrow_tracker/tree_borrows/mod.rs @@ -2,7 +2,6 @@ use rustc_abi::{BackendRepr, Size}; use rustc_middle::mir::{Mutability, RetagKind}; use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::{self, Ty}; -use rustc_span::def_id::DefId; use crate::borrow_tracker::{GlobalState, GlobalStateInner, ProtectorKind}; use crate::concurrency::data_race::NaReadType; @@ -115,9 +114,6 @@ impl<'tcx> Tree { /// Policy for a new borrow. #[derive(Debug, Clone, Copy)] struct NewPermission { - /// Optionally ignore the actual size to do a zero-size reborrow. - /// If this is set then `dereferenceable` is not enforced. - zero_size: bool, /// Which permission should the pointer start with. initial_state: Permission, /// Whether this pointer is part of the arguments of a function call. @@ -157,7 +153,7 @@ impl<'tcx> NewPermission { }; let protector = is_protected.then_some(ProtectorKind::StrongProtector); - Some(Self { zero_size: false, initial_state, protector, initial_read }) + Some(Self { initial_state, protector, initial_read }) } /// Compute permission for `Box`-like type (`Box` always, and also `Unique` if enabled). @@ -167,7 +163,6 @@ impl<'tcx> NewPermission { ty: Ty<'tcx>, kind: RetagKind, cx: &crate::MiriInterpCx<'tcx>, - zero_size: bool, ) -> Option { let pointee = ty.builtin_deref(true).unwrap(); pointee.is_unpin(*cx.tcx, cx.typing_env()).then_some(()).map(|()| { @@ -177,7 +172,6 @@ impl<'tcx> NewPermission { let protected = kind == RetagKind::FnEntry; let initial_state = Permission::new_reserved(ty_is_freeze, protected); Self { - zero_size, initial_state, protector: protected.then_some(ProtectorKind::WeakProtector), initial_read: true, @@ -341,15 +335,12 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Determine the size of the reborrow. // For most types this is the entire size of the place, however // - when `extern type` is involved we use the size of the known prefix, - // - if the pointer is not reborrowed (raw pointer) or if `zero_size` is set - // then we override the size to do a zero-length reborrow. - let reborrow_size = match new_perm { - NewPermission { zero_size: false, .. } => - this.size_and_align_of_mplace(place)? - .map(|(size, _)| size) - .unwrap_or(place.layout.size), - _ => Size::from_bytes(0), - }; + // - if the pointer is not reborrowed (raw pointer) then we override the size + // to do a zero-length reborrow. + let reborrow_size = this + .size_and_align_of_mplace(place)? + .map(|(size, _)| size) + .unwrap_or(place.layout.size); trace!("Creating new permission: {:?} with size {:?}", new_perm, reborrow_size); // This new tag is not guaranteed to actually be used. @@ -413,9 +404,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let options = this.machine.borrow_tracker.as_mut().unwrap().get_mut(); let retag_fields = options.retag_fields; - let unique_did = - options.unique_is_unique.then(|| this.tcx.lang_items().ptr_unique()).flatten(); - let mut visitor = RetagVisitor { ecx: this, kind, retag_fields, unique_did }; + let mut visitor = RetagVisitor { ecx: this, kind, retag_fields }; return visitor.visit_value(place); // The actual visitor. @@ -423,7 +412,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ecx: &'ecx mut MiriInterpCx<'tcx>, kind: RetagKind, retag_fields: RetagFields, - unique_did: Option, } impl<'ecx, 'tcx> RetagVisitor<'ecx, 'tcx> { #[inline(always)] // yes this helps in our benchmarks @@ -454,12 +442,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn visit_box(&mut self, box_ty: Ty<'tcx>, place: &PlaceTy<'tcx>) -> InterpResult<'tcx> { // Only boxes for the global allocator get any special treatment. if box_ty.is_box_global(*self.ecx.tcx) { - let new_perm = NewPermission::from_unique_ty( - place.layout.ty, - self.kind, - self.ecx, - /* zero_size */ false, - ); + let new_perm = + NewPermission::from_unique_ty(place.layout.ty, self.kind, self.ecx); self.retag_ptr_inplace(place, new_perm)?; } interp_ok(()) @@ -493,16 +477,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // even if field retagging is not enabled. *shrug*) self.walk_value(place)?; } - ty::Adt(adt, _) if self.unique_did == Some(adt.did()) => { - let place = inner_ptr_of_unique(self.ecx, place)?; - let new_perm = NewPermission::from_unique_ty( - place.layout.ty, - self.kind, - self.ecx, - /* zero_size */ true, - ); - self.retag_ptr_inplace(&place, new_perm)?; - } _ => { // Not a reference/pointer/box. Only recurse if configured appropriately. let recurse = match self.retag_fields { @@ -541,7 +515,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Retag it. With protection! That is the entire point. let new_perm = NewPermission { initial_state: Permission::new_reserved(ty_is_freeze, /* protected */ true), - zero_size: false, protector: Some(ProtectorKind::StrongProtector), initial_read: true, }; @@ -603,27 +576,3 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { tree_borrows.give_pointer_debug_name(tag, nth_parent, name) } } - -/// Takes a place for a `Unique` and turns it into a place with the inner raw pointer. -/// I.e. input is what you get from the visitor upon encountering an `adt` that is `Unique`, -/// and output can be used by `retag_ptr_inplace`. -fn inner_ptr_of_unique<'tcx>( - ecx: &MiriInterpCx<'tcx>, - place: &PlaceTy<'tcx>, -) -> InterpResult<'tcx, PlaceTy<'tcx>> { - // Follows the same layout as `interpret/visitor.rs:walk_value` for `Box` in - // `rustc_const_eval`, just with one fewer layer. - // Here we have a `Unique(NonNull(*mut), PhantomData)` - assert_eq!(place.layout.fields.count(), 2, "Unique must have exactly 2 fields"); - let (nonnull, phantom) = (ecx.project_field(place, 0)?, ecx.project_field(place, 1)?); - assert!( - phantom.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()), - "2nd field of `Unique` should be `PhantomData` but is `{:?}`", - phantom.layout.ty, - ); - // Now down to `NonNull(*mut)` - assert_eq!(nonnull.layout.fields.count(), 1, "NonNull must have exactly 1 field"); - let ptr = ecx.project_field(&nonnull, 0)?; - // Finally a plain `*mut` - interp_ok(ptr) -} diff --git a/src/eval.rs b/src/eval.rs index f41062dae4..bb5e5d7ee8 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -101,10 +101,6 @@ pub struct MiriConfig { pub validation: ValidationMode, /// Determines if Stacked Borrows or Tree Borrows is enabled. pub borrow_tracker: Option, - /// Whether `core::ptr::Unique` receives special treatment. - /// If `true` then `Unique` is reborrowed with its own new tag and permission, - /// otherwise `Unique` is just another raw pointer. - pub unique_is_unique: bool, /// Controls alignment checking. pub check_alignment: AlignmentCheck, /// Action for an op requiring communication with the host. @@ -177,7 +173,6 @@ impl Default for MiriConfig { env: vec![], validation: ValidationMode::Shallow, borrow_tracker: Some(BorrowTrackerMethod::StackedBorrows), - unique_is_unique: false, check_alignment: AlignmentCheck::Int, isolated_op: IsolatedOp::Reject(RejectOpWith::Abort), ignore_leaks: false, diff --git a/tests/fail/tree_borrows/children-can-alias.default.stderr b/tests/fail/tree_borrows/children-can-alias.default.stderr deleted file mode 100644 index b9651e21ec..0000000000 --- a/tests/fail/tree_borrows/children-can-alias.default.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: entering unreachable code - --> tests/fail/tree_borrows/children-can-alias.rs:LL:CC - | -LL | std::hint::unreachable_unchecked(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at tests/fail/tree_borrows/children-can-alias.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/tests/fail/tree_borrows/children-can-alias.rs b/tests/fail/tree_borrows/children-can-alias.rs deleted file mode 100644 index d3f272dfbf..0000000000 --- a/tests/fail/tree_borrows/children-can-alias.rs +++ /dev/null @@ -1,58 +0,0 @@ -//@revisions: default uniq -//@compile-flags: -Zmiri-tree-borrows -//@[uniq]compile-flags: -Zmiri-unique-is-unique - -//! This is NOT intended behavior. -//! We should eventually find a solution so that the version with `Unique` passes too, -//! otherwise `Unique` is more strict than `&mut`! - -#![feature(ptr_internals)] - -use core::ptr::{Unique, addr_of_mut}; - -fn main() { - let mut data = 0u8; - let raw = addr_of_mut!(data); - unsafe { - raw_children_of_refmut_can_alias(&mut *raw); - raw_children_of_unique_can_alias(Unique::new_unchecked(raw)); - - // Ultimately the intended behavior is that both above tests would - // succeed. - std::hint::unreachable_unchecked(); - //~[default]^ ERROR: entering unreachable code - } -} - -unsafe fn raw_children_of_refmut_can_alias(x: &mut u8) { - let child1 = addr_of_mut!(*x); - let child2 = addr_of_mut!(*x); - // We create two raw aliases of `x`: they have the exact same - // tag and can be used interchangeably. - child1.write(1); - child2.write(2); - child1.write(1); - child2.write(2); -} - -unsafe fn raw_children_of_unique_can_alias(x: Unique) { - let child1 = x.as_ptr(); - let child2 = x.as_ptr(); - // Under `-Zmiri-unique-is-unique`, `Unique` accidentally offers more guarantees - // than `&mut`. Not because it responds differently to accesses but because - // there is no easy way to obtain a copy with the same tag. - // - // The closest (non-hack) attempt is two calls to `as_ptr`. - // - Without `-Zmiri-unique-is-unique`, independent `as_ptr` calls return pointers - // with the same tag that can thus be used interchangeably. - // - With the current implementation of `-Zmiri-unique-is-unique`, they return cousin - // tags with permissions that do not tolerate aliasing. - // Eventually we should make such aliasing allowed in some situations - // (e.g. when there is no protector), which will probably involve - // introducing a new kind of permission. - child1.write(1); - child2.write(2); - //~[uniq]^ ERROR: /write access through .* is forbidden/ - child1.write(1); - child2.write(2); -} diff --git a/tests/fail/tree_borrows/children-can-alias.uniq.stderr b/tests/fail/tree_borrows/children-can-alias.uniq.stderr deleted file mode 100644 index 83c506abb2..0000000000 --- a/tests/fail/tree_borrows/children-can-alias.uniq.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden - --> tests/fail/tree_borrows/children-can-alias.rs:LL:CC - | -LL | child2.write(2); - | ^^^^^^^^^^^^^^^ write access through at ALLOC[0x0] is forbidden - | - = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = help: the accessed tag has state Disabled which forbids this child write access -help: the accessed tag was created here, in the initial state Reserved - --> tests/fail/tree_borrows/children-can-alias.rs:LL:CC - | -LL | let child2 = x.as_ptr(); - | ^^^^^^^^^^ -help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x1] - --> tests/fail/tree_borrows/children-can-alias.rs:LL:CC - | -LL | child1.write(1); - | ^^^^^^^^^^^^^^^ - = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `raw_children_of_unique_can_alias` at tests/fail/tree_borrows/children-can-alias.rs:LL:CC -note: inside `main` - --> tests/fail/tree_borrows/children-can-alias.rs:LL:CC - | -LL | raw_children_of_unique_can_alias(Unique::new_unchecked(raw)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/tests/fail/tree_borrows/unique.rs b/tests/fail/tree_borrows/unique.rs deleted file mode 100644 index 0844dd21a5..0000000000 --- a/tests/fail/tree_borrows/unique.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@revisions: default uniq -//@compile-flags: -Zmiri-tree-borrows -//@[uniq]compile-flags: -Zmiri-unique-is-unique - -// A pattern that detects if `Unique` is treated as exclusive or not: -// activate the pointer behind a `Unique` then do a read that is parent -// iff `Unique` was specially reborrowed. - -#![feature(ptr_internals)] -use core::ptr::Unique; - -fn main() { - let mut data = 0u8; - let refmut = &mut data; - let rawptr = refmut as *mut u8; - - unsafe { - let uniq = Unique::new_unchecked(rawptr); - *uniq.as_ptr() = 1; // activation - let _maybe_parent = *rawptr; // maybe becomes Frozen - *uniq.as_ptr() = 2; - //~[uniq]^ ERROR: /write access through .* is forbidden/ - let _definitely_parent = data; // definitely Frozen by now - *uniq.as_ptr() = 3; - //~[default]^ ERROR: /write access through .* is forbidden/ - } -} diff --git a/tests/fail/tree_borrows/unique.uniq.stderr b/tests/fail/tree_borrows/unique.uniq.stderr deleted file mode 100644 index 4ecff3ea0e..0000000000 --- a/tests/fail/tree_borrows/unique.uniq.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden - --> tests/fail/tree_borrows/unique.rs:LL:CC - | -LL | *uniq.as_ptr() = 2; - | ^^^^^^^^^^^^^^^^^^ write access through at ALLOC[0x0] is forbidden - | - = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental - = help: the accessed tag is a child of the conflicting tag - = help: the conflicting tag has state Frozen which forbids this child write access -help: the accessed tag was created here - --> tests/fail/tree_borrows/unique.rs:LL:CC - | -LL | *uniq.as_ptr() = 2; - | ^^^^^^^^^^^^^ -help: the conflicting tag was created here, in the initial state Reserved - --> tests/fail/tree_borrows/unique.rs:LL:CC - | -LL | let uniq = Unique::new_unchecked(rawptr); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: the conflicting tag later transitioned to Active due to a child write access at offsets [0x0..0x1] - --> tests/fail/tree_borrows/unique.rs:LL:CC - | -LL | *uniq.as_ptr() = 1; // activation - | ^^^^^^^^^^^^^^^^^^ - = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -help: the conflicting tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x1] - --> tests/fail/tree_borrows/unique.rs:LL:CC - | -LL | let _maybe_parent = *rawptr; // maybe becomes Frozen - | ^^^^^^^ - = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/tree_borrows/unique.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/tests/pass/tree_borrows/interior_mutability.rs b/tests/pass/tree_borrows/interior_mutability.rs index c155fcb18c..50d745fa36 100644 --- a/tests/pass/tree_borrows/interior_mutability.rs +++ b/tests/pass/tree_borrows/interior_mutability.rs @@ -1,6 +1,4 @@ -//@revisions: default uniq //@compile-flags: -Zmiri-tree-borrows -//@[uniq]compile-flags: -Zmiri-unique-is-unique #![allow(dangerous_implicit_autorefs)] use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; use std::mem::{self, MaybeUninit}; diff --git a/tests/pass/tree_borrows/tree-borrows.rs b/tests/pass/tree_borrows/tree-borrows.rs index b9d5ca06ed..eddcb7b121 100644 --- a/tests/pass/tree_borrows/tree-borrows.rs +++ b/tests/pass/tree_borrows/tree-borrows.rs @@ -1,6 +1,4 @@ -//@revisions: default uniq //@compile-flags: -Zmiri-tree-borrows -//@[uniq]compile-flags: -Zmiri-unique-is-unique #![feature(allocator_api)] use std::{mem, ptr}; diff --git a/tests/pass/tree_borrows/unique.default.stderr b/tests/pass/tree_borrows/unique.default.stderr deleted file mode 100644 index 6098c855bd..0000000000 --- a/tests/pass/tree_borrows/unique.default.stderr +++ /dev/null @@ -1,21 +0,0 @@ -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 1 -| Act | └─┬── -| Res | └─┬── -| Res | └──── -────────────────────────────────────────────────── -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 1 -| Act | └─┬── -| Act | └─┬── -| Act | └──── -────────────────────────────────────────────────── -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 1 -| Act | └─┬── -| Act | └─┬── -| Act | └──── -────────────────────────────────────────────────── diff --git a/tests/pass/tree_borrows/unique.rs b/tests/pass/tree_borrows/unique.rs deleted file mode 100644 index f1ca1b51aa..0000000000 --- a/tests/pass/tree_borrows/unique.rs +++ /dev/null @@ -1,67 +0,0 @@ -//@revisions: default uniq -// We disable the GC for this test because it would change what is printed. -//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0 -//@[uniq]compile-flags: -Zmiri-unique-is-unique - -#![feature(ptr_internals)] - -#[path = "../../utils/mod.rs"] -#[macro_use] -mod utils; - -use core::ptr::Unique; - -// Check general handling of Unique - -fn main() { - unsafe { - let base = &mut 5u8; - let alloc_id = alloc_id!(base); - name!(base); - - let raw = &mut *base as *mut u8; - name!(raw); - - // We create a `Unique` and expect it to have a fresh tag - // and uninitialized permissions. - let uniq = Unique::new_unchecked(raw); - - // With `-Zmiri-unique-is-unique`, `Unique::as_ptr` (which is called by - // `Vec::as_ptr`) generates pointers with a fresh tag, so to name the actual - // `base` pointer we care about we have to walk up the tree a bit. - // - // We care about naming this specific parent tag because it is the one - // that stays `Active` during the entire execution, unlike the leaves - // that will be invalidated the next time `as_ptr` is called. - // - // (We name it twice so that we have an indicator in the output of - // whether we got the distance correct: - // If the output shows - // - // |- - // '- - // - // then `nth_parent` is not big enough. - // The correct value for `nth_parent` should be the minimum - // integer for which the output shows - // - // '- - // ) - // - // Ultimately we want pointers obtained through independent - // calls of `as_ptr` to be able to alias, which will probably involve - // a new permission that allows aliasing when there is no protector. - let nth_parent = if cfg!(uniq) { 2 } else { 0 }; - name!(uniq.as_ptr()=>nth_parent, "uniq"); - name!(uniq.as_ptr()=>nth_parent, "uniq"); - print_state!(alloc_id); - - // We can activate the Unique and use it mutably. - *uniq.as_ptr() = 42; - print_state!(alloc_id); - - // Write through the raw parent disables the Unique - *raw = 42; - print_state!(alloc_id); - } -} diff --git a/tests/pass/tree_borrows/unique.uniq.stderr b/tests/pass/tree_borrows/unique.uniq.stderr deleted file mode 100644 index 960c7e216e..0000000000 --- a/tests/pass/tree_borrows/unique.uniq.stderr +++ /dev/null @@ -1,24 +0,0 @@ -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 1 -| Act | └─┬── -| Res | └─┬── -| Res | └─┬── -|-----| └──── -────────────────────────────────────────────────── -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 1 -| Act | └─┬── -| Act | └─┬── -| Act | └─┬── -| Act | └──── -────────────────────────────────────────────────── -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 1 -| Act | └─┬── -| Act | └─┬── -| Act | └─┬── -| Dis | └──── -────────────────────────────────────────────────── diff --git a/tests/pass/tree_borrows/vec_unique.rs b/tests/pass/tree_borrows/vec_unique.rs deleted file mode 100644 index af4c3b0693..0000000000 --- a/tests/pass/tree_borrows/vec_unique.rs +++ /dev/null @@ -1,69 +0,0 @@ -//@revisions: default uniq -// We disable the GC for this test because it would change what is printed. -//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0 -//@[uniq]compile-flags: -Zmiri-unique-is-unique - -#![feature(vec_into_raw_parts)] - -#[path = "../../utils/mod.rs"] -#[macro_use] -mod utils; - -// Check general handling of `Unique`: -// there is no *explicit* `Unique` being used here, but there is one -// hidden a few layers inside `Vec` that should be reflected in the tree structure. - -fn main() { - unsafe { - let base = vec![0u8, 1]; - let alloc_id = alloc_id!(base.as_ptr()); - - // With `-Zmiri-unique-is-unique`, `Unique::as_ptr` (which is called by - // `Vec::as_ptr`) generates pointers with a fresh tag, so to name the actual - // `base` pointer we care about we have to walk up the tree a bit. - // - // We care about naming this specific parent tag because it is the one - // that stays `Active` during the entire execution, unlike the leaves - // that will be invalidated the next time `as_ptr` is called. - // - // (We name it twice so that we have an indicator in the output of - // whether we got the distance correct: - // If the output shows - // - // ├─ - // └─ - // - // then `nth_parent` is not big enough. - // The correct value for `nth_parent` should be the minimum - // integer for which the output shows - // - // └─ - // ) - // - // Ultimately we want pointers obtained through independent - // calls of `as_ptr` to be able to alias, which will probably involve - // a new permission that allows aliasing when there is no protector. - let nth_parent = if cfg!(uniq) { 9 } else { 0 }; - name!(base.as_ptr()=>nth_parent); - name!(base.as_ptr()=>nth_parent); - - // Destruct the `Vec` - let (ptr, len, cap) = base.into_raw_parts(); - - // Expect this to be again the same pointer as the one obtained from `as_ptr`. - // Under `-Zmiri-unique-is-unique`, this will be a strict child. - name!(ptr, "raw_parts.0"); - - // This is where the presence of `Unique` has implications, - // because there will be a reborrow here iff the exclusivity of `Unique` - // is enforced. - let reconstructed = Vec::from_raw_parts(ptr, len, cap); - - // The `as_ptr` here (twice for the same reason as above) return either - // the same pointer once more (default) or a strict child (uniq). - name!(reconstructed.as_ptr()=>nth_parent); - name!(reconstructed.as_ptr()=>nth_parent); - - print_state!(alloc_id, false); - } -} diff --git a/tests/pass/tree_borrows/vec_unique.uniq.stderr b/tests/pass/tree_borrows/vec_unique.uniq.stderr deleted file mode 100644 index 7942e9884f..0000000000 --- a/tests/pass/tree_borrows/vec_unique.uniq.stderr +++ /dev/null @@ -1,8 +0,0 @@ -────────────────────────────────────────────────── -Warning: this tree is indicative only. Some tags may have been hidden. -0.. 2 -| Act | └─┬── -|-----| └─┬── -|-----| └─┬── -|-----| └──── -────────────────────────────────────────────────── diff --git a/tests/pass/vec.rs b/tests/pass/vec.rs index 4ab2bcb7f2..3e526813bb 100644 --- a/tests/pass/vec.rs +++ b/tests/pass/vec.rs @@ -1,7 +1,6 @@ -//@revisions: stack tree tree_uniq +//@revisions: stack tree //@compile-flags: -Zmiri-strict-provenance //@[tree]compile-flags: -Zmiri-tree-borrows -//@[tree_uniq]compile-flags: -Zmiri-tree-borrows -Zmiri-unique-is-unique #![feature(iter_advance_by, iter_next_chunk)] // Gather all references from a mutable iterator and make sure Miri notices if diff --git a/tests/pass/vecdeque.rs b/tests/pass/vecdeque.rs index 9153c428e1..bdf57f281a 100644 --- a/tests/pass/vecdeque.rs +++ b/tests/pass/vecdeque.rs @@ -1,8 +1,6 @@ -//@revisions: stack tree tree_uniq +//@revisions: stack tree //@compile-flags: -Zmiri-strict-provenance //@[tree]compile-flags: -Zmiri-tree-borrows -//@[tree_uniq]compile-flags: -Zmiri-tree-borrows -Zmiri-unique-is-unique - use std::collections::VecDeque; fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator) {