@@ -178,14 +178,14 @@ fn encode_fnsig<'tcx>(
178
178
// Encode the return type
179
179
let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
180
180
. unwrap_or_else ( || bug ! ( "encode_fnsig: invalid option(s) `{:?}`" , options. bits( ) ) ) ;
181
- let ty = transform_ty ( tcx, fn_sig. output ( ) , transform_ty_options) ;
181
+ let ty = transform_ty ( tcx, fn_sig. output ( ) , & mut Vec :: new ( ) , transform_ty_options) ;
182
182
s. push_str ( & encode_ty ( tcx, ty, dict, encode_ty_options) ) ;
183
183
184
184
// Encode the parameter types
185
185
let tys = fn_sig. inputs ( ) ;
186
186
if !tys. is_empty ( ) {
187
187
for ty in tys {
188
- let ty = transform_ty ( tcx, * ty, transform_ty_options) ;
188
+ let ty = transform_ty ( tcx, * ty, & mut Vec :: new ( ) , transform_ty_options) ;
189
189
s. push_str ( & encode_ty ( tcx, ty, dict, encode_ty_options) ) ;
190
190
}
191
191
@@ -766,11 +766,12 @@ fn transform_predicates<'tcx>(
766
766
fn transform_args < ' tcx > (
767
767
tcx : TyCtxt < ' tcx > ,
768
768
args : GenericArgsRef < ' tcx > ,
769
+ parents : & mut Vec < Ty < ' tcx > > ,
769
770
options : TransformTyOptions ,
770
771
) -> GenericArgsRef < ' tcx > {
771
772
let args = args. iter ( ) . map ( |arg| match arg. unpack ( ) {
772
773
GenericArgKind :: Type ( ty) if ty. is_c_void ( tcx) => Ty :: new_unit ( tcx) . into ( ) ,
773
- GenericArgKind :: Type ( ty) => transform_ty ( tcx, ty, options) . into ( ) ,
774
+ GenericArgKind :: Type ( ty) => transform_ty ( tcx, ty, parents , options) . into ( ) ,
774
775
_ => arg,
775
776
} ) ;
776
777
tcx. mk_args_from_iter ( args)
@@ -780,9 +781,12 @@ fn transform_args<'tcx>(
780
781
// c_void types into unit types unconditionally, generalizes pointers if
781
782
// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
782
783
// TransformTyOptions::NORMALIZE_INTEGERS option is set.
783
- fn transform_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , options : TransformTyOptions ) -> Ty < ' tcx > {
784
- let mut ty = ty;
785
-
784
+ fn transform_ty < ' tcx > (
785
+ tcx : TyCtxt < ' tcx > ,
786
+ mut ty : Ty < ' tcx > ,
787
+ parents : & mut Vec < Ty < ' tcx > > ,
788
+ options : TransformTyOptions ,
789
+ ) -> Ty < ' tcx > {
786
790
match ty. kind ( ) {
787
791
ty:: Float ( ..) | ty:: Str | ty:: Never | ty:: Foreign ( ..) | ty:: CoroutineWitness ( ..) => { }
788
792
@@ -842,17 +846,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
842
846
_ if ty. is_unit ( ) => { }
843
847
844
848
ty:: Tuple ( tys) => {
845
- ty = Ty :: new_tup_from_iter ( tcx, tys. iter ( ) . map ( |ty| transform_ty ( tcx, ty, options) ) ) ;
849
+ ty = Ty :: new_tup_from_iter (
850
+ tcx,
851
+ tys. iter ( ) . map ( |ty| transform_ty ( tcx, ty, parents, options) ) ,
852
+ ) ;
846
853
}
847
854
848
855
ty:: Array ( ty0, len) => {
849
856
let len = len. eval_target_usize ( tcx, ty:: ParamEnv :: reveal_all ( ) ) ;
850
857
851
- ty = Ty :: new_array ( tcx, transform_ty ( tcx, * ty0, options) , len) ;
858
+ ty = Ty :: new_array ( tcx, transform_ty ( tcx, * ty0, parents , options) , len) ;
852
859
}
853
860
854
861
ty:: Slice ( ty0) => {
855
- ty = Ty :: new_slice ( tcx, transform_ty ( tcx, * ty0, options) ) ;
862
+ ty = Ty :: new_slice ( tcx, transform_ty ( tcx, * ty0, parents , options) ) ;
856
863
}
857
864
858
865
ty:: Adt ( adt_def, args) => {
@@ -861,7 +868,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
861
868
} else if options. contains ( TransformTyOptions :: GENERALIZE_REPR_C ) && adt_def. repr ( ) . c ( )
862
869
{
863
870
ty = Ty :: new_adt ( tcx, * adt_def, ty:: List :: empty ( ) ) ;
864
- } else if adt_def. repr ( ) . transparent ( ) && adt_def. is_struct ( ) {
871
+ } else if adt_def. repr ( ) . transparent ( ) && adt_def. is_struct ( ) && !parents. contains ( & ty)
872
+ {
865
873
// Don't transform repr(transparent) types with an user-defined CFI encoding to
866
874
// preserve the user-defined CFI encoding.
867
875
if let Some ( _) = tcx. get_attr ( adt_def. did ( ) , sym:: cfi_encoding) {
@@ -880,38 +888,48 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
880
888
// Generalize any repr(transparent) user-defined type that is either a pointer
881
889
// or reference, and either references itself or any other type that contains or
882
890
// references itself, to avoid a reference cycle.
891
+
892
+ // If the self reference is not through a pointer, for example, due
893
+ // to using `PhantomData`, need to skip normalizing it if we hit it again.
894
+ parents. push ( ty) ;
883
895
if ty0. is_any_ptr ( ) && ty0. contains ( ty) {
884
896
ty = transform_ty (
885
897
tcx,
886
898
ty0,
899
+ parents,
887
900
options | TransformTyOptions :: GENERALIZE_POINTERS ,
888
901
) ;
889
902
} else {
890
- ty = transform_ty ( tcx, ty0, options) ;
903
+ ty = transform_ty ( tcx, ty0, parents , options) ;
891
904
}
905
+ parents. pop ( ) ;
892
906
} else {
893
907
// Transform repr(transparent) types without non-ZST field into ()
894
908
ty = Ty :: new_unit ( tcx) ;
895
909
}
896
910
} else {
897
- ty = Ty :: new_adt ( tcx, * adt_def, transform_args ( tcx, args, options) ) ;
911
+ ty = Ty :: new_adt ( tcx, * adt_def, transform_args ( tcx, args, parents , options) ) ;
898
912
}
899
913
}
900
914
901
915
ty:: FnDef ( def_id, args) => {
902
- ty = Ty :: new_fn_def ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
916
+ ty = Ty :: new_fn_def ( tcx, * def_id, transform_args ( tcx, args, parents , options) ) ;
903
917
}
904
918
905
919
ty:: Closure ( def_id, args) => {
906
- ty = Ty :: new_closure ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
920
+ ty = Ty :: new_closure ( tcx, * def_id, transform_args ( tcx, args, parents , options) ) ;
907
921
}
908
922
909
923
ty:: CoroutineClosure ( def_id, args) => {
910
- ty = Ty :: new_coroutine_closure ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
924
+ ty = Ty :: new_coroutine_closure (
925
+ tcx,
926
+ * def_id,
927
+ transform_args ( tcx, args, parents, options) ,
928
+ ) ;
911
929
}
912
930
913
931
ty:: Coroutine ( def_id, args) => {
914
- ty = Ty :: new_coroutine ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
932
+ ty = Ty :: new_coroutine ( tcx, * def_id, transform_args ( tcx, args, parents , options) ) ;
915
933
}
916
934
917
935
ty:: Ref ( region, ty0, ..) => {
@@ -923,9 +941,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
923
941
}
924
942
} else {
925
943
if ty. is_mutable_ptr ( ) {
926
- ty = Ty :: new_mut_ref ( tcx, * region, transform_ty ( tcx, * ty0, options) ) ;
944
+ ty = Ty :: new_mut_ref ( tcx, * region, transform_ty ( tcx, * ty0, parents , options) ) ;
927
945
} else {
928
- ty = Ty :: new_imm_ref ( tcx, * region, transform_ty ( tcx, * ty0, options) ) ;
946
+ ty = Ty :: new_imm_ref ( tcx, * region, transform_ty ( tcx, * ty0, parents , options) ) ;
929
947
}
930
948
}
931
949
}
@@ -939,9 +957,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
939
957
}
940
958
} else {
941
959
if ty. is_mutable_ptr ( ) {
942
- ty = Ty :: new_mut_ptr ( tcx, transform_ty ( tcx, tm. ty , options) ) ;
960
+ ty = Ty :: new_mut_ptr ( tcx, transform_ty ( tcx, tm. ty , parents , options) ) ;
943
961
} else {
944
- ty = Ty :: new_imm_ptr ( tcx, transform_ty ( tcx, tm. ty , options) ) ;
962
+ ty = Ty :: new_imm_ptr ( tcx, transform_ty ( tcx, tm. ty , parents , options) ) ;
945
963
}
946
964
}
947
965
}
@@ -954,9 +972,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
954
972
. skip_binder ( )
955
973
. inputs ( )
956
974
. iter ( )
957
- . map ( |ty| transform_ty ( tcx, * ty, options) )
975
+ . map ( |ty| transform_ty ( tcx, * ty, parents , options) )
958
976
. collect ( ) ;
959
- let output = transform_ty ( tcx, fn_sig. skip_binder ( ) . output ( ) , options) ;
977
+ let output = transform_ty ( tcx, fn_sig. skip_binder ( ) . output ( ) , parents , options) ;
960
978
ty = Ty :: new_fn_ptr (
961
979
tcx,
962
980
ty:: Binder :: bind_with_vars (
@@ -986,6 +1004,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
986
1004
ty = transform_ty (
987
1005
tcx,
988
1006
tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty) ,
1007
+ parents,
989
1008
options,
990
1009
) ;
991
1010
}
@@ -1036,7 +1055,7 @@ pub fn typeid_for_fnabi<'tcx>(
1036
1055
// Encode the return type
1037
1056
let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
1038
1057
. unwrap_or_else ( || bug ! ( "typeid_for_fnabi: invalid option(s) `{:?}`" , options. bits( ) ) ) ;
1039
- let ty = transform_ty ( tcx, fn_abi. ret . layout . ty , transform_ty_options) ;
1058
+ let ty = transform_ty ( tcx, fn_abi. ret . layout . ty , & mut Vec :: new ( ) , transform_ty_options) ;
1040
1059
typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
1041
1060
1042
1061
// Encode the parameter types
@@ -1048,7 +1067,7 @@ pub fn typeid_for_fnabi<'tcx>(
1048
1067
let mut pushed_arg = false ;
1049
1068
for arg in fn_abi. args . iter ( ) . filter ( |arg| arg. mode != PassMode :: Ignore ) {
1050
1069
pushed_arg = true ;
1051
- let ty = transform_ty ( tcx, arg. layout . ty , transform_ty_options) ;
1070
+ let ty = transform_ty ( tcx, arg. layout . ty , & mut Vec :: new ( ) , transform_ty_options) ;
1052
1071
typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
1053
1072
}
1054
1073
if !pushed_arg {
@@ -1061,7 +1080,8 @@ pub fn typeid_for_fnabi<'tcx>(
1061
1080
if fn_abi. args [ n] . mode == PassMode :: Ignore {
1062
1081
continue ;
1063
1082
}
1064
- let ty = transform_ty ( tcx, fn_abi. args [ n] . layout . ty , transform_ty_options) ;
1083
+ let ty =
1084
+ transform_ty ( tcx, fn_abi. args [ n] . layout . ty , & mut Vec :: new ( ) , transform_ty_options) ;
1065
1085
typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
1066
1086
}
1067
1087
0 commit comments