@@ -12,6 +12,7 @@ use hir_expand::{
12
12
use intern:: { sym, Symbol } ;
13
13
use la_arena:: { ArenaMap , Idx , RawIdx } ;
14
14
use mbe:: DelimiterKind ;
15
+ use rustc_abi:: ReprOptions ;
15
16
use syntax:: {
16
17
ast:: { self , HasAttrs } ,
17
18
AstPtr ,
@@ -83,7 +84,7 @@ impl Attrs {
83
84
let krate = loc. parent . lookup ( db) . container . krate ;
84
85
item_tree = loc. id . item_tree ( db) ;
85
86
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)
87
88
}
88
89
VariantId :: StructId ( it) => {
89
90
let loc = it. lookup ( db) ;
@@ -221,6 +222,130 @@ impl Attrs {
221
222
pub fn is_unstable ( & self ) -> bool {
222
223
self . by_key ( & sym:: unstable) . exists ( )
223
224
}
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
+ } )
224
349
}
225
350
226
351
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
0 commit comments