@@ -673,19 +673,27 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
673673 fn_entry : bool ,
674674 place : PlaceTy < ' tcx , Borrow >
675675 ) -> EvalResult < ' tcx > {
676+ // Determine mutability and whether to add a barrier.
677+ // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
678+ // making it useless.
679+ fn qualify ( ty : ty:: Ty < ' _ > , fn_entry : bool ) -> Option < ( Mutability , bool ) > {
680+ match ty. sty {
681+ // References are simple
682+ ty:: Ref ( _, _, mutbl) => Some ( ( mutbl, fn_entry) ) ,
683+ // Boxes do not get a barrier: Barriers reflect that references outlive the call
684+ // they were passed in to; that's just not the case for boxes.
685+ ty:: Adt ( ..) if ty. is_box ( ) => Some ( ( MutMutable , false ) ) ,
686+ _ => None ,
687+ }
688+ }
689+
676690 // We need a visitor to visit all references. However, that requires
677691 // a `MemPlace`, so we have a fast path for reference types that
678692 // avoids allocating.
679- // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
680- // making it useless.
681- if let Some ( mutbl) = match place. layout . ty . sty {
682- ty:: Ref ( _, _, mutbl) => Some ( mutbl) ,
683- ty:: Adt ( ..) if place. layout . ty . is_box ( ) => Some ( MutMutable ) ,
684- _ => None , // handled with the general case below
685- } {
693+ if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , fn_entry) {
686694 // fast path
687695 let val = self . read_immediate ( self . place_to_op ( place) ?) ?;
688- let val = self . retag_reference ( val, mutbl, fn_entry ) ?;
696+ let val = self . retag_reference ( val, mutbl, barrier ) ?;
689697 self . write_immediate ( val, place) ?;
690698 return Ok ( ( ) ) ;
691699 }
@@ -716,14 +724,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
716724 {
717725 // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
718726 // making it useless.
719- let mutbl = match place. layout . ty . sty {
720- ty:: Ref ( _, _, mutbl) => mutbl,
721- ty:: Adt ( ..) if place. layout . ty . is_box ( ) => MutMutable ,
722- _ => return Ok ( ( ) ) , // nothing to do
723- } ;
724- let val = self . ecx . read_immediate ( place. into ( ) ) ?;
725- let val = self . ecx . retag_reference ( val, mutbl, self . fn_entry ) ?;
726- self . ecx . write_immediate ( val, place. into ( ) ) ?;
727+ if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , self . fn_entry ) {
728+ let val = self . ecx . read_immediate ( place. into ( ) ) ?;
729+ let val = self . ecx . retag_reference ( val, mutbl, barrier) ?;
730+ self . ecx . write_immediate ( val, place. into ( ) ) ?;
731+ }
727732 Ok ( ( ) )
728733 }
729734 }
0 commit comments