Skip to content

Commit e27d57b

Browse files
committed
tweaks
1 parent c2a6c1e commit e27d57b

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/stacked_borrows/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ impl<'span, 'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'span, 'history, 'ecx, 'mir
288288
}
289289
Operation::Access(AccessOp { kind, range, .. }) =>
290290
(*range, InvalidationCause::Access(*kind)),
291-
_ => {
291+
Operation::Dealloc(_) => {
292292
// This can be reached, but never be relevant later since the entire allocation is
293293
// gone now.
294294
return;

src/stacked_borrows/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
296303
impl<'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

Comments
 (0)