Skip to content

Commit 9af79f5

Browse files
committed
Auto merge of #41329 - nagisa:bitflags-repr-options, r=eddyb
Compress ReprOptions a little bit r? @eddyb
2 parents fef1026 + fcbd898 commit 9af79f5

File tree

7 files changed

+65
-35
lines changed

7 files changed

+65
-35
lines changed

src/librustc/middle/dead.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
162162
hir::ItemStruct(..) | hir::ItemUnion(..) => {
163163
let def_id = self.tcx.hir.local_def_id(item.id);
164164
let def = self.tcx.lookup_adt_def(def_id);
165-
self.struct_has_extern_repr = def.repr.c;
165+
self.struct_has_extern_repr = def.repr.c();
166166

167167
intravisit::walk_item(self, &item);
168168
}

src/librustc/middle/intrinsicck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4646
_ => return ty
4747
};
4848

49-
if def.variants.len() == 2 && !def.repr.c && def.repr.int.is_none() {
49+
if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() {
5050
let data_idx;
5151

5252
if def.variants[0].fields.is_empty() {

src/librustc/ty/layout.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use self::Primitive::*;
1515
use infer::InferCtxt;
1616
use session::Session;
1717
use traits;
18-
use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
18+
use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions, ReprFlags};
1919

2020
use syntax::ast::{FloatTy, IntTy, UintTy};
2121
use syntax::attr;
@@ -479,7 +479,7 @@ impl Integer {
479479
return (discr, ity.is_signed());
480480
}
481481

482-
if repr.c {
482+
if repr.c() {
483483
match &tcx.sess.target.target.arch[..] {
484484
// WARNING: the ARM EABI has two variants; the one corresponding
485485
// to `at_least == I32` appears to be used on Linux and NetBSD,
@@ -583,7 +583,7 @@ impl<'a, 'gcx, 'tcx> Struct {
583583
fn new(dl: &TargetDataLayout, fields: &Vec<&'a Layout>,
584584
repr: &ReprOptions, kind: StructKind,
585585
scapegoat: Ty<'gcx>) -> Result<Struct, LayoutError<'gcx>> {
586-
let packed = repr.packed;
586+
let packed = repr.packed();
587587
let mut ret = Struct {
588588
align: if packed { dl.i8_align } else { dl.aggregate_align },
589589
packed: packed,
@@ -598,7 +598,7 @@ impl<'a, 'gcx, 'tcx> Struct {
598598
// In addition, code in trans assume that 2-element structs can become pairs.
599599
// It's easier to just short-circuit here.
600600
let can_optimize = (fields.len() > 2 || StructKind::EnumVariant == kind)
601-
&& !(repr.c || repr.packed || repr.linear || repr.simd);
601+
&& (repr.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty();
602602

603603
let (optimize, sort_ascending) = match kind {
604604
StructKind::AlwaysSizedUnivariant => (can_optimize, false),
@@ -1177,7 +1177,7 @@ impl<'a, 'gcx, 'tcx> Layout {
11771177
}
11781178

11791179
// SIMD vector types.
1180-
ty::TyAdt(def, ..) if def.repr.simd => {
1180+
ty::TyAdt(def, ..) if def.repr.simd() => {
11811181
let element = ty.simd_type(tcx);
11821182
match *element.layout(infcx)? {
11831183
Scalar { value, .. } => {
@@ -1255,7 +1255,7 @@ impl<'a, 'gcx, 'tcx> Layout {
12551255
field.ty(tcx, substs).layout(infcx)
12561256
}).collect::<Result<Vec<_>, _>>()?;
12571257
let layout = if def.is_union() {
1258-
let mut un = Union::new(dl, def.repr.packed);
1258+
let mut un = Union::new(dl, def.repr.packed());
12591259
un.extend(dl, fields.iter().map(|&f| Ok(f)), ty)?;
12601260
UntaggedUnion { variants: un }
12611261
} else {
@@ -1925,7 +1925,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
19251925
ty::TyTuple(tys, _) => tys[i],
19261926

19271927
// SIMD vector types.
1928-
ty::TyAdt(def, ..) if def.repr.simd => {
1928+
ty::TyAdt(def, ..) if def.repr.simd() => {
19291929
self.ty.simd_type(tcx)
19301930
}
19311931

src/librustc/ty/mod.rs

+51-21
Original file line numberDiff line numberDiff line change
@@ -1438,51 +1438,81 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for AdtDef {
14381438
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
14391439
pub enum AdtKind { Struct, Union, Enum }
14401440

1441+
bitflags! {
1442+
#[derive(RustcEncodable, RustcDecodable, Default)]
1443+
flags ReprFlags: u8 {
1444+
const IS_C = 1 << 0,
1445+
const IS_PACKED = 1 << 1,
1446+
const IS_SIMD = 1 << 2,
1447+
// Internal only for now. If true, don't reorder fields.
1448+
const IS_LINEAR = 1 << 3,
1449+
1450+
// Any of these flags being set prevent field reordering optimisation.
1451+
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits |
1452+
ReprFlags::IS_PACKED.bits |
1453+
ReprFlags::IS_SIMD.bits |
1454+
ReprFlags::IS_LINEAR.bits,
1455+
}
1456+
}
1457+
1458+
impl_stable_hash_for!(struct ReprFlags {
1459+
bits
1460+
});
1461+
1462+
1463+
14411464
/// Represents the repr options provided by the user,
14421465
#[derive(Copy, Clone, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
14431466
pub struct ReprOptions {
1444-
pub c: bool,
1445-
pub packed: bool,
1446-
pub simd: bool,
14471467
pub int: Option<attr::IntType>,
1448-
// Internal only for now. If true, don't reorder fields.
1449-
pub linear: bool,
1468+
pub flags: ReprFlags,
14501469
}
14511470

14521471
impl_stable_hash_for!(struct ReprOptions {
1453-
c,
1454-
packed,
1455-
simd,
14561472
int,
1457-
linear
1473+
flags
14581474
});
14591475

14601476
impl ReprOptions {
14611477
pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions {
1462-
let mut ret = ReprOptions::default();
1478+
let mut flags = ReprFlags::empty();
1479+
let mut size = None;
14631480

14641481
for attr in tcx.get_attrs(did).iter() {
14651482
for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
1466-
match r {
1467-
attr::ReprExtern => ret.c = true,
1468-
attr::ReprPacked => ret.packed = true,
1469-
attr::ReprSimd => ret.simd = true,
1470-
attr::ReprInt(i) => ret.int = Some(i),
1471-
}
1483+
flags.insert(match r {
1484+
attr::ReprExtern => ReprFlags::IS_C,
1485+
attr::ReprPacked => ReprFlags::IS_PACKED,
1486+
attr::ReprSimd => ReprFlags::IS_SIMD,
1487+
attr::ReprInt(i) => {
1488+
size = Some(i);
1489+
ReprFlags::empty()
1490+
},
1491+
});
14721492
}
14731493
}
14741494

14751495
// FIXME(eddyb) This is deprecated and should be removed.
14761496
if tcx.has_attr(did, "simd") {
1477-
ret.simd = true;
1497+
flags.insert(ReprFlags::IS_SIMD);
14781498
}
14791499

14801500
// This is here instead of layout because the choice must make it into metadata.
1481-
ret.linear = !tcx.consider_optimizing(|| format!("Reorder fields of {:?}",
1482-
tcx.item_path_str(did)));
1483-
ret
1501+
if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) {
1502+
flags.insert(ReprFlags::IS_LINEAR);
1503+
}
1504+
ReprOptions { int: size, flags: flags }
14841505
}
14851506

1507+
#[inline]
1508+
pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) }
1509+
#[inline]
1510+
pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) }
1511+
#[inline]
1512+
pub fn packed(&self) -> bool { self.flags.contains(ReprFlags::IS_PACKED) }
1513+
#[inline]
1514+
pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) }
1515+
14861516
pub fn discr_type(&self) -> attr::IntType {
14871517
self.int.unwrap_or(attr::SignedInt(ast::IntTy::Is))
14881518
}
@@ -1491,7 +1521,7 @@ impl ReprOptions {
14911521
/// layout" optimizations, such as representing `Foo<&T>` as a
14921522
/// single pointer.
14931523
pub fn inhibit_enum_layout_opt(&self) -> bool {
1494-
self.c || self.int.is_some()
1524+
self.c() || self.int.is_some()
14951525
}
14961526
}
14971527

src/librustc/ty/sty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
10951095
#[inline]
10961096
pub fn is_simd(&self) -> bool {
10971097
match self.sty {
1098-
TyAdt(def, _) => def.repr.simd,
1098+
TyAdt(def, _) => def.repr.simd(),
10991099
_ => false,
11001100
}
11011101
}

src/librustc_lint/types.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
416416
}
417417
match def.adt_kind() {
418418
AdtKind::Struct => {
419-
if !def.repr.c {
419+
if !def.repr.c() {
420420
return FfiUnsafe("found struct without foreign-function-safe \
421421
representation annotation in foreign module, \
422422
consider adding a #[repr(C)] attribute to the type");
@@ -450,7 +450,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
450450
if all_phantom { FfiPhantom } else { FfiSafe }
451451
}
452452
AdtKind::Union => {
453-
if !def.repr.c {
453+
if !def.repr.c() {
454454
return FfiUnsafe("found union without foreign-function-safe \
455455
representation annotation in foreign module, \
456456
consider adding a #[repr(C)] attribute to the type");
@@ -489,7 +489,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
489489

490490
// Check for a repr() attribute to specify the size of the
491491
// discriminant.
492-
if !def.repr.c && def.repr.int.is_none() {
492+
if !def.repr.c() && def.repr.int.is_none() {
493493
// Special-case types like `Option<extern fn()>`.
494494
if !is_repr_nullable_ptr(cx, def, substs) {
495495
return FfiUnsafe("found enum without foreign-function-safe \

src/librustc_typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
918918
def.destructor(tcx); // force the destructor to be evaluated
919919
check_representable(tcx, span, def_id);
920920

921-
if def.repr.simd {
921+
if def.repr.simd() {
922922
check_simd(tcx, span, def_id);
923923
}
924924
}

0 commit comments

Comments
 (0)