@@ -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 ( ) , & [ ] , 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, & [ ] , transform_ty_options) ;
189189 s. push_str ( & encode_ty ( tcx, ty, dict, encode_ty_options) ) ;
190190 }
191191
@@ -770,11 +770,12 @@ fn transform_predicates<'tcx>(
770770fn transform_args < ' tcx > (
771771 tcx : TyCtxt < ' tcx > ,
772772 args : GenericArgsRef < ' tcx > ,
773+ parents : & [ Ty < ' tcx > ] ,
773774 options : TransformTyOptions ,
774775) -> GenericArgsRef < ' tcx > {
775776 let args = args. iter ( ) . map ( |arg| match arg. unpack ( ) {
776777 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 ( ) ,
778779 _ => arg,
779780 } ) ;
780781 tcx. mk_args_from_iter ( args)
@@ -784,9 +785,12 @@ fn transform_args<'tcx>(
784785// c_void types into unit types unconditionally, generalizes pointers if
785786// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
786787// 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 > {
790794 match ty. kind ( ) {
791795 ty:: Float ( ..) | ty:: Str | ty:: Never | ty:: Foreign ( ..) | ty:: CoroutineWitness ( ..) => { }
792796
@@ -846,17 +850,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
846850 _ if ty. is_unit ( ) => { }
847851
848852 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+ ) ;
850857 }
851858
852859 ty:: Array ( ty0, len) => {
853860 let len = len. eval_target_usize ( tcx, ty:: ParamEnv :: reveal_all ( ) ) ;
854861
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) ;
856863 }
857864
858865 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) ) ;
860867 }
861868
862869 ty:: Adt ( adt_def, args) => {
@@ -865,7 +872,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
865872 } else if options. contains ( TransformTyOptions :: GENERALIZE_REPR_C ) && adt_def. repr ( ) . c ( )
866873 {
867874 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+ {
869877 // Don't transform repr(transparent) types with an user-defined CFI encoding to
870878 // preserve the user-defined CFI encoding.
871879 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
884892 // Generalize any repr(transparent) user-defined type that is either a pointer
885893 // or reference, and either references itself or any other type that contains or
886894 // 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) ;
887900 if ty0. is_any_ptr ( ) && ty0. contains ( ty) {
888901 ty = transform_ty (
889902 tcx,
890903 ty0,
904+ & parents,
891905 options | TransformTyOptions :: GENERALIZE_POINTERS ,
892906 ) ;
893907 } else {
894- ty = transform_ty ( tcx, ty0, options) ;
908+ ty = transform_ty ( tcx, ty0, & parents , options) ;
895909 }
896910 } else {
897911 // Transform repr(transparent) types without non-ZST field into ()
898912 ty = Ty :: new_unit ( tcx) ;
899913 }
900914 } 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) ) ;
902916 }
903917 }
904918
905919 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) ) ;
907921 }
908922
909923 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) ) ;
911925 }
912926
913927 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+ ) ;
915933 }
916934
917935 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) ) ;
919937 }
920938
921939 ty:: Ref ( region, ty0, ..) => {
@@ -927,9 +945,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
927945 }
928946 } else {
929947 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) ) ;
931949 } 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) ) ;
933951 }
934952 }
935953 }
@@ -943,9 +961,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
943961 }
944962 } else {
945963 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) ) ;
947965 } 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) ) ;
949967 }
950968 }
951969 }
@@ -958,9 +976,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
958976 . skip_binder ( )
959977 . inputs ( )
960978 . iter ( )
961- . map ( |ty| transform_ty ( tcx, * ty, options) )
979+ . map ( |ty| transform_ty ( tcx, * ty, & parents , options) )
962980 . 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) ;
964982 ty = Ty :: new_fn_ptr (
965983 tcx,
966984 ty:: Binder :: bind_with_vars (
@@ -990,6 +1008,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
9901008 ty = transform_ty (
9911009 tcx,
9921010 tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty) ,
1011+ & parents,
9931012 options,
9941013 ) ;
9951014 }
@@ -1040,15 +1059,15 @@ pub fn typeid_for_fnabi<'tcx>(
10401059 // Encode the return type
10411060 let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
10421061 . 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) ;
10441063 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10451064
10461065 // Encode the parameter types
10471066 if !fn_abi. c_variadic {
10481067 let mut pushed_arg = false ;
10491068 for arg in fn_abi. args . iter ( ) . filter ( |arg| arg. mode != PassMode :: Ignore ) {
10501069 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) ;
10521071 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10531072 }
10541073 if !pushed_arg {
@@ -1061,7 +1080,7 @@ pub fn typeid_for_fnabi<'tcx>(
10611080 if fn_abi. args [ n] . mode == PassMode :: Ignore {
10621081 continue ;
10631082 }
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) ;
10651084 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10661085 }
10671086
0 commit comments