@@ -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 ( ) , & [ ] , 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, & [ ] , transform_ty_options) ;
189
189
s. push_str ( & encode_ty ( tcx, ty, dict, encode_ty_options) ) ;
190
190
}
191
191
@@ -770,11 +770,12 @@ fn transform_predicates<'tcx>(
770
770
fn transform_args < ' tcx > (
771
771
tcx : TyCtxt < ' tcx > ,
772
772
args : GenericArgsRef < ' tcx > ,
773
+ parents : & [ Ty < ' tcx > ] ,
773
774
options : TransformTyOptions ,
774
775
) -> GenericArgsRef < ' tcx > {
775
776
let args = args. iter ( ) . map ( |arg| match arg. unpack ( ) {
776
777
GenericArgKind :: Type ( ty) if ty. is_c_void ( tcx) => Ty :: new_unit ( tcx) . into ( ) ,
777
- GenericArgKind :: Type ( ty) => transform_ty ( tcx, ty, options) . into ( ) ,
778
+ GenericArgKind :: Type ( ty) => transform_ty ( tcx, ty, parents , options) . into ( ) ,
778
779
_ => arg,
779
780
} ) ;
780
781
tcx. mk_args_from_iter ( args)
@@ -784,9 +785,12 @@ fn transform_args<'tcx>(
784
785
// c_void types into unit types unconditionally, generalizes pointers if
785
786
// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
786
787
// TransformTyOptions::NORMALIZE_INTEGERS option is set.
787
- fn transform_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , options : TransformTyOptions ) -> Ty < ' tcx > {
788
- let mut ty = ty;
789
-
788
+ fn transform_ty < ' tcx > (
789
+ tcx : TyCtxt < ' tcx > ,
790
+ mut ty : Ty < ' tcx > ,
791
+ parents : & [ Ty < ' tcx > ] ,
792
+ options : TransformTyOptions ,
793
+ ) -> Ty < ' tcx > {
790
794
match ty. kind ( ) {
791
795
ty:: Float ( ..) | ty:: Str | ty:: Never | ty:: Foreign ( ..) | ty:: CoroutineWitness ( ..) => { }
792
796
@@ -846,17 +850,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
846
850
_ if ty. is_unit ( ) => { }
847
851
848
852
ty:: Tuple ( tys) => {
849
- ty = Ty :: new_tup_from_iter ( tcx, tys. iter ( ) . map ( |ty| transform_ty ( tcx, ty, options) ) ) ;
853
+ ty = Ty :: new_tup_from_iter (
854
+ tcx,
855
+ tys. iter ( ) . map ( |ty| transform_ty ( tcx, ty, & parents, options) ) ,
856
+ ) ;
850
857
}
851
858
852
859
ty:: Array ( ty0, len) => {
853
860
let len = len. eval_target_usize ( tcx, ty:: ParamEnv :: reveal_all ( ) ) ;
854
861
855
- ty = Ty :: new_array ( tcx, transform_ty ( tcx, * ty0, options) , len) ;
862
+ ty = Ty :: new_array ( tcx, transform_ty ( tcx, * ty0, & parents , options) , len) ;
856
863
}
857
864
858
865
ty:: Slice ( ty0) => {
859
- ty = Ty :: new_slice ( tcx, transform_ty ( tcx, * ty0, options) ) ;
866
+ ty = Ty :: new_slice ( tcx, transform_ty ( tcx, * ty0, & parents , options) ) ;
860
867
}
861
868
862
869
ty:: Adt ( adt_def, args) => {
@@ -865,7 +872,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
865
872
} else if options. contains ( TransformTyOptions :: GENERALIZE_REPR_C ) && adt_def. repr ( ) . c ( )
866
873
{
867
874
ty = Ty :: new_adt ( tcx, * adt_def, ty:: List :: empty ( ) ) ;
868
- } else if adt_def. repr ( ) . transparent ( ) && adt_def. is_struct ( ) {
875
+ } else if adt_def. repr ( ) . transparent ( ) && adt_def. is_struct ( ) && !parents. contains ( & ty)
876
+ {
869
877
// Don't transform repr(transparent) types with an user-defined CFI encoding to
870
878
// preserve the user-defined CFI encoding.
871
879
if let Some ( _) = tcx. get_attr ( adt_def. did ( ) , sym:: cfi_encoding) {
@@ -884,38 +892,48 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
884
892
// Generalize any repr(transparent) user-defined type that is either a pointer
885
893
// or reference, and either references itself or any other type that contains or
886
894
// references itself, to avoid a reference cycle.
895
+
896
+ // If the self reference is not through a pointer, for example, due
897
+ // to using `PhantomData`, need to skip normalizing it if we hit it again.
898
+ let mut parents = parents. to_vec ( ) ;
899
+ parents. push ( ty) ;
887
900
if ty0. is_any_ptr ( ) && ty0. contains ( ty) {
888
901
ty = transform_ty (
889
902
tcx,
890
903
ty0,
904
+ & parents,
891
905
options | TransformTyOptions :: GENERALIZE_POINTERS ,
892
906
) ;
893
907
} else {
894
- ty = transform_ty ( tcx, ty0, options) ;
908
+ ty = transform_ty ( tcx, ty0, & parents , options) ;
895
909
}
896
910
} else {
897
911
// Transform repr(transparent) types without non-ZST field into ()
898
912
ty = Ty :: new_unit ( tcx) ;
899
913
}
900
914
} else {
901
- ty = Ty :: new_adt ( tcx, * adt_def, transform_args ( tcx, args, options) ) ;
915
+ ty = Ty :: new_adt ( tcx, * adt_def, transform_args ( tcx, args, & parents , options) ) ;
902
916
}
903
917
}
904
918
905
919
ty:: FnDef ( def_id, args) => {
906
- ty = Ty :: new_fn_def ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
920
+ ty = Ty :: new_fn_def ( tcx, * def_id, transform_args ( tcx, args, & parents , options) ) ;
907
921
}
908
922
909
923
ty:: Closure ( def_id, args) => {
910
- ty = Ty :: new_closure ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
924
+ ty = Ty :: new_closure ( tcx, * def_id, transform_args ( tcx, args, & parents , options) ) ;
911
925
}
912
926
913
927
ty:: CoroutineClosure ( def_id, args) => {
914
- ty = Ty :: new_coroutine_closure ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
928
+ ty = Ty :: new_coroutine_closure (
929
+ tcx,
930
+ * def_id,
931
+ transform_args ( tcx, args, & parents, options) ,
932
+ ) ;
915
933
}
916
934
917
935
ty:: Coroutine ( def_id, args) => {
918
- ty = Ty :: new_coroutine ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
936
+ ty = Ty :: new_coroutine ( tcx, * def_id, transform_args ( tcx, args, & parents , options) ) ;
919
937
}
920
938
921
939
ty:: Ref ( region, ty0, ..) => {
@@ -927,9 +945,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
927
945
}
928
946
} else {
929
947
if ty. is_mutable_ptr ( ) {
930
- ty = Ty :: new_mut_ref ( tcx, * region, transform_ty ( tcx, * ty0, options) ) ;
948
+ ty = Ty :: new_mut_ref ( tcx, * region, transform_ty ( tcx, * ty0, & parents , options) ) ;
931
949
} else {
932
- ty = Ty :: new_imm_ref ( tcx, * region, transform_ty ( tcx, * ty0, options) ) ;
950
+ ty = Ty :: new_imm_ref ( tcx, * region, transform_ty ( tcx, * ty0, & parents , options) ) ;
933
951
}
934
952
}
935
953
}
@@ -943,9 +961,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
943
961
}
944
962
} else {
945
963
if ty. is_mutable_ptr ( ) {
946
- ty = Ty :: new_mut_ptr ( tcx, transform_ty ( tcx, tm. ty , options) ) ;
964
+ ty = Ty :: new_mut_ptr ( tcx, transform_ty ( tcx, tm. ty , & parents , options) ) ;
947
965
} else {
948
- ty = Ty :: new_imm_ptr ( tcx, transform_ty ( tcx, tm. ty , options) ) ;
966
+ ty = Ty :: new_imm_ptr ( tcx, transform_ty ( tcx, tm. ty , & parents , options) ) ;
949
967
}
950
968
}
951
969
}
@@ -958,9 +976,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
958
976
. skip_binder ( )
959
977
. inputs ( )
960
978
. iter ( )
961
- . map ( |ty| transform_ty ( tcx, * ty, options) )
979
+ . map ( |ty| transform_ty ( tcx, * ty, & parents , options) )
962
980
. collect ( ) ;
963
- let output = transform_ty ( tcx, fn_sig. skip_binder ( ) . output ( ) , options) ;
981
+ let output = transform_ty ( tcx, fn_sig. skip_binder ( ) . output ( ) , & parents , options) ;
964
982
ty = Ty :: new_fn_ptr (
965
983
tcx,
966
984
ty:: Binder :: bind_with_vars (
@@ -990,6 +1008,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
990
1008
ty = transform_ty (
991
1009
tcx,
992
1010
tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty) ,
1011
+ & parents,
993
1012
options,
994
1013
) ;
995
1014
}
@@ -1040,15 +1059,15 @@ pub fn typeid_for_fnabi<'tcx>(
1040
1059
// Encode the return type
1041
1060
let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
1042
1061
. unwrap_or_else ( || bug ! ( "typeid_for_fnabi: invalid option(s) `{:?}`" , options. bits( ) ) ) ;
1043
- let ty = transform_ty ( tcx, fn_abi. ret . layout . ty , transform_ty_options) ;
1062
+ let ty = transform_ty ( tcx, fn_abi. ret . layout . ty , & [ ] , transform_ty_options) ;
1044
1063
typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
1045
1064
1046
1065
// Encode the parameter types
1047
1066
if !fn_abi. c_variadic {
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 , & [ ] , 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,7 @@ 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 = transform_ty ( tcx, fn_abi. args [ n] . layout . ty , & [ ] , transform_ty_options) ;
1065
1084
typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
1066
1085
}
1067
1086
0 commit comments