@@ -14,7 +14,6 @@ use rustc_middle::mir::RetagKind;
14
14
use rustc_middle:: ty:: {
15
15
self ,
16
16
layout:: { HasParamEnv , LayoutOf } ,
17
- Ty ,
18
17
} ;
19
18
use rustc_target:: abi:: Abi ;
20
19
use rustc_target:: abi:: Size ;
@@ -983,28 +982,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
983
982
let mut visitor = RetagVisitor { ecx : this, kind, retag_cause, retag_fields } ;
984
983
return visitor. visit_value ( place) ;
985
984
986
- // Determine mutability and whether to add a protector.
987
- // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
988
- // making it useless.
989
- fn qualify ( ty : Ty < ' _ > , kind : RetagKind ) -> Option < ( RefKind , bool ) > {
990
- match ty. kind ( ) {
991
- // References are simple.
992
- ty:: Ref ( _, _, Mutability :: Mut ) =>
993
- Some ( (
994
- RefKind :: Unique { two_phase : kind == RetagKind :: TwoPhase } ,
995
- kind == RetagKind :: FnEntry ,
996
- ) ) ,
997
- ty:: Ref ( _, _, Mutability :: Not ) =>
998
- Some ( ( RefKind :: Shared , kind == RetagKind :: FnEntry ) ) ,
999
- // Raw pointers need to be enabled.
1000
- ty:: RawPtr ( tym) if kind == RetagKind :: Raw =>
1001
- Some ( ( RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } , false ) ) ,
1002
- // Boxes are handled separately due to that allocator situation,
1003
- // see the visitor below.
1004
- _ => None ,
1005
- }
1006
- }
1007
-
1008
985
// The actual visitor.
1009
986
struct RetagVisitor < ' ecx , ' mir , ' tcx > {
1010
987
ecx : & ' ecx mut MiriInterpCx < ' mir , ' tcx > ,
@@ -1057,34 +1034,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1057
1034
return Ok ( ( ) ) ;
1058
1035
}
1059
1036
1060
- let recurse_for_fields = || {
1061
- match self . retag_fields {
1062
- RetagFields :: No => false ,
1063
- RetagFields :: Yes => true ,
1064
- RetagFields :: OnlyScalar => {
1065
- // Matching `ArgAbi::new` at the time of writing, only fields of
1066
- // `Scalar` and `ScalarPair` ABI are considered.
1067
- matches ! ( place. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) )
1037
+ // Check the type of this value to see what to do with it (retag, or recurse).
1038
+ match place. layout . ty . kind ( ) {
1039
+ ty:: Ref ( _, _, mutbl) => {
1040
+ let ref_kind = match mutbl {
1041
+ Mutability :: Mut =>
1042
+ RefKind :: Unique { two_phase : self . kind == RetagKind :: TwoPhase } ,
1043
+ Mutability :: Not => RefKind :: Shared ,
1044
+ } ;
1045
+ self . retag_place (
1046
+ place,
1047
+ ref_kind,
1048
+ self . retag_cause ,
1049
+ /*protector*/ self . kind == RetagKind :: FnEntry ,
1050
+ ) ?;
1051
+ }
1052
+ ty:: RawPtr ( tym) => {
1053
+ // We definitely do *not* want to recurse into raw pointers -- wide raw
1054
+ // pointers have fields, and for dyn Trait pointees those can have reference
1055
+ // type!
1056
+ if self . kind == RetagKind :: Raw {
1057
+ // Raw pointers need to be enabled.
1058
+ self . retag_place (
1059
+ place,
1060
+ RefKind :: Raw { mutable : tym. mutbl == Mutability :: Mut } ,
1061
+ self . retag_cause ,
1062
+ /*protector*/ false ,
1063
+ ) ?;
1064
+ }
1065
+ }
1066
+ _ if place. layout . ty . ty_adt_def ( ) . is_some_and ( |adt| adt. is_box ( ) ) => {
1067
+ // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
1068
+ // (Yes this means we technically also recursively retag the allocator itself
1069
+ // even if field retagging is not enabled. *shrug*)
1070
+ self . walk_value ( place) ?;
1071
+ }
1072
+ _ => {
1073
+ // Not a reference/pointer/box. Only recurse if configured appropriately.
1074
+ let recurse = match self . retag_fields {
1075
+ RetagFields :: No => false ,
1076
+ RetagFields :: Yes => true ,
1077
+ RetagFields :: OnlyScalar => {
1078
+ // Matching `ArgAbi::new` at the time of writing, only fields of
1079
+ // `Scalar` and `ScalarPair` ABI are considered.
1080
+ matches ! ( place. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) )
1081
+ }
1082
+ } ;
1083
+ if recurse {
1084
+ self . walk_value ( place) ?;
1068
1085
}
1069
1086
}
1070
- } ;
1071
-
1072
- if let Some ( ( ref_kind, protector) ) = qualify ( place. layout . ty , self . kind ) {
1073
- self . retag_place ( place, ref_kind, self . retag_cause , protector) ?;
1074
- } else if matches ! ( place. layout. ty. kind( ) , ty:: RawPtr ( ..) ) {
1075
- // Wide raw pointers *do* have fields and their types are strange.
1076
- // vtables have a type like `&[*const (); 3]` or so!
1077
- // Do *not* recurse into them.
1078
- // (No need to worry about wide references, those always "qualify". And Boxes
1079
- // are handles specially by the visitor anyway.)
1080
- } else if recurse_for_fields ( )
1081
- || place. layout . ty . ty_adt_def ( ) . is_some_and ( |adt| adt. is_box ( ) )
1082
- {
1083
- // Recurse deeper. Need to always recurse for `Box` to even hit `visit_box`.
1084
- // (Yes this means we technically also recursively retag the allocator itself
1085
- // even if field retagging is not enabled. *shrug*)
1086
- self . walk_value ( place) ?;
1087
1087
}
1088
+
1088
1089
Ok ( ( ) )
1089
1090
}
1090
1091
}
0 commit comments