@@ -15,7 +15,7 @@ pub use self::Primitive::*;
15
15
use infer:: InferCtxt ;
16
16
use session:: Session ;
17
17
use traits;
18
- use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
18
+ use ty:: { self , Ty , TyCtxt , TypeFoldable , ReprOptions } ;
19
19
20
20
use syntax:: ast:: { FloatTy , IntTy , UintTy } ;
21
21
use syntax:: attr;
@@ -437,7 +437,7 @@ impl Integer {
437
437
/// signed discriminant range and #[repr] attribute.
438
438
/// N.B.: u64 values above i64::MAX will be treated as signed, but
439
439
/// that shouldn't affect anything, other than maybe debuginfo.
440
- fn repr_discr ( tcx : TyCtxt , ty : Ty , hints : & [ attr :: ReprAttr ] , min : i64 , max : i64 )
440
+ fn repr_discr ( tcx : TyCtxt , ty : Ty , repr : & ReprOptions , min : i64 , max : i64 )
441
441
-> ( Integer , bool ) {
442
442
// Theoretically, negative values could be larger in unsigned representation
443
443
// than the unsigned representation of the signed minimum. However, if there
@@ -449,34 +449,24 @@ impl Integer {
449
449
let mut min_from_extern = None ;
450
450
let min_default = I8 ;
451
451
452
- for & r in hints. iter ( ) {
453
- match r {
454
- attr:: ReprInt ( ity) => {
455
- let discr = Integer :: from_attr ( & tcx. data_layout , ity) ;
456
- let fit = if ity. is_signed ( ) { signed_fit } else { unsigned_fit } ;
457
- if discr < fit {
458
- bug ! ( "Integer::repr_discr: `#[repr]` hint too small for \
459
- discriminant range of enum `{}", ty)
460
- }
461
- return ( discr, ity. is_signed ( ) ) ;
462
- }
463
- attr:: ReprExtern => {
464
- match & tcx. sess . target . target . arch [ ..] {
465
- // WARNING: the ARM EABI has two variants; the one corresponding
466
- // to `at_least == I32` appears to be used on Linux and NetBSD,
467
- // but some systems may use the variant corresponding to no
468
- // lower bound. However, we don't run on those yet...?
469
- "arm" => min_from_extern = Some ( I32 ) ,
470
- _ => min_from_extern = Some ( I32 ) ,
471
- }
472
- }
473
- attr:: ReprAny => { } ,
474
- attr:: ReprPacked => {
475
- bug ! ( "Integer::repr_discr: found #[repr(packed)] on enum `{}" , ty) ;
476
- }
477
- attr:: ReprSimd => {
478
- bug ! ( "Integer::repr_discr: found #[repr(simd)] on enum `{}" , ty) ;
479
- }
452
+ if let Some ( ity) = repr. int {
453
+ let discr = Integer :: from_attr ( & tcx. data_layout , ity) ;
454
+ let fit = if ity. is_signed ( ) { signed_fit } else { unsigned_fit } ;
455
+ if discr < fit {
456
+ bug ! ( "Integer::repr_discr: `#[repr]` hint too small for \
457
+ discriminant range of enum `{}", ty)
458
+ }
459
+ return ( discr, ity. is_signed ( ) ) ;
460
+ }
461
+
462
+ if repr. c {
463
+ match & tcx. sess . target . target . arch [ ..] {
464
+ // WARNING: the ARM EABI has two variants; the one corresponding
465
+ // to `at_least == I32` appears to be used on Linux and NetBSD,
466
+ // but some systems may use the variant corresponding to no
467
+ // lower bound. However, we don't run on those yet...?
468
+ "arm" => min_from_extern = Some ( I32 ) ,
469
+ _ => min_from_extern = Some ( I32 ) ,
480
470
}
481
471
}
482
472
@@ -568,9 +558,9 @@ enum StructKind {
568
558
impl < ' a , ' gcx , ' tcx > Struct {
569
559
// FIXME(camlorn): reprs need a better representation to deal with multiple reprs on one type.
570
560
fn new ( dl : & TargetDataLayout , fields : & Vec < & ' a Layout > ,
571
- reprs : & [ attr :: ReprAttr ] , kind : StructKind ,
561
+ repr : & ReprOptions , kind : StructKind ,
572
562
scapegoat : Ty < ' gcx > ) -> Result < Struct , LayoutError < ' gcx > > {
573
- let packed = reprs . contains ( & attr :: ReprPacked ) ;
563
+ let packed = repr . packed ;
574
564
let mut ret = Struct {
575
565
align : if packed { dl. i8_align } else { dl. aggregate_align } ,
576
566
packed : packed,
@@ -580,27 +570,16 @@ impl<'a, 'gcx, 'tcx> Struct {
580
570
min_size : Size :: from_bytes ( 0 ) ,
581
571
} ;
582
572
583
- // Anything with ReprExtern or ReprPacked doesn't optimize.
573
+ // Anything with repr(C) or repr(packed) doesn't optimize.
584
574
// Neither do 1-member and 2-member structs.
585
575
// In addition, code in trans assume that 2-element structs can become pairs.
586
576
// It's easier to just short-circuit here.
587
- let mut can_optimize = fields. len ( ) > 2 || StructKind :: EnumVariant == kind;
588
- if can_optimize {
589
- // This exhaustive match makes new reprs force the adder to modify this function.
590
- // Otherwise, things can silently break.
591
- // Note the inversion, return true to stop optimizing.
592
- can_optimize = !reprs. iter ( ) . any ( |r| {
593
- match * r {
594
- attr:: ReprAny | attr:: ReprInt ( _) => false ,
595
- attr:: ReprExtern | attr:: ReprPacked => true ,
596
- attr:: ReprSimd => bug ! ( "Simd vectors should be represented as layout::Vector" )
597
- }
598
- } ) ;
599
- }
577
+ let mut can_optimize = ( fields. len ( ) > 2 || StructKind :: EnumVariant == kind)
578
+ && ! ( repr. c || repr. packed ) ;
600
579
601
580
// Disable field reordering until we can decide what to do.
602
581
// The odd pattern here avoids a warning about the value never being read.
603
- if can_optimize { can_optimize = false }
582
+ if can_optimize { can_optimize = false ; }
604
583
605
584
let ( optimize, sort_ascending) = match kind {
606
585
StructKind :: AlwaysSizedUnivariant => ( can_optimize, false ) ,
@@ -1092,7 +1071,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1092
1071
1093
1072
// The never type.
1094
1073
ty:: TyNever => Univariant {
1095
- variant : Struct :: new ( dl, & vec ! [ ] , & [ ] ,
1074
+ variant : Struct :: new ( dl, & vec ! [ ] , & ReprOptions :: default ( ) ,
1096
1075
StructKind :: AlwaysSizedUnivariant , ty) ?,
1097
1076
non_zero : false
1098
1077
} ,
@@ -1135,12 +1114,12 @@ impl<'a, 'gcx, 'tcx> Layout {
1135
1114
ty:: TyFnDef ( ..) => {
1136
1115
Univariant {
1137
1116
variant : Struct :: new ( dl, & vec ! [ ] ,
1138
- & [ ] , StructKind :: AlwaysSizedUnivariant , ty) ?,
1117
+ & ReprOptions :: default ( ) , StructKind :: AlwaysSizedUnivariant , ty) ?,
1139
1118
non_zero : false
1140
1119
}
1141
1120
}
1142
1121
ty:: TyDynamic ( ..) => {
1143
- let mut unit = Struct :: new ( dl, & vec ! [ ] , & [ ] ,
1122
+ let mut unit = Struct :: new ( dl, & vec ! [ ] , & ReprOptions :: default ( ) ,
1144
1123
StructKind :: AlwaysSizedUnivariant , ty) ?;
1145
1124
unit. sized = false ;
1146
1125
Univariant { variant : unit, non_zero : false }
@@ -1152,7 +1131,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1152
1131
let st = Struct :: new ( dl,
1153
1132
& tys. map ( |ty| ty. layout ( infcx) )
1154
1133
. collect :: < Result < Vec < _ > , _ > > ( ) ?,
1155
- & [ ] ,
1134
+ & ReprOptions :: default ( ) ,
1156
1135
StructKind :: AlwaysSizedUnivariant , ty) ?;
1157
1136
Univariant { variant : st, non_zero : false }
1158
1137
}
@@ -1163,7 +1142,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1163
1142
let st = Struct :: new ( dl,
1164
1143
& tys. iter ( ) . map ( |ty| ty. layout ( infcx) )
1165
1144
. collect :: < Result < Vec < _ > , _ > > ( ) ?,
1166
- & [ ] , StructKind :: AlwaysSizedUnivariant , ty) ?;
1145
+ & ReprOptions :: default ( ) , StructKind :: AlwaysSizedUnivariant , ty) ?;
1167
1146
Univariant { variant : st, non_zero : false }
1168
1147
}
1169
1148
@@ -1187,16 +1166,13 @@ impl<'a, 'gcx, 'tcx> Layout {
1187
1166
1188
1167
// ADTs.
1189
1168
ty:: TyAdt ( def, substs) => {
1190
- let hints = & tcx. lookup_repr_hints ( def. did ) [ ..] ;
1191
-
1192
1169
if def. variants . is_empty ( ) {
1193
1170
// Uninhabitable; represent as unit
1194
1171
// (Typechecking will reject discriminant-sizing attrs.)
1195
- assert_eq ! ( hints. len( ) , 0 ) ;
1196
1172
1197
1173
return success ( Univariant {
1198
1174
variant : Struct :: new ( dl, & vec ! [ ] ,
1199
- & hints [ .. ] , StructKind :: AlwaysSizedUnivariant , ty) ?,
1175
+ & def . repr , StructKind :: AlwaysSizedUnivariant , ty) ?,
1200
1176
non_zero : false
1201
1177
} ) ;
1202
1178
}
@@ -1219,7 +1195,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1219
1195
1220
1196
// FIXME: should handle i128? signed-value based impl is weird and hard to
1221
1197
// grok.
1222
- let ( discr, signed) = Integer :: repr_discr ( tcx, ty, & hints [ .. ] ,
1198
+ let ( discr, signed) = Integer :: repr_discr ( tcx, ty, & def . repr ,
1223
1199
min,
1224
1200
max) ;
1225
1201
return success ( CEnum {
@@ -1232,7 +1208,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1232
1208
} ) ;
1233
1209
}
1234
1210
1235
- if !def. is_enum ( ) || def. variants . len ( ) == 1 && hints . is_empty ( ) {
1211
+ if !def. is_enum ( ) || def. variants . len ( ) == 1 {
1236
1212
// Struct, or union, or univariant enum equivalent to a struct.
1237
1213
// (Typechecking will reject discriminant-sizing attrs.)
1238
1214
@@ -1259,7 +1235,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1259
1235
un. extend ( dl, fields. iter ( ) . map ( |& f| Ok ( f) ) , ty) ?;
1260
1236
UntaggedUnion { variants : un }
1261
1237
} else {
1262
- let st = Struct :: new ( dl, & fields, & hints [ .. ] ,
1238
+ let st = Struct :: new ( dl, & fields, & def . repr ,
1263
1239
kind, ty) ?;
1264
1240
let non_zero = Some ( def. did ) == tcx. lang_items . non_zero ( ) ;
1265
1241
Univariant { variant : st, non_zero : non_zero }
@@ -1282,7 +1258,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1282
1258
v. fields . iter ( ) . map ( |field| field. ty ( tcx, substs) ) . collect :: < Vec < _ > > ( )
1283
1259
} ) . collect :: < Vec < _ > > ( ) ;
1284
1260
1285
- if variants. len ( ) == 2 && hints . is_empty ( ) {
1261
+ if variants. len ( ) == 2 && !def . repr . c {
1286
1262
// Nullable pointer optimization
1287
1263
for discr in 0 ..2 {
1288
1264
let other_fields = variants[ 1 - discr] . iter ( ) . map ( |ty| {
@@ -1315,7 +1291,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1315
1291
let st = Struct :: new ( dl,
1316
1292
& variants[ discr] . iter ( ) . map ( |ty| ty. layout ( infcx) )
1317
1293
. collect :: < Result < Vec < _ > , _ > > ( ) ?,
1318
- & hints [ .. ] , StructKind :: AlwaysSizedUnivariant , ty) ?;
1294
+ & def . repr , StructKind :: AlwaysSizedUnivariant , ty) ?;
1319
1295
1320
1296
// We have to fix the last element of path here.
1321
1297
let mut i = * path. last ( ) . unwrap ( ) ;
@@ -1338,7 +1314,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1338
1314
// The general case.
1339
1315
let discr_max = ( variants. len ( ) - 1 ) as i64 ;
1340
1316
assert ! ( discr_max >= 0 ) ;
1341
- let ( min_ity, _) = Integer :: repr_discr ( tcx, ty, & hints [ .. ] , 0 , discr_max) ;
1317
+ let ( min_ity, _) = Integer :: repr_discr ( tcx, ty, & def . repr , 0 , discr_max) ;
1342
1318
1343
1319
let mut align = dl. aggregate_align ;
1344
1320
let mut size = Size :: from_bytes ( 0 ) ;
@@ -1356,7 +1332,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1356
1332
fields. insert ( 0 , & discr) ;
1357
1333
let st = Struct :: new ( dl,
1358
1334
& fields,
1359
- & hints [ .. ] , StructKind :: EnumVariant , ty) ?;
1335
+ & def . repr , StructKind :: EnumVariant , ty) ?;
1360
1336
// Find the first field we can't move later
1361
1337
// to make room for a larger discriminant.
1362
1338
// It is important to skip the first field.
0 commit comments