@@ -296,12 +296,6 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
296
296
297
297
let span = this. machine . current_span ( ) ;
298
298
299
- // Store initial permissions for the "inside" part.
300
- let mut perms_map: DedupRangeMap < LocationState > = DedupRangeMap :: new (
301
- ptr_size,
302
- LocationState :: new_accessed ( Permission :: new_disabled ( ) , IdempotentForeignAccess :: None ) , // this will be overwritten
303
- ) ;
304
-
305
299
// When adding a new node, the SIFA of its parents needs to be updated, potentially across
306
300
// the entire memory range. For the parts that are being accessed below, the access itself
307
301
// trivially takes care of that. However, we have to do some more work to also deal with
@@ -329,58 +323,48 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
329
323
. get_tree_borrows_params ( )
330
324
. precise_interior_mut ;
331
325
332
- // Set "inside" permissions.
333
- if !precise_interior_mut {
334
- let ty_is_freeze = place. layout . ty . is_freeze ( * this. tcx , this. typing_env ( ) ) ;
335
- let ( perm, access) = if ty_is_freeze {
326
+ // Compute initial "inside" permissions.
327
+ let loc_state = |frozen : bool | -> LocationState {
328
+ let ( perm, access) = if frozen {
336
329
( new_perm. freeze_perm , new_perm. freeze_access )
337
330
} else {
338
- // Just pretend the entire thing is an `UnsafeCell`.
339
331
( new_perm. nonfreeze_perm , new_perm. nonfreeze_access )
340
332
} ;
341
333
let sifa = perm. strongest_idempotent_foreign_access ( protected) ;
342
- let new_loc = if access {
334
+ if access {
343
335
LocationState :: new_accessed ( perm, sifa)
344
336
} else {
345
337
LocationState :: new_non_accessed ( perm, sifa)
346
- } ;
347
-
348
- for ( _loc_range, loc) in perms_map. iter_mut_all ( ) {
349
- * loc = new_loc;
350
338
}
339
+ } ;
340
+ let perms_map = if !precise_interior_mut {
341
+ // For `!Freeze` types, just pretend the entire thing is an `UnsafeCell`.
342
+ let ty_is_freeze = place. layout . ty . is_freeze ( * this. tcx , this. typing_env ( ) ) ;
343
+ let state = loc_state ( ty_is_freeze) ;
344
+ DedupRangeMap :: new ( ptr_size, state)
351
345
} else {
346
+ // The initial state will be overwritten by the visitor below.
347
+ let mut perms_map: DedupRangeMap < LocationState > = DedupRangeMap :: new (
348
+ ptr_size,
349
+ LocationState :: new_accessed (
350
+ Permission :: new_disabled ( ) ,
351
+ IdempotentForeignAccess :: None ,
352
+ ) ,
353
+ ) ;
352
354
this. visit_freeze_sensitive ( place, ptr_size, |range, frozen| {
353
- // We are only ever `Frozen` inside the frozen bits.
354
- let ( perm, access) = if frozen {
355
- ( new_perm. freeze_perm , new_perm. freeze_access )
356
- } else {
357
- ( new_perm. nonfreeze_perm , new_perm. nonfreeze_access )
358
- } ;
359
- let sifa = perm. strongest_idempotent_foreign_access ( protected) ;
360
- // NOTE: Currently, `access` is false if and only if `perm` is Cell, so this `if`
361
- // doesn't not change whether any code is UB or not. We could just always use
362
- // `new_accessed` and everything would stay the same. But that seems conceptually
363
- // odd, so we keep the initial "accessed" bit of the `LocationState` in sync with whether
364
- // a read access is performed below.
365
- let new_loc = if access {
366
- LocationState :: new_accessed ( perm, sifa)
367
- } else {
368
- LocationState :: new_non_accessed ( perm, sifa)
369
- } ;
370
-
371
- // Store initial permissions.
355
+ let state = loc_state ( frozen) ;
372
356
for ( _loc_range, loc) in perms_map. iter_mut ( range. start , range. size ) {
373
- * loc = new_loc ;
357
+ * loc = state ;
374
358
}
375
-
376
359
interp_ok ( ( ) )
377
360
} ) ?;
361
+ perms_map
378
362
} ;
379
363
380
364
let alloc_extra = this. get_alloc_extra ( alloc_id) ?;
381
365
let mut tree_borrows = alloc_extra. borrow_tracker_tb ( ) . borrow_mut ( ) ;
382
366
383
- for ( perm_range, perm) in perms_map. iter_mut_all ( ) {
367
+ for ( perm_range, perm) in perms_map. iter_all ( ) {
384
368
if perm. is_accessed ( ) {
385
369
// Some reborrows incur a read access to the parent.
386
370
// Adjust range to be relative to allocation start (rather than to `place`).
0 commit comments