@@ -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
@@ -766,11 +766,12 @@ fn transform_predicates<'tcx>(
766766fn  transform_args < ' tcx > ( 
767767    tcx :  TyCtxt < ' tcx > , 
768768    args :  GenericArgsRef < ' tcx > , 
769+     parents :  & mut  Vec < 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 :  & mut  Vec < 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+                     parents. push ( ty) ; 
883895                    if  ty0. is_any_ptr ( )  && ty0. contains ( ty)  { 
884896                        ty = transform_ty ( 
885897                            tcx, 
886898                            ty0, 
899+                             parents, 
887900                            options | TransformTyOptions :: GENERALIZE_POINTERS , 
888901                        ) ; 
889902                    }  else  { 
890-                         ty = transform_ty ( tcx,  ty0,  options) ; 
903+                         ty = transform_ty ( tcx,  ty0,  parents ,   options) ; 
891904                    } 
905+                     parents. pop ( ) ; 
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 ,  & mut   Vec :: new ( ) ,   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 ,  & mut   Vec :: new ( ) ,   transform_ty_options) ; 
10521071            typeid. push_str ( & encode_ty ( tcx,  ty,  & mut  dict,  encode_ty_options) ) ; 
10531072        } 
10541073        if  !pushed_arg { 
@@ -1061,7 +1080,8 @@ 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 =
1084+                 transform_ty ( tcx,  fn_abi. args [ n] . layout . ty ,  & mut  Vec :: new ( ) ,  transform_ty_options) ; 
10651085            typeid. push_str ( & encode_ty ( tcx,  ty,  & mut  dict,  encode_ty_options) ) ; 
10661086        } 
10671087
0 commit comments