@@ -2060,10 +2060,6 @@ pub enum TyKind {
20602060Never , 
20612061    /// A tuple (`(A, B, C, D,...)`). 
20622062Tup ( ThinVec < P < Ty > > ) , 
2063-     /// An anonymous struct type i.e. `struct { foo: Type }` 
2064- AnonStruct ( ThinVec < FieldDef > ) , 
2065-     /// An anonymous union type i.e. `union { bar: Type }` 
2066- AnonUnion ( ThinVec < FieldDef > ) , 
20672063    /// A path (`module::module::...::Type`), optionally 
20682064/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. 
20692065/// 
@@ -2689,6 +2685,93 @@ impl VisibilityKind {
26892685    } 
26902686} 
26912687
2688+ #[ derive( Clone ,  Copy ,  Encodable ,  Decodable ,  Debug ) ]  
2689+ pub  enum  AnonRecordKind  { 
2690+     Struct , 
2691+     Union , 
2692+ } 
2693+ 
2694+ impl  AnonRecordKind  { 
2695+     /// Returns the lowercase name. 
2696+ pub  fn  name ( self )  -> & ' static  str  { 
2697+         match  self  { 
2698+             Self :: Struct  => "struct" , 
2699+             Self :: Union  => "union" , 
2700+         } 
2701+     } 
2702+ } 
2703+ 
2704+ /// An anonymous struct or union, i.e. `struct { foo: Foo }` or `union { foo: Foo }`. 
2705+ #[ derive( Clone ,  Encodable ,  Decodable ,  Debug ) ]  
2706+ pub  struct  AnonRecord  { 
2707+     pub  id :  NodeId , 
2708+     pub  span :  Span , 
2709+     pub  fields :  ThinVec < FieldDef > , 
2710+     pub  kind :  AnonRecordKind , 
2711+     pub  recovered :  bool , 
2712+ } 
2713+ 
2714+ impl  AnonRecord  { 
2715+     pub  fn  is_union ( & self )  -> bool  { 
2716+         matches ! ( self . kind,  AnonRecordKind :: Union ) 
2717+     } 
2718+     pub  fn  is_struct ( & self )  -> bool  { 
2719+         matches ! ( self . kind,  AnonRecordKind :: Struct ) 
2720+     } 
2721+ } 
2722+ 
2723+ /// Type of fields in a struct, variant or union. 
2724+ #[ derive( Clone ,  Encodable ,  Decodable ,  Debug ) ]  
2725+ pub  enum  FieldTy  { 
2726+     Ty ( P < Ty > ) , 
2727+     /// An anonymous struct or union, i.e. `struct { foo: Foo }` or `union { foo: Foo }`. 
2728+ // AnonRecord(P<Item>), 
2729+     AnonRecord ( P < AnonRecord > ) , 
2730+ } 
2731+ 
2732+ impl  From < P < Ty > >  for  FieldTy  { 
2733+     fn  from ( ty :  P < Ty > )  -> Self  { 
2734+         Self :: Ty ( ty) 
2735+     } 
2736+ } 
2737+ 
2738+ impl  From < AnonRecord >  for  FieldTy  { 
2739+     fn  from ( anon_record :  AnonRecord )  -> Self  { 
2740+         Self :: AnonRecord ( P ( anon_record) ) 
2741+     } 
2742+ } 
2743+ 
2744+ impl  FieldTy  { 
2745+     pub  fn  id ( & self )  -> NodeId  { 
2746+         match  self  { 
2747+             Self :: Ty ( ty)  => ty. id , 
2748+             Self :: AnonRecord ( anon_record)  => anon_record. id , 
2749+         } 
2750+     } 
2751+ 
2752+     pub  fn  span ( & self )  -> Span  { 
2753+         match  self  { 
2754+             Self :: Ty ( ty)  => ty. span , 
2755+             Self :: AnonRecord ( anon_record)  => anon_record. span , 
2756+         } 
2757+     } 
2758+ 
2759+     pub  fn  as_ty ( & self )  -> Option < & P < Ty > >  { 
2760+         match  self  { 
2761+             Self :: Ty ( ty)  => Some ( ty) , 
2762+             _ => None , 
2763+         } 
2764+     } 
2765+ 
2766+     /// Expects a `Ty`, otherwise panics. 
2767+ pub  fn  expect_ty ( & self )  -> & P < Ty >  { 
2768+         let  FieldTy :: Ty ( ty)  = & self  else  { 
2769+             panic ! ( "expect a type, found {self:?}" ) ; 
2770+         } ; 
2771+         ty
2772+     } 
2773+ } 
2774+ 
26922775/// Field definition in a struct, variant or union. 
26932776/// 
26942777/// E.g., `bar: usize` as in `struct Foo { bar: usize }`. 
@@ -2700,7 +2783,7 @@ pub struct FieldDef {
27002783    pub  vis :  Visibility , 
27012784    pub  ident :  Option < Ident > , 
27022785
2703-     pub  ty :  P < Ty > , 
2786+     pub  ty :  FieldTy , 
27042787    pub  is_placeholder :  bool , 
27052788} 
27062789
@@ -2730,6 +2813,27 @@ impl VariantData {
27302813        } 
27312814    } 
27322815
2816+     /// Return all fields of this variant, with anonymous structs or unions flattened. 
2817+ pub  fn  all_fields ( & self )  -> AllFields < ' _ >  { 
2818+         AllFields  {  iters :  smallvec:: smallvec![ self . fields( ) . iter( ) ]  } 
2819+     } 
2820+ 
2821+     /// Return whether this variant contains inner anonymous unions. 
2822+ pub  fn  find_inner_union ( & self )  -> Option < Span >  { 
2823+         // We only check the record-like structs 
2824+         let  VariantData :: Struct ( fields,  ..)  = self  else  {  return  None  } ; 
2825+         fn  find_union ( fields :  & [ FieldDef ] )  -> Option < Span >  { 
2826+             fields. iter ( ) . find_map ( |field| { 
2827+                 let  FieldTy :: AnonRecord ( anon_record)  = & field. ty  else  {  return  None  } ; 
2828+                 anon_record
2829+                     . is_union ( ) 
2830+                     . then ( || anon_record. span ) 
2831+                     . or_else ( || find_union ( & anon_record. fields ) ) 
2832+             } ) 
2833+         } 
2834+         find_union ( & fields) 
2835+     } 
2836+ 
27332837    /// Return the `NodeId` of this variant's constructor, if it has one. 
27342838pub  fn  ctor_node_id ( & self )  -> Option < NodeId >  { 
27352839        match  * self  { 
@@ -2739,6 +2843,44 @@ impl VariantData {
27392843    } 
27402844} 
27412845
2846+ /// Iterator of all fields of a `VariantData`. 
2847+ /// 
2848+ /// It iterates on the field tree in preorder, where the unnamed fields with anonymous structs or unions 
2849+ /// are flattened to their inner fields. 
2850+ pub  struct  AllFields < ' a >  { 
2851+     iters :  smallvec:: SmallVec < [ std:: slice:: Iter < ' a ,  FieldDef > ;  1 ] > , 
2852+ } 
2853+ 
2854+ impl < ' a >  Iterator  for  AllFields < ' a >  { 
2855+     type  Item  = & ' a  FieldDef ; 
2856+ 
2857+     fn  next ( & mut  self )  -> Option < Self :: Item >  { 
2858+         let  mut  top = self . iters . last_mut ( ) ?; 
2859+         loop  { 
2860+             if  let  Some ( field)  = top. next ( )  { 
2861+                 if  let  FieldTy :: AnonRecord ( anon_record)  = & field. ty  { 
2862+                     self . iters . push ( anon_record. fields . iter ( ) ) ; 
2863+                     top = self . iters . last_mut ( ) . unwrap ( ) ; 
2864+                     continue ; 
2865+                 } 
2866+                 return  Some ( field) ; 
2867+             } 
2868+             self . iters . pop ( ) ; 
2869+             top = self . iters . last_mut ( ) ?; 
2870+         } 
2871+     } 
2872+ 
2873+     fn  size_hint ( & self )  -> ( usize ,  Option < usize > )  { 
2874+         match  & self . iters [ ..]  { 
2875+             [ ]  => ( 0 ,  Some ( 0 ) ) , 
2876+             [ single]  => ( single. size_hint ( ) . 0 ,  None ) , 
2877+             [ first,  ..,  last]  => ( first. size_hint ( ) . 0  + last. size_hint ( ) . 0 ,  None ) , 
2878+         } 
2879+     } 
2880+ } 
2881+ 
2882+ impl  std:: iter:: FusedIterator  for  AllFields < ' _ >  { } 
2883+ 
27422884/// An item definition. 
27432885#[ derive( Clone ,  Encodable ,  Decodable ,  Debug ) ]  
27442886pub  struct  Item < K  = ItemKind >  { 
0 commit comments