@@ -14,7 +14,6 @@ use rustc_middle::mir::RetagKind;
1414use rustc_middle:: ty:: {
1515 self ,
1616 layout:: { HasParamEnv , LayoutOf } ,
17- Ty ,
1817} ;
1918use rustc_target:: abi:: Abi ;
2019use rustc_target:: abi:: Size ;
@@ -983,28 +982,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
983982 let mut visitor = RetagVisitor { ecx : this, kind, retag_cause, retag_fields } ;
984983 return visitor. visit_value ( place) ;
985984
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-
1008985 // The actual visitor.
1009986 struct RetagVisitor < ' ecx , ' mir , ' tcx > {
1010987 ecx : & ' ecx mut MiriInterpCx < ' mir , ' tcx > ,
@@ -1057,34 +1034,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10571034 return Ok ( ( ) ) ;
10581035 }
10591036
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) ?;
10681085 }
10691086 }
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) ?;
10871087 }
1088+
10881089 Ok ( ( ) )
10891090 }
10901091 }
0 commit comments