@@ -976,27 +976,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
976
976
// Raw pointers need to be enabled.
977
977
ty:: RawPtr ( tym) if kind == RetagKind :: Raw =>
978
978
Some ( ( RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } , false ) ) ,
979
- // Boxes do not get a protector: protectors reflect that references outlive the call
980
- // they were passed in to; that's just not the case for boxes.
981
- ty:: Adt ( ..) if ty. is_box ( ) => Some ( ( RefKind :: Unique { two_phase : false } , false ) ) ,
979
+ // Boxes are handled separately due to that allocator situation.
982
980
_ => None ,
983
981
}
984
982
}
985
983
986
984
// We need a visitor to visit all references. However, that requires
987
- // a `MPlaceTy` (or `OpTy), so we have a fast path for reference types that
985
+ // a `MPlaceTy` (or `OpTy` ), so we have a fast path for reference types that
988
986
// avoids allocating.
989
987
990
- if let Some ( ( mutbl , protector) ) = qualify ( place. layout . ty , kind) {
988
+ if let Some ( ( ref_kind , protector) ) = qualify ( place. layout . ty , kind) {
991
989
// Fast path.
992
990
let val = this. read_immediate ( & this. place_to_op ( place) ?) ?;
993
- let val = this. retag_reference ( & val, mutbl , protector) ?;
991
+ let val = this. retag_reference ( & val, ref_kind , protector) ?;
994
992
this. write_immediate ( * val, place) ?;
995
993
return Ok ( ( ) ) ;
996
994
}
997
995
998
996
// If we don't want to recurse, we are already done.
999
- if !this. machine . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) . retag_fields {
997
+ // EXCEPT if this is a `Box`, then we have to recurse because allocators.
998
+ // (Yes this means we technically also recursively retag the allocator itself even if field
999
+ // retagging is not enabled. *shrug*)
1000
+ if !this. machine . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) . retag_fields
1001
+ && !place. layout . ty . ty_adt_def ( ) . is_some_and ( |adt| adt. is_box ( ) )
1002
+ {
1000
1003
return Ok ( ( ) ) ;
1001
1004
}
1002
1005
@@ -1034,10 +1037,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1034
1037
self . ecx
1035
1038
}
1036
1039
1040
+ fn visit_box ( & mut self , place : & MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
1041
+ // Boxes do not get a protector: protectors reflect that references outlive the call
1042
+ // they were passed in to; that's just not the case for boxes.
1043
+ let ( ref_kind, protector) = ( RefKind :: Unique { two_phase : false } , false ) ;
1044
+
1045
+ let val = self . ecx . read_immediate ( & place. into ( ) ) ?;
1046
+ let val = self . ecx . retag_reference ( & val, ref_kind, protector) ?;
1047
+ self . ecx . write_immediate ( * val, & place. into ( ) ) ?;
1048
+ Ok ( ( ) )
1049
+ }
1050
+
1037
1051
fn visit_value ( & mut self , place : & MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
1038
- if let Some ( ( mutbl , protector) ) = qualify ( place. layout . ty , self . kind ) {
1052
+ if let Some ( ( ref_kind , protector) ) = qualify ( place. layout . ty , self . kind ) {
1039
1053
let val = self . ecx . read_immediate ( & place. into ( ) ) ?;
1040
- let val = self . ecx . retag_reference ( & val, mutbl , protector) ?;
1054
+ let val = self . ecx . retag_reference ( & val, ref_kind , protector) ?;
1041
1055
self . ecx . write_immediate ( * val, & place. into ( ) ) ?;
1042
1056
} else if matches ! ( place. layout. ty. kind( ) , ty:: RawPtr ( ..) ) {
1043
1057
// Wide raw pointers *do* have fields and their types are strange.
0 commit comments