@@ -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
@@ -766,11 +766,12 @@ fn transform_predicates<'tcx>(
766766fn transform_args < ' tcx > (
767767 tcx : TyCtxt < ' tcx > ,
768768 args : GenericArgsRef < ' tcx > ,
769+ parents : & [ Ty < ' tcx > ] ,
769770 options : TransformTyOptions ,
770771) -> GenericArgsRef < ' tcx > {
771772 let args = args. iter ( ) . map ( |arg| match arg. unpack ( ) {
772773 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 ( ) ,
774775 _ => arg,
775776 } ) ;
776777 tcx. mk_args_from_iter ( args)
@@ -780,9 +781,12 @@ fn transform_args<'tcx>(
780781// c_void types into unit types unconditionally, generalizes pointers if
781782// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
782783// 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 : & [ Ty < ' tcx > ] ,
788+ options : TransformTyOptions ,
789+ ) -> Ty < ' tcx > {
786790 match ty. kind ( ) {
787791 ty:: Float ( ..) | ty:: Str | ty:: Never | ty:: Foreign ( ..) | ty:: CoroutineWitness ( ..) => { }
788792
@@ -842,17 +846,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
842846 _ if ty. is_unit ( ) => { }
843847
844848 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+ ) ;
846853 }
847854
848855 ty:: Array ( ty0, len) => {
849856 let len = len. eval_target_usize ( tcx, ty:: ParamEnv :: reveal_all ( ) ) ;
850857
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) ;
852859 }
853860
854861 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) ) ;
856863 }
857864
858865 ty:: Adt ( adt_def, args) => {
@@ -861,7 +868,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
861868 } else if options. contains ( TransformTyOptions :: GENERALIZE_REPR_C ) && adt_def. repr ( ) . c ( )
862869 {
863870 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+ {
865873 // Don't transform repr(transparent) types with an user-defined CFI encoding to
866874 // preserve the user-defined CFI encoding.
867875 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
880888 // Generalize any repr(transparent) user-defined type that is either a pointer
881889 // or reference, and either references itself or any other type that contains or
882890 // 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+ let mut parents = parents. to_vec ( ) ;
895+ parents. push ( ty) ;
883896 if ty0. is_any_ptr ( ) && ty0. contains ( ty) {
884897 ty = transform_ty (
885898 tcx,
886899 ty0,
900+ & parents,
887901 options | TransformTyOptions :: GENERALIZE_POINTERS ,
888902 ) ;
889903 } else {
890- ty = transform_ty ( tcx, ty0, options) ;
904+ ty = transform_ty ( tcx, ty0, & parents , options) ;
891905 }
892906 } else {
893907 // Transform repr(transparent) types without non-ZST field into ()
894908 ty = Ty :: new_unit ( tcx) ;
895909 }
896910 } 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) ) ;
898912 }
899913 }
900914
901915 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) ) ;
903917 }
904918
905919 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) ) ;
907921 }
908922
909923 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+ ) ;
911929 }
912930
913931 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) ) ;
915933 }
916934
917935 ty:: Ref ( region, ty0, ..) => {
@@ -923,9 +941,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
923941 }
924942 } else {
925943 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) ) ;
927945 } 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) ) ;
929947 }
930948 }
931949 }
@@ -939,9 +957,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
939957 }
940958 } else {
941959 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) ) ;
943961 } 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) ) ;
945963 }
946964 }
947965 }
@@ -954,9 +972,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
954972 . skip_binder ( )
955973 . inputs ( )
956974 . iter ( )
957- . map ( |ty| transform_ty ( tcx, * ty, options) )
975+ . map ( |ty| transform_ty ( tcx, * ty, & parents , options) )
958976 . 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) ;
960978 ty = Ty :: new_fn_ptr (
961979 tcx,
962980 ty:: Binder :: bind_with_vars (
@@ -986,6 +1004,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
9861004 ty = transform_ty (
9871005 tcx,
9881006 tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty) ,
1007+ & parents,
9891008 options,
9901009 ) ;
9911010 }
@@ -1036,7 +1055,7 @@ pub fn typeid_for_fnabi<'tcx>(
10361055 // Encode the return type
10371056 let transform_ty_options = TransformTyOptions :: from_bits ( options. bits ( ) )
10381057 . 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 , & [ ] , transform_ty_options) ;
10401059 typeid. push_str ( & encode_ty ( tcx, ty, & mut dict, encode_ty_options) ) ;
10411060
10421061 // Encode the parameter types
@@ -1048,7 +1067,7 @@ pub fn typeid_for_fnabi<'tcx>(
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