@@ -296,12 +296,6 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
296296
297297 let span = this. machine . current_span ( ) ;
298298
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-
305299 // When adding a new node, the SIFA of its parents needs to be updated, potentially across
306300 // the entire memory range. For the parts that are being accessed below, the access itself
307301 // 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> {
329323 . get_tree_borrows_params ( )
330324 . precise_interior_mut ;
331325
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 {
336329 ( new_perm. freeze_perm , new_perm. freeze_access )
337330 } else {
338- // Just pretend the entire thing is an `UnsafeCell`.
339331 ( new_perm. nonfreeze_perm , new_perm. nonfreeze_access )
340332 } ;
341333 let sifa = perm. strongest_idempotent_foreign_access ( protected) ;
342- let new_loc = if access {
334+ if access {
343335 LocationState :: new_accessed ( perm, sifa)
344336 } else {
345337 LocationState :: new_non_accessed ( perm, sifa)
346- } ;
347-
348- for ( _loc_range, loc) in perms_map. iter_mut_all ( ) {
349- * loc = new_loc;
350338 }
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)
351345 } 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+ ) ;
352354 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) ;
372356 for ( _loc_range, loc) in perms_map. iter_mut ( range. start , range. size ) {
373- * loc = new_loc ;
357+ * loc = state ;
374358 }
375-
376359 interp_ok ( ( ) )
377360 } ) ?;
361+ perms_map
378362 } ;
379363
380364 let alloc_extra = this. get_alloc_extra ( alloc_id) ?;
381365 let mut tree_borrows = alloc_extra. borrow_tracker_tb ( ) . borrow_mut ( ) ;
382366
383- for ( perm_range, perm) in perms_map. iter_mut_all ( ) {
367+ for ( perm_range, perm) in perms_map. iter_all ( ) {
384368 if perm. is_accessed ( ) {
385369 // Some reborrows incur a read access to the parent.
386370 // Adjust range to be relative to allocation start (rather than to `place`).
0 commit comments