@@ -2092,10 +2092,6 @@ pub enum TyKind {
20922092Never , 
20932093    /// A tuple (`(A, B, C, D,...)`). 
20942094Tup ( ThinVec < P < Ty > > ) , 
2095-     /// An anonymous struct type i.e. `struct { foo: Type }` 
2096- AnonStruct ( ThinVec < FieldDef > ) , 
2097-     /// An anonymous union type i.e. `union { bar: Type }` 
2098- AnonUnion ( ThinVec < FieldDef > ) , 
20992095    /// A path (`module::module::...::Type`), optionally 
21002096/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. 
21012097/// 
@@ -2715,6 +2711,93 @@ impl VisibilityKind {
27152711    } 
27162712} 
27172713
2714+ #[ derive( Clone ,  Copy ,  Encodable ,  Decodable ,  Debug ) ]  
2715+ pub  enum  AnonRecordKind  { 
2716+     Struct , 
2717+     Union , 
2718+ } 
2719+ 
2720+ impl  AnonRecordKind  { 
2721+     /// Returns the lowercase name. 
2722+ pub  fn  name ( self )  -> & ' static  str  { 
2723+         match  self  { 
2724+             Self :: Struct  => "struct" , 
2725+             Self :: Union  => "union" , 
2726+         } 
2727+     } 
2728+ } 
2729+ 
2730+ /// An anonymous struct or union, i.e. `struct { foo: Foo }` or `union { foo: Foo }`. 
2731+ #[ derive( Clone ,  Encodable ,  Decodable ,  Debug ) ]  
2732+ pub  struct  AnonRecord  { 
2733+     pub  id :  NodeId , 
2734+     pub  span :  Span , 
2735+     pub  fields :  ThinVec < FieldDef > , 
2736+     pub  kind :  AnonRecordKind , 
2737+     pub  recovered :  bool , 
2738+ } 
2739+ 
2740+ impl  AnonRecord  { 
2741+     pub  fn  is_union ( & self )  -> bool  { 
2742+         matches ! ( self . kind,  AnonRecordKind :: Union ) 
2743+     } 
2744+     pub  fn  is_struct ( & self )  -> bool  { 
2745+         matches ! ( self . kind,  AnonRecordKind :: Struct ) 
2746+     } 
2747+ } 
2748+ 
2749+ /// Type of fields in a struct, variant or union. 
2750+ #[ derive( Clone ,  Encodable ,  Decodable ,  Debug ) ]  
2751+ pub  enum  FieldTy  { 
2752+     Ty ( P < Ty > ) , 
2753+     /// An anonymous struct or union, i.e. `struct { foo: Foo }` or `union { foo: Foo }`. 
2754+ // AnonRecord(P<Item>), 
2755+     AnonRecord ( P < AnonRecord > ) , 
2756+ } 
2757+ 
2758+ impl  From < P < Ty > >  for  FieldTy  { 
2759+     fn  from ( ty :  P < Ty > )  -> Self  { 
2760+         Self :: Ty ( ty) 
2761+     } 
2762+ } 
2763+ 
2764+ impl  From < AnonRecord >  for  FieldTy  { 
2765+     fn  from ( anon_record :  AnonRecord )  -> Self  { 
2766+         Self :: AnonRecord ( P ( anon_record) ) 
2767+     } 
2768+ } 
2769+ 
2770+ impl  FieldTy  { 
2771+     pub  fn  id ( & self )  -> NodeId  { 
2772+         match  self  { 
2773+             Self :: Ty ( ty)  => ty. id , 
2774+             Self :: AnonRecord ( anon_record)  => anon_record. id , 
2775+         } 
2776+     } 
2777+ 
2778+     pub  fn  span ( & self )  -> Span  { 
2779+         match  self  { 
2780+             Self :: Ty ( ty)  => ty. span , 
2781+             Self :: AnonRecord ( anon_record)  => anon_record. span , 
2782+         } 
2783+     } 
2784+ 
2785+     pub  fn  as_ty ( & self )  -> Option < & P < Ty > >  { 
2786+         match  self  { 
2787+             Self :: Ty ( ty)  => Some ( ty) , 
2788+             _ => None , 
2789+         } 
2790+     } 
2791+ 
2792+     /// Expects a `Ty`, otherwise panics. 
2793+ pub  fn  expect_ty ( & self )  -> & P < Ty >  { 
2794+         let  FieldTy :: Ty ( ty)  = & self  else  { 
2795+             panic ! ( "expect a type, found {self:?}" ) ; 
2796+         } ; 
2797+         ty
2798+     } 
2799+ } 
2800+ 
27182801/// Field definition in a struct, variant or union. 
27192802/// 
27202803/// E.g., `bar: usize` as in `struct Foo { bar: usize }`. 
@@ -2726,7 +2809,7 @@ pub struct FieldDef {
27262809    pub  vis :  Visibility , 
27272810    pub  ident :  Option < Ident > , 
27282811
2729-     pub  ty :  P < Ty > , 
2812+     pub  ty :  FieldTy , 
27302813    pub  is_placeholder :  bool , 
27312814} 
27322815
@@ -2756,6 +2839,27 @@ impl VariantData {
27562839        } 
27572840    } 
27582841
2842+     /// Return all fields of this variant, with anonymous structs or unions flattened. 
2843+ pub  fn  all_fields ( & self )  -> AllFields < ' _ >  { 
2844+         AllFields  {  iters :  smallvec:: smallvec![ self . fields( ) . iter( ) ]  } 
2845+     } 
2846+ 
2847+     /// Return whether this variant contains inner anonymous unions. 
2848+ pub  fn  find_inner_union ( & self )  -> Option < Span >  { 
2849+         // We only check the record-like structs 
2850+         let  VariantData :: Struct ( fields,  ..)  = self  else  {  return  None  } ; 
2851+         fn  find_union ( fields :  & [ FieldDef ] )  -> Option < Span >  { 
2852+             fields. iter ( ) . find_map ( |field| { 
2853+                 let  FieldTy :: AnonRecord ( anon_record)  = & field. ty  else  {  return  None  } ; 
2854+                 anon_record
2855+                     . is_union ( ) 
2856+                     . then ( || anon_record. span ) 
2857+                     . or_else ( || find_union ( & anon_record. fields ) ) 
2858+             } ) 
2859+         } 
2860+         find_union ( & fields) 
2861+     } 
2862+ 
27592863    /// Return the `NodeId` of this variant's constructor, if it has one. 
27602864pub  fn  ctor_node_id ( & self )  -> Option < NodeId >  { 
27612865        match  * self  { 
@@ -2765,6 +2869,44 @@ impl VariantData {
27652869    } 
27662870} 
27672871
2872+ /// Iterator of all fields of a `VariantData`. 
2873+ /// 
2874+ /// It iterates on the field tree in preorder, where the unnamed fields with anonymous structs or unions 
2875+ /// are flattened to their inner fields. 
2876+ pub  struct  AllFields < ' a >  { 
2877+     iters :  smallvec:: SmallVec < [ std:: slice:: Iter < ' a ,  FieldDef > ;  1 ] > , 
2878+ } 
2879+ 
2880+ impl < ' a >  Iterator  for  AllFields < ' a >  { 
2881+     type  Item  = & ' a  FieldDef ; 
2882+ 
2883+     fn  next ( & mut  self )  -> Option < Self :: Item >  { 
2884+         let  mut  top = self . iters . last_mut ( ) ?; 
2885+         loop  { 
2886+             if  let  Some ( field)  = top. next ( )  { 
2887+                 if  let  FieldTy :: AnonRecord ( anon_record)  = & field. ty  { 
2888+                     self . iters . push ( anon_record. fields . iter ( ) ) ; 
2889+                     top = self . iters . last_mut ( ) . unwrap ( ) ; 
2890+                     continue ; 
2891+                 } 
2892+                 return  Some ( field) ; 
2893+             } 
2894+             self . iters . pop ( ) ; 
2895+             top = self . iters . last_mut ( ) ?; 
2896+         } 
2897+     } 
2898+ 
2899+     fn  size_hint ( & self )  -> ( usize ,  Option < usize > )  { 
2900+         match  & self . iters [ ..]  { 
2901+             [ ]  => ( 0 ,  Some ( 0 ) ) , 
2902+             [ single]  => ( single. size_hint ( ) . 0 ,  None ) , 
2903+             [ first,  ..,  last]  => ( first. size_hint ( ) . 0  + last. size_hint ( ) . 0 ,  None ) , 
2904+         } 
2905+     } 
2906+ } 
2907+ 
2908+ impl  std:: iter:: FusedIterator  for  AllFields < ' _ >  { } 
2909+ 
27682910/// An item definition. 
27692911#[ derive( Clone ,  Encodable ,  Decodable ,  Debug ) ]  
27702912pub  struct  Item < K  = ItemKind >  { 
0 commit comments