@@ -178,14 +178,14 @@ fn encode_fnsig<'tcx>(
178178 // Encode the return type
179179 let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
180180 . 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) ;
182182 s. push_str ( & encode_ty ( tcx, ty, dict, encode_ty_options) ) ;
183183
184184 // Encode the parameter types
185185 let tys = fn_sig. inputs ( ) ;
186186 if !tys. is_empty ( ) {
187187 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) ;
189189 s. push_str ( & encode_ty ( tcx, ty, dict, encode_ty_options) ) ;
190190 }
191191
@@ -767,11 +767,12 @@ fn transform_predicates<'tcx>(
767767fn transform_args < ' tcx > (
768768 tcx : TyCtxt < ' tcx > ,
769769 args : GenericArgsRef < ' tcx > ,
770+ parents : & mut Vec < Ty < ' tcx > > ,
770771 options : TransformTyOptions ,
771772) -> GenericArgsRef < ' tcx > {
772773 let args = args. iter ( ) . map ( |arg| match arg. unpack ( ) {
773774 GenericArgKind :: Type ( ty) if ty. is_c_void ( tcx) => Ty :: new_unit ( tcx) . into ( ) ,
774- GenericArgKind :: Type ( ty) => transform_ty ( tcx, ty, options) . into ( ) ,
775+ GenericArgKind :: Type ( ty) => transform_ty ( tcx, ty, parents , options) . into ( ) ,
775776 _ => arg,
776777 } ) ;
777778 tcx. mk_args_from_iter ( args)
@@ -781,9 +782,12 @@ fn transform_args<'tcx>(
781782// c_void types into unit types unconditionally, generalizes pointers if
782783// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
783784// TransformTyOptions::NORMALIZE_INTEGERS option is set.
784- fn transform_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , options : TransformTyOptions ) -> Ty < ' tcx > {
785- let mut ty = ty;
786-
785+ fn transform_ty < ' tcx > (
786+ tcx : TyCtxt < ' tcx > ,
787+ mut ty : Ty < ' tcx > ,
788+ parents : & mut Vec < Ty < ' tcx > > ,
789+ options : TransformTyOptions ,
790+ ) -> Ty < ' tcx > {
787791 match ty. kind ( ) {
788792 ty:: Float ( ..) | ty:: Str | ty:: Never | ty:: Foreign ( ..) | ty:: CoroutineWitness ( ..) => { }
789793
@@ -843,17 +847,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
843847 _ if ty. is_unit ( ) => { }
844848
845849 ty:: Tuple ( tys) => {
846- ty = Ty :: new_tup_from_iter ( tcx, tys. iter ( ) . map ( |ty| transform_ty ( tcx, ty, options) ) ) ;
850+ ty = Ty :: new_tup_from_iter (
851+ tcx,
852+ tys. iter ( ) . map ( |ty| transform_ty ( tcx, ty, parents, options) ) ,
853+ ) ;
847854 }
848855
849856 ty:: Array ( ty0, len) => {
850857 let len = len. eval_target_usize ( tcx, ty:: ParamEnv :: reveal_all ( ) ) ;
851858
852- ty = Ty :: new_array ( tcx, transform_ty ( tcx, * ty0, options) , len) ;
859+ ty = Ty :: new_array ( tcx, transform_ty ( tcx, * ty0, parents , options) , len) ;
853860 }
854861
855862 ty:: Slice ( ty0) => {
856- ty = Ty :: new_slice ( tcx, transform_ty ( tcx, * ty0, options) ) ;
863+ ty = Ty :: new_slice ( tcx, transform_ty ( tcx, * ty0, parents , options) ) ;
857864 }
858865
859866 ty:: Adt ( adt_def, args) => {
@@ -862,7 +869,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
862869 } else if options. contains ( TransformTyOptions :: GENERALIZE_REPR_C ) && adt_def. repr ( ) . c ( )
863870 {
864871 ty = Ty :: new_adt ( tcx, * adt_def, ty:: List :: empty ( ) ) ;
865- } else if adt_def. repr ( ) . transparent ( ) && adt_def. is_struct ( ) {
872+ } else if adt_def. repr ( ) . transparent ( ) && adt_def. is_struct ( ) && !parents. contains ( & ty)
873+ {
866874 // Don't transform repr(transparent) types with an user-defined CFI encoding to
867875 // preserve the user-defined CFI encoding.
868876 if let Some ( _) = tcx. get_attr ( adt_def. did ( ) , sym:: cfi_encoding) {
@@ -881,38 +889,48 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
881889 // Generalize any repr(transparent) user-defined type that is either a pointer
882890 // or reference, and either references itself or any other type that contains or
883891 // references itself, to avoid a reference cycle.
892+
893+ // If the self reference is not through a pointer, for example, due
894+ // to using `PhantomData`, need to skip normalizing it if we hit it again.
895+ parents. push ( ty) ;
884896 if ty0. is_any_ptr ( ) && ty0. contains ( ty) {
885897 ty = transform_ty (
886898 tcx,
887899 ty0,
900+ parents,
888901 options | TransformTyOptions :: GENERALIZE_POINTERS ,
889902 ) ;
890903 } else {
891- ty = transform_ty ( tcx, ty0, options) ;
904+ ty = transform_ty ( tcx, ty0, parents , options) ;
892905 }
906+ parents. pop ( ) ;
893907 } else {
894908 // Transform repr(transparent) types without non-ZST field into ()
895909 ty = Ty :: new_unit ( tcx) ;
896910 }
897911 } else {
898- ty = Ty :: new_adt ( tcx, * adt_def, transform_args ( tcx, args, options) ) ;
912+ ty = Ty :: new_adt ( tcx, * adt_def, transform_args ( tcx, args, parents , options) ) ;
899913 }
900914 }
901915
902916 ty:: FnDef ( def_id, args) => {
903- ty = Ty :: new_fn_def ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
917+ ty = Ty :: new_fn_def ( tcx, * def_id, transform_args ( tcx, args, parents , options) ) ;
904918 }
905919
906920 ty:: Closure ( def_id, args) => {
907- ty = Ty :: new_closure ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
921+ ty = Ty :: new_closure ( tcx, * def_id, transform_args ( tcx, args, parents , options) ) ;
908922 }
909923
910924 ty:: CoroutineClosure ( def_id, args) => {
911- ty = Ty :: new_coroutine_closure ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
925+ ty = Ty :: new_coroutine_closure (
926+ tcx,
927+ * def_id,
928+ transform_args ( tcx, args, parents, options) ,
929+ ) ;
912930 }
913931
914932 ty:: Coroutine ( def_id, args) => {
915- ty = Ty :: new_coroutine ( tcx, * def_id, transform_args ( tcx, args, options) ) ;
933+ ty = Ty :: new_coroutine ( tcx, * def_id, transform_args ( tcx, args, parents , options) ) ;
916934 }
917935
918936 ty:: Ref ( region, ty0, ..) => {
@@ -924,9 +942,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
924942 }
925943 } else {
926944 if ty. is_mutable_ptr ( ) {
927- ty = Ty :: new_mut_ref ( tcx, * region, transform_ty ( tcx, * ty0, options) ) ;
945+ ty = Ty :: new_mut_ref ( tcx, * region, transform_ty ( tcx, * ty0, parents , options) ) ;
928946 } else {
929- ty = Ty :: new_imm_ref ( tcx, * region, transform_ty ( tcx, * ty0, options) ) ;
947+ ty = Ty :: new_imm_ref ( tcx, * region, transform_ty ( tcx, * ty0, parents , options) ) ;
930948 }
931949 }
932950 }
@@ -940,9 +958,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
940958 }
941959 } else {
942960 if ty. is_mutable_ptr ( ) {
943- ty = Ty :: new_mut_ptr ( tcx, transform_ty ( tcx, * ptr_ty, options) ) ;
961+ ty = Ty :: new_mut_ptr ( tcx, transform_ty ( tcx, * ptr_ty, parents , options) ) ;
944962 } else {
945- ty = Ty :: new_imm_ptr ( tcx, transform_ty ( tcx, * ptr_ty, options) ) ;
963+ ty = Ty :: new_imm_ptr ( tcx, transform_ty ( tcx, * ptr_ty, parents , options) ) ;
946964 }
947965 }
948966 }
@@ -955,9 +973,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
955973 . skip_binder ( )
956974 . inputs ( )
957975 . iter ( )
958- . map ( |ty| transform_ty ( tcx, * ty, options) )
976+ . map ( |ty| transform_ty ( tcx, * ty, parents , options) )
959977 . collect ( ) ;
960- let output = transform_ty ( tcx, fn_sig. skip_binder ( ) . output ( ) , options) ;
978+ let output = transform_ty ( tcx, fn_sig. skip_binder ( ) . output ( ) , parents , options) ;
961979 ty = Ty :: new_fn_ptr (
962980 tcx,
963981 ty:: Binder :: bind_with_vars (
@@ -987,6 +1005,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
9871005 ty = transform_ty (
9881006 tcx,
9891007 tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty) ,
1008+ parents,
9901009 options,
9911010 ) ;
9921011 }
@@ -1037,7 +1056,7 @@ pub fn typeid_for_fnabi<'tcx>(
10371056 // Encode the return type
10381057 let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
10391058 . unwrap_or_else ( || bug ! ( "typeid_for_fnabi: invalid option(s) `{:?}`" , options. bits( ) ) ) ;
1040- let ty = transform_ty ( tcx, fn_abi. ret . layout . ty , transform_ty_options) ;
1059+ let ty = transform_ty ( tcx, fn_abi. ret . layout . ty , & mut Vec :: new ( ) , transform_ty_options) ;
10411060 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10421061
10431062 // Encode the parameter types
@@ -1049,7 +1068,7 @@ pub fn typeid_for_fnabi<'tcx>(
10491068 let mut pushed_arg = false ;
10501069 for arg in fn_abi. args . iter ( ) . filter ( |arg| arg. mode != PassMode :: Ignore ) {
10511070 pushed_arg = true ;
1052- let ty = transform_ty ( tcx, arg. layout . ty , transform_ty_options) ;
1071+ let ty = transform_ty ( tcx, arg. layout . ty , & mut Vec :: new ( ) , transform_ty_options) ;
10531072 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10541073 }
10551074 if !pushed_arg {
@@ -1062,7 +1081,8 @@ pub fn typeid_for_fnabi<'tcx>(
10621081 if fn_abi. args [ n] . mode == PassMode :: Ignore {
10631082 continue ;
10641083 }
1065- let ty = transform_ty ( tcx, fn_abi. args [ n] . layout . ty , transform_ty_options) ;
1084+ let ty =
1085+ transform_ty ( tcx, fn_abi. args [ n] . layout . ty , & mut Vec :: new ( ) , transform_ty_options) ;
10661086 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10671087 }
10681088
0 commit comments