]> git.lizzy.rs Git - rust.git/commitdiff
Introduce ReprOptions, a struct for holding info from the repr attributes. This...
authorAustin Hicks <camlorn@camlorn.net>
Mon, 6 Feb 2017 20:26:32 +0000 (15:26 -0500)
committerAustin Hicks <camlorn@camlorn.net>
Tue, 7 Feb 2017 02:13:50 +0000 (21:13 -0500)
src/librustc/ty/context.rs
src/librustc/ty/mod.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_typeck/collect.rs

index a0eae33c4402b20c5a03478840ae208efe05bc54..6203679a510585ef03ae82a7e475d5d44a022725 100644 (file)
@@ -26,6 +26,7 @@
 use middle::stability;
 use mir::Mir;
 use ty::subst::{Kind, Substs};
+use ty::ReprOptions;
 use traits;
 use ty::{self, TraitRef, Ty, TypeAndMut};
 use ty::{TyS, TypeVariants, Slice};
@@ -672,9 +673,10 @@ pub fn alloc_trait_def(self, def: ty::TraitDef) -> &'gcx ty::TraitDef {
     pub fn alloc_adt_def(self,
                          did: DefId,
                          kind: AdtKind,
-                         variants: Vec<ty::VariantDef>)
+                         variants: Vec<ty::VariantDef>,
+                         repr: ReprOptions)
                          -> &'gcx ty::AdtDef {
-        let def = ty::AdtDef::new(self, did, kind, variants);
+        let def = ty::AdtDef::new(self, did, kind, variants, repr);
         self.global_arenas.adt_def.alloc(def)
     }
 
index 4d9514b1473c7a6d254f59e929ce9df7e6ca4cd5..beb286108a034cfd7e86181a6c04aa939a76fd35 100644 (file)
@@ -1327,7 +1327,8 @@ pub struct AdtDef {
     pub did: DefId,
     pub variants: Vec<VariantDef>,
     destructor: Cell<Option<DefId>>,
-    flags: Cell<AdtFlags>
+    flags: Cell<AdtFlags>,
+    pub repr: ReprOptions,
 }
 
 impl PartialEq for AdtDef {
@@ -1356,11 +1357,38 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum AdtKind { Struct, Union, Enum }
 
+/// 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>,
+}
+
+impl ReprOptions {
+    pub fn new<'a, 'gcx, 'tcx>(tcx: &TyCtxt<'a, 'gcx, 'tcx>, did: DefId) -> ReprOptions {
+        let mut ret = ReprOptions::default();
+        let attrs = tcx.lookup_repr_hints(did);
+        for r in attrs.iter() {
+            match *r {
+                attr::ReprExtern => ret.c = true,
+                attr::ReprPacked => ret.packed = true,
+                attr::ReprSimd => ret.simd = true,
+                attr::ReprInt(i) => ret.int = Some(i),
+                attr::ReprAny => (),
+            }
+        }
+        ret
+    }
+}
+
 impl<'a, 'gcx, 'tcx> AdtDef {
     fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
            did: DefId,
            kind: AdtKind,
-           variants: Vec<VariantDef>) -> Self {
+           variants: Vec<VariantDef>,
+           repr: ReprOptions) -> Self {
         let mut flags = AdtFlags::NO_ADT_FLAGS;
         let attrs = tcx.get_attrs(did);
         if attr::contains_name(&attrs, "fundamental") {
@@ -1385,6 +1413,7 @@ fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
             variants: variants,
             flags: Cell::new(flags),
             destructor: Cell::new(None),
+            repr: repr,
         }
     }
 
