@@ -233,7 +233,12 @@ impl Attrs {
233
233
}
234
234
235
235
pub fn repr ( & self ) -> Option < ReprOptions > {
236
- self . by_key ( & sym:: repr) . tt_values ( ) . find_map ( parse_repr_tt)
236
+ self . by_key ( & sym:: repr) . tt_values ( ) . filter_map ( parse_repr_tt) . fold ( None , |acc, repr| {
237
+ acc. map_or ( Some ( repr) , |mut acc| {
238
+ merge_repr ( & mut acc, repr) ;
239
+ Some ( acc)
240
+ } )
241
+ } )
237
242
}
238
243
}
239
244
@@ -260,6 +265,19 @@ fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> {
260
265
indices. into_boxed_slice ( )
261
266
}
262
267
268
+ fn merge_repr ( this : & mut ReprOptions , other : ReprOptions ) {
269
+ let ReprOptions { int, align, pack, flags, field_shuffle_seed : _ } = this;
270
+ flags. insert ( other. flags ) ;
271
+ * align = ( * align) . max ( other. align ) ;
272
+ * pack = match ( * pack, other. pack ) {
273
+ ( Some ( pack) , None ) | ( None , Some ( pack) ) => Some ( pack) ,
274
+ _ => ( * pack) . min ( other. pack ) ,
275
+ } ;
276
+ if other. int . is_some ( ) {
277
+ * int = other. int ;
278
+ }
279
+ }
280
+
263
281
fn parse_repr_tt ( tt : & crate :: tt:: TopSubtree ) -> Option < ReprOptions > {
264
282
use crate :: builtin_type:: { BuiltinInt , BuiltinUint } ;
265
283
use rustc_abi:: { Align , Integer , IntegerType , ReprFlags , ReprOptions } ;
@@ -269,83 +287,76 @@ fn parse_repr_tt(tt: &crate::tt::TopSubtree) -> Option<ReprOptions> {
269
287
_ => return None ,
270
288
}
271
289
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
-
290
+ let mut acc = ReprOptions :: default ( ) ;
277
291
let mut tts = tt. iter ( ) ;
278
292
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
- }
293
+ let TtElement :: Leaf ( tt:: Leaf :: Ident ( ident) ) = tt else {
294
+ continue ;
295
+ } ;
296
+ let repr = match & ident. sym {
297
+ s if * s == sym:: packed => {
298
+ let pack = 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
+ lit. symbol . as_str ( ) . parse ( ) . unwrap_or_default ( )
289
302
} else {
290
303
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
- }
304
+ }
305
+ } else {
306
+ 0
307
+ } ;
308
+ let pack = Some ( Align :: from_bytes ( pack ) . unwrap_or ( Align :: ONE ) ) ;
309
+ ReprOptions { pack , .. Default :: default ( ) }
310
+ }
311
+ s if * s == sym :: align => {
312
+ let mut align = None ;
313
+ if let Some ( TtElement :: Subtree ( _ , mut tt_iter ) ) = tts . peek ( ) {
314
+ tts . next ( ) ;
315
+ if let Some ( TtElement :: Leaf ( tt :: Leaf :: Literal ( lit ) ) ) = tt_iter . next ( ) {
316
+ if let Ok ( a ) = lit . symbol . as_str ( ) . parse ( ) {
317
+ align = Align :: from_bytes ( a ) . ok ( ) ;
305
318
}
306
319
}
307
- ReprFlags :: empty ( )
308
320
}
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 ( )
321
+ ReprOptions { align, ..Default :: default ( ) }
322
+ }
323
+ s if * s == sym:: C => ReprOptions { flags : ReprFlags :: IS_C , ..Default :: default ( ) } ,
324
+ s if * s == sym:: transparent => {
325
+ ReprOptions { flags : ReprFlags :: IS_TRANSPARENT , ..Default :: default ( ) }
326
+ }
327
+ s if * s == sym:: simd => ReprOptions { flags : ReprFlags :: IS_SIMD , ..Default :: default ( ) } ,
328
+ repr => {
329
+ let mut int = None ;
330
+ if let Some ( builtin) = BuiltinInt :: from_suffix_sym ( repr)
331
+ . map ( Either :: Left )
332
+ . or_else ( || BuiltinUint :: from_suffix_sym ( repr) . map ( Either :: Right ) )
333
+ {
334
+ int = Some ( match builtin {
335
+ Either :: Left ( bi) => match bi {
336
+ BuiltinInt :: Isize => IntegerType :: Pointer ( true ) ,
337
+ BuiltinInt :: I8 => IntegerType :: Fixed ( Integer :: I8 , true ) ,
338
+ BuiltinInt :: I16 => IntegerType :: Fixed ( Integer :: I16 , true ) ,
339
+ BuiltinInt :: I32 => IntegerType :: Fixed ( Integer :: I32 , true ) ,
340
+ BuiltinInt :: I64 => IntegerType :: Fixed ( Integer :: I64 , true ) ,
341
+ BuiltinInt :: I128 => IntegerType :: Fixed ( Integer :: I128 , true ) ,
342
+ } ,
343
+ Either :: Right ( bu) => match bu {
344
+ BuiltinUint :: Usize => IntegerType :: Pointer ( false ) ,
345
+ BuiltinUint :: U8 => IntegerType :: Fixed ( Integer :: I8 , false ) ,
346
+ BuiltinUint :: U16 => IntegerType :: Fixed ( Integer :: I16 , false ) ,
347
+ BuiltinUint :: U32 => IntegerType :: Fixed ( Integer :: I32 , false ) ,
348
+ BuiltinUint :: U64 => IntegerType :: Fixed ( Integer :: I64 , false ) ,
349
+ BuiltinUint :: U128 => IntegerType :: Fixed ( Integer :: I128 , false ) ,
350
+ } ,
351
+ } ) ;
337
352
}
338
- } )
339
- }
353
+ ReprOptions { int, ..Default :: default ( ) }
354
+ }
355
+ } ;
356
+ merge_repr ( & mut acc, repr) ;
340
357
}
341
358
342
- Some ( ReprOptions {
343
- int,
344
- align : max_align,
345
- pack : min_pack,
346
- flags,
347
- field_shuffle_seed : rustc_hashes:: Hash64 :: ZERO ,
348
- } )
359
+ Some ( acc)
349
360
}
350
361
351
362
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
0 commit comments