@@ -572,6 +572,18 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
572572 new_tag : Tag ,
573573 protect : bool ,
574574 ) -> InterpResult < ' tcx > {
575+ // Nothing to do for ZSTs.
576+ if size == Size :: ZERO {
577+ trace ! (
578+ "reborrow of size 0: {} reference {:?} derived from {:?} (pointee {})" ,
579+ kind,
580+ new_tag,
581+ place. ptr,
582+ place. layout. ty,
583+ ) ;
584+ return Ok ( ( ) ) ;
585+ }
586+
575587 let this = self . eval_context_mut ( ) ;
576588 let protector = if protect { Some ( this. frame ( ) . extra . call_id ) } else { None } ;
577589 let ptr = place. ptr . assert_ptr ( ) ;
@@ -617,6 +629,8 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
617629 }
618630 } ;
619631 // Here we can avoid `borrow()` calls because we have mutable references.
632+ // Note that this asserts that the allocation is mutable -- but since we are creating a
633+ // mutable pointer, that seems reasonable.
620634 let ( alloc_extra, memory_extra) = this. memory . get_alloc_extra_mut ( ptr. alloc_id ) ?;
621635 let stacked_borrows =
622636 alloc_extra. stacked_borrows . as_mut ( ) . expect ( "we should have Stacked Borrows data" ) ;
@@ -649,12 +663,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
649663 // We can see dangling ptrs in here e.g. after a Box's `Unique` was
650664 // updated using "self.0 = ..." (can happen in Box::from_raw) so we cannot ICE; see miri#1050.
651665 let place = this. mplace_access_checked ( place, Some ( Align :: from_bytes ( 1 ) . unwrap ( ) ) ) ?;
652- // Nothing to do for ZSTs. We use `is_bits` here because we *do* need to retag even ZSTs
653- // when there actually is a tag (to avoid inheriting a tag that would let us access more
654- // than 0 bytes).
655- if size == Size :: ZERO && place. ptr . is_bits ( ) {
656- return Ok ( * val) ;
657- }
658666
659667 // Compute new borrow.
660668 let new_tag = {
0 commit comments