@@ -12,6 +12,7 @@ use hir_expand::{
1212use intern:: { sym, Symbol } ;
1313use la_arena:: { ArenaMap , Idx , RawIdx } ;
1414use mbe:: DelimiterKind ;
15+ use rustc_abi:: ReprOptions ;
1516use syntax:: {
1617 ast:: { self , HasAttrs } ,
1718 AstPtr ,
@@ -83,7 +84,7 @@ impl Attrs {
8384 let krate = loc. parent . lookup ( db) . container . krate ;
8485 item_tree = loc. id . item_tree ( db) ;
8586 let variant = & item_tree[ loc. id . value ] ;
86- ( FieldParent :: Variant ( loc. id . value ) , & variant. fields , krate)
87+ ( FieldParent :: EnumVariant ( loc. id . value ) , & variant. fields , krate)
8788 }
8889 VariantId :: StructId ( it) => {
8990 let loc = it. lookup ( db) ;
@@ -221,6 +222,130 @@ impl Attrs {
221222 pub fn is_unstable ( & self ) -> bool {
222223 self . by_key ( & sym:: unstable) . exists ( )
223224 }
225+
226+ pub fn rustc_legacy_const_generics ( & self ) -> Option < Box < Box < [ u32 ] > > > {
227+ self . by_key ( & sym:: rustc_legacy_const_generics)
228+ . tt_values ( )
229+ . next ( )
230+ . map ( parse_rustc_legacy_const_generics)
231+ . filter ( |it| !it. is_empty ( ) )
232+ . map ( Box :: new)
233+ }
234+
235+ pub fn repr ( & self ) -> Option < ReprOptions > {
236+ self . by_key ( & sym:: repr) . tt_values ( ) . find_map ( parse_repr_tt)
237+ }
238+ }
239+
240+ fn parse_rustc_legacy_const_generics ( tt : & crate :: tt:: TopSubtree ) -> Box < [ u32 ] > {
241+ let mut indices = Vec :: new ( ) ;
242+ let mut iter = tt. iter ( ) ;
243+ while let ( Some ( first) , second) = ( iter. next ( ) , iter. next ( ) ) {
244+ match first {
245+ TtElement :: Leaf ( tt:: Leaf :: Literal ( lit) ) => match lit. symbol . as_str ( ) . parse ( ) {
246+ Ok ( index) => indices. push ( index) ,
247+ Err ( _) => break ,
248+ } ,
249+ _ => break ,
250+ }
251+
252+ if let Some ( comma) = second {
253+ match comma {
254+ TtElement :: Leaf ( tt:: Leaf :: Punct ( punct) ) if punct. char == ',' => { }
255+ _ => break ,
256+ }
257+ }
258+ }
259+
260+ indices. into_boxed_slice ( )
261+ }
262+
263+ fn parse_repr_tt ( tt : & crate :: tt:: TopSubtree ) -> Option < ReprOptions > {
264+ use crate :: builtin_type:: { BuiltinInt , BuiltinUint } ;
265+ use rustc_abi:: { Align , Integer , IntegerType , ReprFlags , ReprOptions } ;
266+
267+ match tt. top_subtree ( ) . delimiter {
268+ tt:: Delimiter { kind : DelimiterKind :: Parenthesis , .. } => { }
269+ _ => return None ,
270+ }
271+
272+ let mut flags = ReprFlags :: empty ( ) ;
273+ let mut int = None ;
274+ let mut max_align: Option < Align > = None ;
275+ let mut min_pack: Option < Align > = None ;
276+
277+ let mut tts = tt. iter ( ) ;
278+ while let Some ( tt) = tts. next ( ) {
279+ if let TtElement :: Leaf ( tt:: Leaf :: Ident ( ident) ) = tt {
280+ flags. insert ( match & ident. sym {
281+ s if * s == sym:: packed => {
282+ let pack = if let Some ( TtElement :: Subtree ( _, mut tt_iter) ) = tts. peek ( ) {
283+ tts. next ( ) ;
284+ if let Some ( TtElement :: Leaf ( tt:: Leaf :: Literal ( lit) ) ) = tt_iter. next ( ) {
285+ lit. symbol . as_str ( ) . parse ( ) . unwrap_or_default ( )
286+ } else {
287+ 0
288+ }
289+ } else {
290+ 0
291+ } ;
292+ let pack = Align :: from_bytes ( pack) . unwrap_or ( Align :: ONE ) ;
293+ min_pack =
294+ Some ( if let Some ( min_pack) = min_pack { min_pack. min ( pack) } else { pack } ) ;
295+ ReprFlags :: empty ( )
296+ }
297+ s if * s == sym:: align => {
298+ if let Some ( TtElement :: Subtree ( _, mut tt_iter) ) = tts. peek ( ) {
299+ tts. next ( ) ;
300+ if let Some ( TtElement :: Leaf ( tt:: Leaf :: Literal ( lit) ) ) = tt_iter. next ( ) {
301+ if let Ok ( align) = lit. symbol . as_str ( ) . parse ( ) {
302+ let align = Align :: from_bytes ( align) . ok ( ) ;
303+ max_align = max_align. max ( align) ;
304+ }
305+ }
306+ }
307+ ReprFlags :: empty ( )
308+ }
309+ s if * s == sym:: C => ReprFlags :: IS_C ,
310+ s if * s == sym:: transparent => ReprFlags :: IS_TRANSPARENT ,
311+ s if * s == sym:: simd => ReprFlags :: IS_SIMD ,
312+ repr => {
313+ if let Some ( builtin) = BuiltinInt :: from_suffix_sym ( repr)
314+ . map ( Either :: Left )
315+ . or_else ( || BuiltinUint :: from_suffix_sym ( repr) . map ( Either :: Right ) )
316+ {
317+ int = Some ( match builtin {
318+ Either :: Left ( bi) => match bi {
319+ BuiltinInt :: Isize => IntegerType :: Pointer ( true ) ,
320+ BuiltinInt :: I8 => IntegerType :: Fixed ( Integer :: I8 , true ) ,
321+ BuiltinInt :: I16 => IntegerType :: Fixed ( Integer :: I16 , true ) ,
322+ BuiltinInt :: I32 => IntegerType :: Fixed ( Integer :: I32 , true ) ,
323+ BuiltinInt :: I64 => IntegerType :: Fixed ( Integer :: I64 , true ) ,
324+ BuiltinInt :: I128 => IntegerType :: Fixed ( Integer :: I128 , true ) ,
325+ } ,
326+ Either :: Right ( bu) => match bu {
327+ BuiltinUint :: Usize => IntegerType :: Pointer ( false ) ,
328+ BuiltinUint :: U8 => IntegerType :: Fixed ( Integer :: I8 , false ) ,
329+ BuiltinUint :: U16 => IntegerType :: Fixed ( Integer :: I16 , false ) ,
330+ BuiltinUint :: U32 => IntegerType :: Fixed ( Integer :: I32 , false ) ,
331+ BuiltinUint :: U64 => IntegerType :: Fixed ( Integer :: I64 , false ) ,
332+ BuiltinUint :: U128 => IntegerType :: Fixed ( Integer :: I128 , false ) ,
333+ } ,
334+ } ) ;
335+ }
336+ ReprFlags :: empty ( )
337+ }
338+ } )
339+ }
340+ }
341+
342+ Some ( ReprOptions {
343+ int,
344+ align : max_align,
345+ pack : min_pack,
346+ flags,
347+ field_shuffle_seed : rustc_hashes:: Hash64 :: ZERO ,
348+ } )
224349}
225350
226351#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
0 commit comments