@@ -1037,17 +1037,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1037
1037
// Raw pointers need to be enabled.
1038
1038
ty:: RawPtr ( tym) if kind == RetagKind :: Raw =>
1039
1039
Some ( ( RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } , false ) ) ,
1040
- // Boxes are handled separately due to that allocator situation.
1040
+ // Boxes are handled separately due to that allocator situation,
1041
+ // see the visitor below.
1041
1042
_ => None ,
1042
1043
}
1043
1044
}
1044
1045
1045
- // We need a visitor to visit all references. However, that requires
1046
- // a `MPlaceTy` (or `OpTy`), so we have a fast path for reference types that
1047
- // avoids allocating.
1048
-
1046
+ // For some types we can do the work without starting up the visitor infrastructure.
1049
1047
if let Some ( ( ref_kind, protector) ) = qualify ( place. layout . ty , kind) {
1050
- // Fast path.
1051
1048
let val = this. read_immediate ( & this. place_to_op ( place) ?) ?;
1052
1049
let val = this. retag_reference ( & val, ref_kind, protector) ?;
1053
1050
this. write_immediate ( * val, place) ?;
@@ -1077,11 +1074,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1077
1074
) {
1078
1075
return Ok ( ( ) ) ;
1079
1076
}
1080
- // Now go visit this thing.
1081
- let place = this. force_allocation ( place) ?;
1082
1077
1078
+ // Now go visit this thing.
1083
1079
let mut visitor = RetagVisitor { ecx : this, kind } ;
1084
- return visitor. visit_value ( & place) ;
1080
+ return visitor. visit_value ( place) ;
1085
1081
1086
1082
// The actual visitor.
1087
1083
struct RetagVisitor < ' ecx , ' mir , ' tcx > {
@@ -1091,36 +1087,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1091
1087
impl < ' ecx , ' mir , ' tcx > MutValueVisitor < ' mir , ' tcx , Evaluator < ' mir , ' tcx > >
1092
1088
for RetagVisitor < ' ecx , ' mir , ' tcx >
1093
1089
{
1094
- type V = MPlaceTy < ' tcx , Tag > ;
1090
+ type V = PlaceTy < ' tcx , Tag > ;
1095
1091
1096
1092
#[ inline( always) ]
1097
1093
fn ecx ( & mut self ) -> & mut MiriEvalContext < ' mir , ' tcx > {
1098
1094
self . ecx
1099
1095
}
1100
1096
1101
- fn visit_box ( & mut self , place : & MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
1097
+ fn visit_box ( & mut self , place : & PlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
1102
1098
// Boxes do not get a protector: protectors reflect that references outlive the call
1103
1099
// they were passed in to; that's just not the case for boxes.
1104
1100
let ( ref_kind, protector) = ( RefKind :: Unique { two_phase : false } , false ) ;
1105
-
1106
- let val = self . ecx . read_immediate ( & place. into ( ) ) ?;
1101
+ let val = self . ecx . read_immediate ( & self . ecx . place_to_op ( place) ?) ?;
1107
1102
let val = self . ecx . retag_reference ( & val, ref_kind, protector) ?;
1108
- self . ecx . write_immediate ( * val, & place. into ( ) ) ?;
1103
+ self . ecx . write_immediate ( * val, place) ?;
1109
1104
Ok ( ( ) )
1110
1105
}
1111
1106
1112
- fn visit_value ( & mut self , place : & MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
1107
+ fn visit_value ( & mut self , place : & PlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
1113
1108
if let Some ( ( ref_kind, protector) ) = qualify ( place. layout . ty , self . kind ) {
1114
- let val = self . ecx . read_immediate ( & place . into ( ) ) ?;
1109
+ let val = self . ecx . read_immediate ( & self . ecx . place_to_op ( place ) ? ) ?;
1115
1110
let val = self . ecx . retag_reference ( & val, ref_kind, protector) ?;
1116
- self . ecx . write_immediate ( * val, & place. into ( ) ) ?;
1111
+ self . ecx . write_immediate ( * val, place) ?;
1117
1112
} else if matches ! ( place. layout. ty. kind( ) , ty:: RawPtr ( ..) ) {
1118
1113
// Wide raw pointers *do* have fields and their types are strange.
1119
1114
// vtables have a type like `&[*const (); 3]` or so!
1120
1115
// Do *not* recurse into them.
1121
- // (No need to worry about wide references or boxes, those always "qualify".)
1116
+ // (No need to worry about wide references, those always "qualify". And Boxes
1117
+ // are handles specially by the visitor anyway.)
1122
1118
} else {
1123
- // Maybe we need to go deeper.
1119
+ // Recurse deeper.
1124
1120
self . walk_value ( place) ?;
1125
1121
}
1126
1122
Ok ( ( ) )
0 commit comments