]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
for now, do not do fake reads on non-Unpin mutable references
[rust.git] / src / tools / miri / src / borrow_tracker / stacked_borrows / mod.rs
index ec3be398a2c29d896ac1a92ac49ee236c025fd2c..bcac873251f587509c766cd4197cb929feb950f2 100644 (file)
@@ -25,7 +25,7 @@
 pub use stack::Stack;
 pub mod diagnostics;
 
-pub type AllocExtra = Stacks;
+pub type AllocState = Stacks;
 
 /// Extra per-allocation state.
 #[derive(Clone, Debug)]
@@ -45,7 +45,9 @@ pub struct Stacks {
 /// new pointer.
 #[derive(Copy, Clone, Hash, PartialEq, Eq)]
 enum RefKind {
-    /// `&mut` and `Box`.
+    /// `Box`.
+    Box,
+    /// `&mut`.
     Unique { two_phase: bool },
     /// `&` with or without interior mutability.
     Shared,
@@ -56,6 +58,7 @@ enum RefKind {
 impl fmt::Display for RefKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
+            RefKind::Box => write!(f, "Box"),
             RefKind::Unique { two_phase: false } => write!(f, "unique reference"),
             RefKind::Unique { two_phase: true } => write!(f, "unique reference (two-phase)"),
             RefKind::Shared => write!(f, "shared reference"),
@@ -500,10 +503,6 @@ pub fn before_memory_deallocation<'tcx>(
         })?;
         Ok(())
     }
-
-    fn expose_tag(&mut self, tag: BorTag) {
-        self.exposed_tags.insert(tag);
-    }
 }
 
 /// Retagging/reborrowing.  There is some policy in here, such as which permissions
@@ -567,10 +566,7 @@ fn sb_reborrow(
                     // uncovers a non-supported `extern static`.
                     let extra = this.get_alloc_extra(alloc_id)?;
                     let mut stacked_borrows = extra
-                        .borrow_tracker
-                        .as_ref()
-                        .expect("We should have borrow tracking data")
-                        .assert_sb()
+                        .borrow_tracker_sb()
                         .borrow_mut();
                     // Note that we create a *second* `DiagnosticCxBuilder` below for the actual retag.
                     // FIXME: can this be done cleaner?
@@ -661,15 +657,17 @@ fn sb_reborrow(
         let (perm, access) = match kind {
             RefKind::Unique { two_phase } => {
                 // Permission is Unique only if the type is `Unpin` and this is not twophase
-                let perm = if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
-                    Permission::Unique
+                if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
+                    (Permission::Unique, Some(AccessKind::Write))
                 } else {
-                    Permission::SharedReadWrite
-                };
-                // We do an access for all full borrows, even if `!Unpin`.
-                let access = if !two_phase { Some(AccessKind::Write) } else { None };
-                (perm, access)
+                    // FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we
+                    // should do fake accesses here. But then we run into
+                    // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now
+                    // we don't do that.
+                    (Permission::SharedReadWrite, None)
+                }
             }
+            RefKind::Box => (Permission::Unique, Some(AccessKind::Write)),
             RefKind::Raw { mutable: true } => {
                 // Creating a raw ptr does not count as an access
                 (Permission::SharedReadWrite, None)
@@ -681,12 +679,7 @@ fn sb_reborrow(
                 // We have to use shared references to alloc/memory_extra here since
                 // `visit_freeze_sensitive` needs to access the global state.
                 let alloc_extra = this.get_alloc_extra(alloc_id)?;
-                let mut stacked_borrows = alloc_extra
-                    .borrow_tracker
-                    .as_ref()
-                    .expect("We should have borrow tracking data")
-                    .assert_sb()
-                    .borrow_mut();
+                let mut stacked_borrows = alloc_extra.borrow_tracker_sb().borrow_mut();
                 this.visit_freeze_sensitive(place, size, |mut range, frozen| {
                     // Adjust range.
                     range.start += base_offset;
@@ -736,12 +729,7 @@ fn sb_reborrow(
         // Note that this asserts that the allocation is mutable -- but since we are creating a
         // mutable pointer, that seems reasonable.
         let (alloc_extra, machine) = this.get_alloc_extra_mut(alloc_id)?;
-        let stacked_borrows = alloc_extra
-            .borrow_tracker
-            .as_mut()
-            .expect("We should have borrow tracking data")
-            .assert_sb_mut()
-            .get_mut();
+        let stacked_borrows = alloc_extra.borrow_tracker_sb_mut().get_mut();
         let item = Item::new(new_tag, perm, protect.is_some());
         let range = alloc_range(base_offset, size);
         let global = machine.borrow_tracker.as_ref().unwrap().borrow();
@@ -870,7 +858,7 @@ fn visit_box(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>
                 // Boxes get a weak protectors, since they may be deallocated.
                 self.retag_place(
                     place,
-                    RefKind::Unique { two_phase: false },
+                    RefKind::Box,
                     self.retag_cause,
                     /*protector*/
                     (self.kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector),
@@ -993,13 +981,7 @@ fn sb_expose_tag(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx
                 // uncovers a non-supported `extern static`.
                 let alloc_extra = this.get_alloc_extra(alloc_id)?;
                 trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}");
-                alloc_extra
-                    .borrow_tracker
-                    .as_ref()
-                    .expect("We should have borrow tracking data")
-                    .assert_sb()
-                    .borrow_mut()
-                    .expose_tag(tag);
+                alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag);
             }
             AllocKind::Function | AllocKind::VTable | AllocKind::Dead => {
                 // No stacked borrows on these allocations.
@@ -1011,12 +993,7 @@ fn sb_expose_tag(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx
     fn print_stacks(&mut self, alloc_id: AllocId) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         let alloc_extra = this.get_alloc_extra(alloc_id)?;
-        let stacks = alloc_extra
-            .borrow_tracker
-            .as_ref()
-            .expect("We should have borrow tracking data")
-            .assert_sb()
-            .borrow();
+        let stacks = alloc_extra.borrow_tracker_sb().borrow();
         for (range, stack) in stacks.stacks.iter_all() {
             print!("{range:?}: [");
             if let Some(bottom) = stack.unknown_bottom() {