about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-04-16 16:47:18 +0000
committerbors <bors@rust-lang.org>2017-04-16 16:47:18 +0000
commit9af79f52d0ab43e318bdf3aa73d939c4482cc946 (patch)
tree395a330707399f64722675b7c29fcc21a785e299
parentfef1026bae4a0cc59c4bd204021eea4e1a976b4f (diff)
parentfcbd89850239a53a5dc459e99004c4b5b8e6146d (diff)
downloadrust-9af79f52d0ab43e318bdf3aa73d939c4482cc946.tar.gz
rust-9af79f52d0ab43e318bdf3aa73d939c4482cc946.zip
Auto merge of #41329 - nagisa:bitflags-repr-options, r=eddyb
Compress ReprOptions a little bit

r? @eddyb
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/intrinsicck.rs2
-rw-r--r--src/librustc/ty/layout.rs14
-rw-r--r--src/librustc/ty/mod.rs72
-rw-r--r--src/librustc/ty/sty.rs2
-rw-r--r--src/librustc_lint/types.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs2
7 files changed, 65 insertions, 35 deletions
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 8926ff5c1fb..342553593af 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -162,7 +162,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     hir::ItemStruct(..) | hir::ItemUnion(..) => {
                         let def_id = self.tcx.hir.local_def_id(item.id);
                         let def = self.tcx.lookup_adt_def(def_id);
-                        self.struct_has_extern_repr = def.repr.c;
+                        self.struct_has_extern_repr = def.repr.c();
 
                         intravisit::walk_item(self, &item);
                     }
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 8dc298b9c2a..942f8475ece 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -46,7 +46,7 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         _ => return ty
     };
 
