@@ -382,6 +382,23 @@ impl Integer {
382
382
}
383
383
}
384
384
385
+ pub fn to_attr ( & self , signed : bool ) -> attr:: IntType {
386
+ match ( * self , signed) {
387
+ ( I1 , false ) => attr:: IntType :: UnsignedInt ( UintTy :: U8 ) ,
388
+ ( I8 , false ) => attr:: IntType :: UnsignedInt ( UintTy :: U8 ) ,
389
+ ( I16 , false ) => attr:: IntType :: UnsignedInt ( UintTy :: U16 ) ,
390
+ ( I32 , false ) => attr:: IntType :: UnsignedInt ( UintTy :: U32 ) ,
391
+ ( I64 , false ) => attr:: IntType :: UnsignedInt ( UintTy :: U64 ) ,
392
+ ( I128 , false ) => attr:: IntType :: UnsignedInt ( UintTy :: U128 ) ,
393
+ ( I1 , true ) => attr:: IntType :: SignedInt ( IntTy :: I8 ) ,
394
+ ( I8 , true ) => attr:: IntType :: SignedInt ( IntTy :: I8 ) ,
395
+ ( I16 , true ) => attr:: IntType :: SignedInt ( IntTy :: I16 ) ,
396
+ ( I32 , true ) => attr:: IntType :: SignedInt ( IntTy :: I32 ) ,
397
+ ( I64 , true ) => attr:: IntType :: SignedInt ( IntTy :: I64 ) ,
398
+ ( I128 , true ) => attr:: IntType :: SignedInt ( IntTy :: I128 ) ,
399
+ }
400
+ }
401
+
385
402
/// Find the smallest Integer type which can represent the signed value.
386
403
pub fn fit_signed ( x : i64 ) -> Integer {
387
404
match x {
@@ -436,13 +453,13 @@ impl Integer {
436
453
/// signed discriminant range and #[repr] attribute.
437
454
/// N.B.: u64 values above i64::MAX will be treated as signed, but
438
455
/// that shouldn't affect anything, other than maybe debuginfo.
439
- fn repr_discr ( tcx : TyCtxt , ty : Ty , hints : & [ attr:: ReprAttr ] , min : i64 , max : i64 )
440
- -> ( Integer , bool ) {
456
+ pub fn repr_discr ( tcx : TyCtxt , hints : & [ attr:: ReprAttr ] , min : i128 , max : i128 )
457
+ -> ( Integer , bool ) {
441
458
// Theoretically, negative values could be larger in unsigned representation
442
459
// than the unsigned representation of the signed minimum. However, if there
443
460
// are any negative values, the only valid unsigned representation is u64
444
461
// which can fit all i64 values, so the result remains unaffected.
445
- let unsigned_fit = Integer :: fit_unsigned ( cmp:: max ( min as u64 , max as u64 ) ) ;
462
+ let unsigned_fit = Integer :: fit_unsigned ( cmp:: max ( min as u128 , max as u128 ) ) ;
446
463
let signed_fit = cmp:: max ( Integer :: fit_signed ( min) , Integer :: fit_signed ( max) ) ;
447
464
448
465
let mut min_from_extern = None ;
@@ -455,7 +472,7 @@ impl Integer {
455
472
let fit = if ity. is_signed ( ) { signed_fit } else { unsigned_fit } ;
456
473
if discr < fit {
457
474
bug ! ( "Integer::repr_discr: `#[repr]` hint too small for \
458
- discriminant range of enum `{}" , ty )
475
+ discriminant range of enum" )
459
476
}
460
477
return ( discr, ity. is_signed ( ) ) ;
461
478
}
@@ -471,16 +488,15 @@ impl Integer {
471
488
}
472
489
attr:: ReprAny => { } ,
473
490
attr:: ReprPacked => {
474
- bug ! ( "Integer::repr_discr: found #[repr(packed)] on enum `{}" , ty ) ;
491
+ bug ! ( "Integer::repr_discr: found #[repr(packed)] on enum" ) ;
475
492
}
476
493
attr:: ReprSimd => {
477
- bug ! ( "Integer::repr_discr: found #[repr(simd)] on enum `{}" , ty ) ;
494
+ bug ! ( "Integer::repr_discr: found #[repr(simd)] on enum" ) ;
478
495
}
479
496
}
480
497
}
481
498
482
499
let at_least = min_from_extern. unwrap_or ( min_default) ;
483
-
484
500
// If there are no negative values, we can use the unsigned fit.
485
501
if min >= 0 {
486
502
( cmp:: max ( unsigned_fit, at_least) , false )
@@ -1220,9 +1236,8 @@ impl<'a, 'gcx, 'tcx> Layout {
1220
1236
1221
1237
// FIXME: should handle i128? signed-value based impl is weird and hard to
1222
1238
// grok.
1223
- let ( discr, signed) = Integer :: repr_discr ( tcx, ty, & hints[ ..] ,
1224
- min,
1225
- max) ;
1239
+ let discr = Integer :: from_attr ( & tcx. data_layout , def. discr_ty ) ;
1240
+ let signed = def. discr_ty . is_signed ( ) ;
1226
1241
return success ( CEnum {
1227
1242
discr : discr,
1228
1243
signed : signed,
@@ -1337,10 +1352,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1337
1352
}
1338
1353
1339
1354
// The general case.
1340
- let discr_max = ( variants. len ( ) - 1 ) as i64 ;
1341
- assert ! ( discr_max >= 0 ) ;
1342
- let ( min_ity, _) = Integer :: repr_discr ( tcx, ty, & hints[ ..] , 0 , discr_max) ;
1343
-
1355
+ let min_ity = Integer :: from_attr ( & tcx. data_layout , def. discr_ty ) ;
1344
1356
let mut align = dl. aggregate_align ;
1345
1357
let mut size = Size :: from_bytes ( 0 ) ;
1346
1358
0 commit comments