@@ -65,7 +65,7 @@ pub struct FrameExtra {
6565 /// incremental updates of the global list of protected tags stored in the
6666 /// `stacked_borrows::GlobalState` upon function return, and if we attempt to pop a protected
6767 /// tag, to identify which call is responsible for protecting the tag.
68- /// See `Stack::item_popped ` for more explanation.
68+ /// See `Stack::item_invalidated ` for more explanation.
6969 ///
7070 /// This will contain one tag per reference passed to the function, so
7171 /// a size of 2 is enough for the vast majority of functions.
@@ -126,7 +126,7 @@ pub struct GlobalStateInner {
126126 /// An item is protected if its tag is in this set, *and* it has the "protected" bit set.
127127 /// We add tags to this when they are created with a protector in `reborrow`, and
128128 /// we remove tags from this when the call which is protecting them returns, in
129- /// `GlobalStateInner::end_call`. See `Stack::item_popped ` for more details.
129+ /// `GlobalStateInner::end_call`. See `Stack::item_invalidated ` for more details.
130130 protected_tags : FxHashMap < SbTag , ProtectorKind > ,
131131 /// The pointer ids to trace
132132 tracked_pointer_tags : FxHashSet < SbTag > ,
@@ -292,6 +292,13 @@ impl Permission {
292292 }
293293}
294294
295+ /// Determines whether an item was invalidated by a conflicting access, or by deallocation.
296+ #[ derive( Copy , Clone , Debug ) ]
297+ enum ItemInvalidationCause {
298+ Conflict ,
299+ Dealloc ,
300+ }
301+
295302/// Core per-location operations: access, dealloc, reborrow.
296303impl < ' tcx > Stack {
297304 /// Find the first write-incompatible item above the given one --
@@ -330,11 +337,11 @@ impl<'tcx> Stack {
330337 /// Within `provoking_access, the `AllocRange` refers the entire operation, and
331338 /// the `Size` refers to the specific location in the `AllocRange` that we are
332339 /// currently checking.
333- fn item_popped (
340+ fn item_invalidated (
334341 item : & Item ,
335342 global : & GlobalStateInner ,
336343 dcx : & mut DiagnosticCx < ' _ , ' _ , ' _ , ' _ , ' tcx > ,
337- deallocation : bool ,
344+ cause : ItemInvalidationCause ,
338345 ) -> InterpResult < ' tcx > {
339346 if !global. tracked_pointer_tags . is_empty ( ) {
340347 dcx. check_tracked_tag_popped ( item, global) ;
@@ -358,7 +365,10 @@ impl<'tcx> Stack {
358365 // which ends up about linear in the number of protected tags in the program into a
359366 // constant time check (and a slow linear, because the tags in the frames aren't contiguous).
360367 if let Some ( & protector_kind) = global. protected_tags . get ( & item. tag ( ) ) {
361- let allowed = deallocation && matches ! ( protector_kind, ProtectorKind :: WeakProtector ) ;
368+ // The only way this is okay is if the protector is weak and we are deallocating with
369+ // the right pointer.
370+ let allowed = matches ! ( cause, ItemInvalidationCause :: Dealloc )
371+ && matches ! ( protector_kind, ProtectorKind :: WeakProtector ) ;
362372 if !allowed {
363373 return Err ( dcx. protector_error ( item, protector_kind) . into ( ) ) ;
364374 }
@@ -401,7 +411,7 @@ impl<'tcx> Stack {
401411 0
402412 } ;
403413 self . pop_items_after ( first_incompatible_idx, |item| {
404- Stack :: item_popped ( & item, global, dcx, /* deallocation */ false ) ?;
414+ Stack :: item_invalidated ( & item, global, dcx, ItemInvalidationCause :: Conflict ) ?;
405415 dcx. log_invalidation ( item. tag ( ) ) ;
406416 Ok ( ( ) )
407417 } ) ?;
@@ -422,7 +432,7 @@ impl<'tcx> Stack {
422432 0
423433 } ;
424434 self . disable_uniques_starting_at ( first_incompatible_idx, |item| {
425- Stack :: item_popped ( & item, global, dcx, /* deallocation */ false ) ?;
435+ Stack :: item_invalidated ( & item, global, dcx, ItemInvalidationCause :: Conflict ) ?;
426436 dcx. log_invalidation ( item. tag ( ) ) ;
427437 Ok ( ( ) )
428438 } ) ?;
@@ -472,7 +482,7 @@ impl<'tcx> Stack {
472482 // Step 2: Pretend we remove the remaining items, checking if any are strongly protected.
473483 for idx in ( 0 ..self . len ( ) ) . rev ( ) {
474484 let item = self . get ( idx) . unwrap ( ) ;
475- Stack :: item_popped ( & item, global, dcx, /* deallocation */ true ) ?;
485+ Stack :: item_invalidated ( & item, global, dcx, ItemInvalidationCause :: Dealloc ) ?;
476486 }
477487
478488 Ok ( ( ) )
@@ -847,7 +857,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
847857 ) ;
848858
849859 if let Some ( protect) = protect {
850- // See comment in `Stack::item_popped ` for why we store the tag twice.
860+ // See comment in `Stack::item_invalidated ` for why we store the tag twice.
851861 this. frame_mut ( ) . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . protected_tags . push ( new_tag) ;
852862 this. machine
853863 . stacked_borrows
0 commit comments