index f4a35ea5fd0cf396c38bee213e5aee611d270cd5..bb99be20f64d30ed46e4c0e1a6f53bc7605782ea 100644 (file)
@@ -425,8 +425,8 @@ fn to_def(&self, did: DefId) -> Option<Def> {
             EntryKind::ForeignImmStatic => Def::Static(did, false),
             EntryKind::MutStatic |
             EntryKind::ForeignMutStatic => Def::Static(did, true),
-            EntryKind::Struct(_) => Def::Struct(did),
-            EntryKind::Union(_) => Def::Union(did),
+            EntryKind::Struct(_, _) => Def::Struct(did),
+            EntryKind::Union(_, _) => Def::Union(did),
             EntryKind::Fn(_) |
             EntryKind::ForeignFn(_) => Def::Fn(did),
             EntryKind::Method(_) => Def::Method(did),
@@ -435,7 +435,7 @@ fn to_def(&self, did: DefId) -> Option<Def> {
             EntryKind::Mod(_) => Def::Mod(did),
             EntryKind::Variant(_) => Def::Variant(did),
             EntryKind::Trait(_) => Def::Trait(did),
-            EntryKind::Enum => Def::Enum(did),
+            EntryKind::Enum(_) => Def::Enum(did),
             EntryKind::MacroDef(_) => Def::Macro(did),
 
             EntryKind::ForeignMod |
@@ -519,8 +519,8 @@ fn get_variant(&self,
                    -> (ty::VariantDef, Option<DefIndex>) {
         let data = match item.kind {
             EntryKind::Variant(data) |
-            EntryKind::Struct(data) |
-            EntryKind::Union(data) => data.decode(self),
+            EntryKind::Struct(data, _) |
+            EntryKind::Union(data, _) => data.decode(self),
             _ => bug!(),
         };
 
@@ -547,7 +547,7 @@ pub fn get_adt_def(&self,
         let item = self.entry(item_id);
         let did = self.local_def_id(item_id);
         let mut ctor_index = None;
-        let variants = if let EntryKind::Enum = item.kind {
+        let variants = if let EntryKind::Enum(_) = item.kind {
             item.children
                 .decode(self)
                 .map(|index| {
@@ -561,14 +561,14 @@ pub fn get_adt_def(&self,
             ctor_index = struct_ctor;
             vec![variant]
         };
-        let kind = match item.kind {
-            EntryKind::Enum => ty::AdtKind::Enum,
-            EntryKind::Struct(_) => ty::AdtKind::Struct,
-            EntryKind::Union(_) => ty::AdtKind::Union,
+        let (kind, repr) = match item.kind {
+            EntryKind::Enum(repr) => (ty::AdtKind::Enum, repr),
+            EntryKind::Struct(_, repr) => (ty::AdtKind::Struct, repr),
+            EntryKind::Union(_, repr) => (ty::AdtKind::Union, repr),
             _ => bug!("get_adt_def called on a non-ADT {:?}", did),
         };
 
-        let adt = tcx.alloc_adt_def(did, kind, variants);
+        let adt = tcx.alloc_adt_def(did, kind, variants, repr);
         if let Some(ctor_index) = ctor_index {
             // Make adt definition available through constructor id as well.
             tcx.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt);
@@ -881,8 +881,8 @@ pub fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
 
     pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
         match self.entry(node_id).kind {
-            EntryKind::Struct(data) |
-            EntryKind::Union(data) |
+            EntryKind::Struct(data, _) |
+            EntryKind::Union(data, _) |
             EntryKind::Variant(data) => data.decode(self).ctor_kind,
             _ => CtorKind::Fictive,
         }
@@ -890,7 +890,7 @@ pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
 
     pub fn get_struct_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
         match self.entry(node_id).kind {
-            EntryKind::Struct(data) => {
+            EntryKind::Struct(data, _) => {
                 data.decode(self).struct_ctor.map(|index| self.local_def_id(index))
             }
             _ => None,
index 69e1bbd77662b8700ff88e94a46beee7fd1bd2a6..f4ff5f4626f3587e9a36ec97e7a61cd3352bacc4 100644 (file)
@@ -20,7 +20,7 @@
 use rustc::middle::lang_items;
 use rustc::mir;
 use rustc::traits::specialization_graph;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt, ReprOptions};
 
 use rustc::session::config::{self, CrateTypeProcMacro};
 use rustc::util::nodemap::{FxHashMap, NodeSet};
@@ -401,8 +401,10 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
             }
         }
 
+        let repr_options = get_repr_options(&tcx, adt_def_id);
+
         Entry {
-            kind: EntryKind::Struct(self.lazy(&data)),
+            kind: EntryKind::Struct(self.lazy(&data), repr_options),
             visibility: self.lazy(&ctor_vis),
             span: self.lazy(&tcx.def_span(def_id)),
             attributes: LazySeq::empty(),
@@ -659,7 +661,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
             }
             hir::ItemForeignMod(_) => EntryKind::ForeignMod,
             hir::ItemTy(..) => EntryKind::Type,
-            hir::ItemEnum(..) => EntryKind::Enum,
+            hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
             hir::ItemStruct(ref struct_def, _) => {
                 let variant = tcx.lookup_adt_def(def_id).struct_variant();
 
@@ -671,20 +673,24 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 } else {
                     None
                 };
+
+                let repr_options = get_repr_options(&tcx, def_id);
+
                 EntryKind::Struct(self.lazy(&VariantData {
                     ctor_kind: variant.ctor_kind,
                     disr: variant.disr_val.to_u128_unchecked(),
                     struct_ctor: struct_ctor,
-                }))
+                }), repr_options)
             }
             hir::ItemUnion(..) => {
                 let variant = tcx.lookup_adt_def(def_id).struct_variant();
+                let repr_options = get_repr_options(&tcx, def_id);
 
                 EntryKind::Union(self.lazy(&VariantData {
                     ctor_kind: variant.ctor_kind,
                     disr: variant.disr_val.to_u128_unchecked(),
                     struct_ctor: None,
-                }))
+                }), repr_options)
             }
             hir::ItemDefaultImpl(..) => {
                 let data = ImplData {
@@ -1419,3 +1425,11 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     result
 }
+
+pub fn get_repr_options<'a, 'tcx, 'gcx>(tcx: &TyCtxt<'a, 'tcx, 'gcx>, did: DefId) -> ReprOptions {
+    let ty = tcx.item_type(did);
+    match ty.sty {
+        ty::TyAdt(ref def, _) => return def.repr,
+        _ => bug!("{} is not an ADT", ty),
+    }
+}
index d13628e9ce7a3c0787997ae62a42ce5e4e8694ef..10aa4784aa2e13611efd3d0f50cdd67833f360b1 100644 (file)
@@ -18,7 +18,7 @@
 use rustc::middle::lang_items;
 use rustc::middle::resolve_lifetime::ObjectLifetimeDefault;
 use rustc::mir;
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, Ty, ReprOptions};
 use rustc_back::PanicStrategy;
 
 use rustc_serialize as serialize;
@@ -228,11 +228,11 @@ pub enum EntryKind<'tcx> {
     ForeignMutStatic,
     ForeignMod,
     Type,
-    Enum,
+    Enum(ReprOptions),
     Field,
     Variant(Lazy<VariantData>),
-    Struct(Lazy<VariantData>),
-    Union(Lazy<VariantData>),
+    Struct(Lazy<VariantData>, ReprOptions),
+    Union(Lazy<VariantData>, ReprOptions),
     Fn(Lazy<FnData>),
     ForeignFn(Lazy<FnData>),
     Mod(Lazy<ModData>),
index 1981e7c3a3d122086fcd695912cb515782cd2a6d..7936db65c44acd2a2b54e1ee7f9f83d4c50ae005 100644 (file)
@@ -65,7 +65,7 @@
 use rustc_const_eval::EvalHint::UncheckedExprHint;
 use rustc_const_eval::{ConstContext, report_const_eval_err};
 use rustc::ty::subst::Substs;
-use rustc::ty::{ToPredicate, ImplContainer, AssociatedItemContainer, TraitContainer};
+use rustc::ty::{ToPredicate, ImplContainer, AssociatedItemContainer, TraitContainer, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
 use rustc::ty::util::IntTypeExt;
 use rustc::dep_graph::DepNode;
@@ -1006,7 +1006,8 @@ fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let ctor_id = if !def.is_struct() { Some(ccx.tcx.hir.local_def_id(def.id())) } else { None };
     let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
                                                ConstInt::Infer(0), def)];
-    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, variants);
+    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, variants,
+        ReprOptions::new(&ccx.tcx, did));
     if let Some(ctor_id) = ctor_id {
         // Make adt definition available through constructor id as well.
         ccx.tcx.adt_defs.borrow_mut().insert(ctor_id, adt);
@@ -1024,7 +1025,7 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let did = ccx.tcx.hir.local_def_id(it.id);
     let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)];
 
-    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants);
+    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants, ReprOptions::new(&ccx.tcx, did));
     ccx.tcx.adt_defs.borrow_mut().insert(did, adt);
     adt
 }
@@ -1112,7 +1113,7 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
     }).collect();
 
-    let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants);
+    let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants, ReprOptions::new(&ccx.tcx, did));
     tcx.adt_defs.borrow_mut().insert(did, adt);
     adt
 }