@@ -673,19 +673,27 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
673
673
fn_entry : bool ,
674
674
place : PlaceTy < ' tcx , Borrow >
675
675
) -> 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
+
676
690
// We need a visitor to visit all references. However, that requires
677
691
// a `MemPlace`, so we have a fast path for reference types that
678
692
// 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) {
686
694
// fast path
687
695
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 ) ?;
689
697
self . write_immediate ( val, place) ?;
690
698
return Ok ( ( ) ) ;
691
699
}
@@ -716,14 +724,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
716
724
{
717
725
// Cannot use `builtin_deref` because that reports *immutable* for `Box`,
718
726
// 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
+ }
727
732
Ok ( ( ) )
728
733
}
729
734
}
0 commit comments