-    if def.variants.len() == 2 && !def.repr.c && def.repr.int.is_none() {
+    if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() {
         let data_idx;
 
         if def.variants[0].fields.is_empty() {
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index d7a4b3fda63..df60eee8c02 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -15,7 +15,7 @@ pub use self::Primitive::*;
 use infer::InferCtxt;
 use session::Session;
 use traits;
-use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
+use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions, ReprFlags};
 
 use syntax::ast::{FloatTy, IntTy, UintTy};
 use syntax::attr;
@@ -479,7 +479,7 @@ impl Integer {
             return (discr, ity.is_signed());
         }
 
-        if repr.c {
+        if repr.c() {
             match &tcx.sess.target.target.arch[..] {
                 // WARNING: the ARM EABI has two variants; the one corresponding
                 // to `at_least == I32` appears to be used on Linux and NetBSD,
@@ -583,7 +583,7 @@ impl<'a, 'gcx, 'tcx> Struct {
     fn new(dl: &TargetDataLayout, fields: &Vec<&'a Layout>,
                   repr: &ReprOptions, kind: StructKind,
                   scapegoat: Ty<'gcx>) -> Result<Struct, LayoutError<'gcx>> {
-        let packed = repr.packed;
+        let packed = repr.packed();
         let mut ret = Struct {
             align: if packed { dl.i8_align } else { dl.aggregate_align },
             packed: packed,
@@ -598,7 +598,7 @@ impl<'a, 'gcx, 'tcx> Struct {
         // In addition, code in trans assume that 2-element structs can become pairs.
         // It's easier to just short-circuit here.
         let can_optimize = (fields.len() > 2 || StructKind::EnumVariant == kind)
-            && !(repr.c || repr.packed || repr.linear || repr.simd);
+            && (repr.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty();
 
         let (optimize, sort_ascending) = match kind {
             StructKind::AlwaysSizedUnivariant => (can_optimize, false),
@@ -1177,7 +1177,7 @@ impl<'a, 'gcx, 'tcx> Layout {
             }
 
             // SIMD vector types.
-            ty::TyAdt(def, ..) if def.repr.simd => {
+            ty::TyAdt(def, ..) if def.repr.simd() => {
                 let element = ty.simd_type(tcx);
                 match *element.layout(infcx)? {
                     Scalar { value, .. } => {
@@ -1255,7 +1255,7 @@ impl<'a, 'gcx, 'tcx> Layout {
                         field.ty(tcx, substs).layout(infcx)
                     }).collect::<Result<Vec<_>, _>>()?;
                     let layout = if def.is_union() {
-                        let mut un = Union::new(dl, def.repr.packed);
+                        let mut un = Union::new(dl, def.repr.packed());
                         un.extend(dl, fields.iter().map(|&f| Ok(f)), ty)?;
                         UntaggedUnion { variants: un }
                     } else {
@@ -1925,7 +1925,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
             ty::TyTuple(tys, _) => tys[i],
 
             // SIMD vector types.
-            ty::TyAdt(def, ..) if def.repr.simd => {
+            ty::TyAdt(def, ..) if def.repr.simd() => {
                 self.ty.simd_type(tcx)
             }
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 09eacb40aef..b4f2deabd23 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1438,51 +1438,81 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for AdtDef {
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum AdtKind { Struct, Union, Enum }
 
+bitflags! {
+    #[derive(RustcEncodable, RustcDecodable, Default)]
+    flags ReprFlags: u8 {
+        const IS_C               = 1 << 0,
+        const IS_PACKED          = 1 << 1,
+        const IS_SIMD            = 1 << 2,
+        // Internal only for now. If true, don't reorder fields.
+        const IS_LINEAR          = 1 << 3,
+
+        // Any of these flags being set prevent field reordering optimisation.
+        const IS_UNOPTIMISABLE   = ReprFlags::IS_C.bits |
+                                   ReprFlags::IS_PACKED.bits |
+                                   ReprFlags::IS_SIMD.bits |
+                                   ReprFlags::IS_LINEAR.bits,
+    }
+}
+
+impl_stable_hash_for!(struct ReprFlags {
+    bits
+});
+
+
+
 /// Represents the repr options provided by the user,
 #[derive(Copy, Clone, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
 pub struct ReprOptions {
-    pub c: bool,
-    pub packed: bool,
-    pub simd: bool,
     pub int: Option<attr::IntType>,
-    // Internal only for now. If true, don't reorder fields.
-    pub linear: bool,
+    pub flags: ReprFlags,
 }
 
 impl_stable_hash_for!(struct ReprOptions {
-    c,
-    packed,
-    simd,
     int,
-    linear
+    flags
 });
 
 impl ReprOptions {
     pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions {
-        let mut ret = ReprOptions::default();
+        let mut flags = ReprFlags::empty();
+        let mut size = None;
 
         for attr in tcx.get_attrs(did).iter() {
             for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
-                match r {
-                    attr::ReprExtern => ret.c = true,
-                    attr::ReprPacked => ret.packed = true,
-                    attr::ReprSimd => ret.simd = true,
-                    attr::ReprInt(i) => ret.int = Some(i),
-                }
+                flags.insert(match r {
+                    attr::ReprExtern => ReprFlags::IS_C,
+                    attr::ReprPacked => ReprFlags::IS_PACKED,
+                    attr::ReprSimd => ReprFlags::IS_SIMD,
+                    attr::ReprInt(i) => {
+                        size = Some(i);
+                        ReprFlags::empty()
+                    },
+                });
             }
         }
 
         // FIXME(eddyb) This is deprecated and should be removed.
         if tcx.has_attr(did, "simd") {
-            ret.simd = true;
+            flags.insert(ReprFlags::IS_SIMD);
         }
 
         // This is here instead of layout because the choice must make it into metadata.
-        ret.linear = !tcx.consider_optimizing(|| format!("Reorder fields of {:?}",
-            tcx.item_path_str(did)));
-        ret
+        if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) {
+            flags.insert(ReprFlags::IS_LINEAR);
+        }
+        ReprOptions { int: size, flags: flags }
     }
 
+    #[inline]
+    pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) }
+    #[inline]
+    pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) }
+    #[inline]
+    pub fn packed(&self) -> bool { self.flags.contains(ReprFlags::IS_PACKED) }
+    #[inline]
+    pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) }
+
     pub fn discr_type(&self) -> attr::IntType {
         self.int.unwrap_or(attr::SignedInt(ast::IntTy::Is))
     }
@@ -1491,7 +1521,7 @@ impl ReprOptions {
     /// layout" optimizations, such as representing `Foo<&T>` as a
     /// single pointer.
     pub fn inhibit_enum_layout_opt(&self) -> bool {
-        self.c || self.int.is_some()
+        self.c() || self.int.is_some()
     }
 }
 
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 0e3005847bc..d5924817034 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1095,7 +1095,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
     #[inline]
     pub fn is_simd(&self) -> bool {
         match self.sty {
-            TyAdt(def, _) => def.repr.simd,
+            TyAdt(def, _) => def.repr.simd(),
             _ => false,
         }
     }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 2318bb81aff..3e60d8a5ada 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -416,7 +416,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 }
                 match def.adt_kind() {
                     AdtKind::Struct => {
-                        if !def.repr.c {
+                        if !def.repr.c() {
                             return FfiUnsafe("found struct without foreign-function-safe \
                                               representation annotation in foreign module, \
                                               consider adding a #[repr(C)] attribute to the type");
@@ -450,7 +450,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                         if all_phantom { FfiPhantom } else { FfiSafe }
                     }
                     AdtKind::Union => {
-                        if !def.repr.c {
+                        if !def.repr.c() {
                             return FfiUnsafe("found union without foreign-function-safe \
                                               representation annotation in foreign module, \
                                               consider adding a #[repr(C)] attribute to the type");
@@ -489,7 +489,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
                         // Check for a repr() attribute to specify the size of the
                         // discriminant.
-                        if !def.repr.c && def.repr.int.is_none() {
+                        if !def.repr.c() && def.repr.int.is_none() {
                             // Special-case types like `Option<extern fn()>`.
                             if !is_repr_nullable_ptr(cx, def, substs) {
                                 return FfiUnsafe("found enum without foreign-function-safe \
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5e7325275b8..daa18aaa556 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -918,7 +918,7 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
 
-    if def.repr.simd {
+    if def.repr.simd() {
         check_simd(tcx, span, def_id);
     }
 }