]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/ty/mod.rs
Rollup merge of #55834 - ogoffart:union-abi, r=eddyb
[rust.git] / src / librustc / ty / mod.rs
index 979cc9b115b5a2e6307631e1dd035956553eab2f..a474065b5cd55fe1911c8a1de888eb53ddf52ac3 100644 (file)
@@ -32,6 +32,7 @@
 use session::CrateDisambiguator;
 use traits::{self, Reveal};
 use ty;
+use ty::layout::VariantIdx;
 use ty::subst::{Subst, Substs};
 use ty::util::{IntTypeExt, Discr};
 use ty::walk::TypeWalker;
@@ -57,7 +58,7 @@
 use syntax_pos::{DUMMY_SP, Span};
 
 use smallvec;
-use rustc_data_structures::indexed_vec::Idx;
+use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
                                            HashStable};
 
@@ -1789,7 +1790,7 @@ pub enum VariantDiscr {
     /// For efficiency reasons, the distance from the
     /// last `Explicit` discriminant is being stored,
     /// or `0` for the first variant, if it has none.
-    Relative(usize),
+    Relative(u32),
 }
 
 #[derive(Debug)]
@@ -1805,7 +1806,7 @@ pub struct FieldDef {
 /// table.
 pub struct AdtDef {
     pub did: DefId,
-    pub variants: Vec<VariantDef>,
+    pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
     flags: AdtFlags,
     pub repr: ReprOptions,
 }
@@ -1997,13 +1998,19 @@ pub fn inhibit_enum_layout_opt(&self) -> bool {
     pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
         !(self.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty() || (self.pack == 1)
     }
+
+    /// Returns true if this `#[repr()]` should inhibit union abi optimisations
+    pub fn inhibit_union_abi_opt(&self) -> bool {
+        self.c()
+    }
+
 }
 
 impl<'a, 'gcx, 'tcx> AdtDef {
     fn new(tcx: TyCtxt<'_, '_, '_>,
            did: DefId,
            kind: AdtKind,
-           variants: Vec<VariantDef>,
+           variants: IndexVec<VariantIdx, VariantDef>,
            repr: ReprOptions) -> Self {
         debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
         let mut flags = AdtFlags::NO_ADT_FLAGS;
@@ -2125,11 +2132,11 @@ pub fn has_dtor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
     /// Asserts this is a struct or union and returns its unique variant.
     pub fn non_enum_variant(&self) -> &VariantDef {
         assert!(self.is_struct() || self.is_union());
-        &self.variants[0]
+        &self.variants[VariantIdx::new(0)]
     }
 
     #[inline]
-    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> GenericPredicates<'gcx> {
+    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc<GenericPredicates<'gcx>> {
         tcx.predicates_of(self.did)
     }
 
@@ -2152,11 +2159,12 @@ pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
             .expect("variant_with_id: unknown variant")
     }
 
-    pub fn variant_index_with_id(&self, vid: DefId) -> usize {
+    pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
         self.variants
-            .iter()
-            .position(|v| v.did == vid)
+            .iter_enumerated()
+            .find(|(_, v)| v.did == vid)
             .expect("variant_index_with_id: unknown variant")
+            .0
     }
 
     pub fn variant_of_def(&self, def: Def) -> &VariantDef {
@@ -2220,11 +2228,11 @@ pub fn eval_explicit_discr(
     pub fn discriminants(
         &'a self,
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    ) -> impl Iterator<Item=Discr<'tcx>> + Captures<'gcx> + 'a {
+    ) -> impl Iterator<Item=(VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a {
         let repr_type = self.repr.discr_type();
         let initial = repr_type.initial_discriminant(tcx.global_tcx());
         let mut prev_discr = None::<Discr<'tcx>>;
-        self.variants.iter().map(move |v| {
+        self.variants.iter_enumerated().map(move |(i, v)| {
             let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
             if let VariantDiscr::Explicit(expr_did) = v.discr {
                 if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
@@ -2233,7 +2241,7 @@ pub fn discriminants(
             }
             prev_discr = Some(discr);
 
-            discr
+            (i, discr)
         })
     }
 
@@ -2244,7 +2252,7 @@ pub fn discriminants(
     /// assuming there are no constant-evaluation errors there.
     pub fn discriminant_for_variant(&self,
                                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                    variant_index: usize)
+                                    variant_index: VariantIdx)
                                     -> Discr<'tcx> {
         let (val, offset) = self.discriminant_def_for_variant(variant_index);
         let explicit_value = val
@@ -2258,12 +2266,12 @@ pub fn discriminant_for_variant(&self,
     /// inferred discriminant directly
     pub fn discriminant_def_for_variant(
         &self,
-        variant_index: usize,
-    ) -> (Option<DefId>, usize) {
-        let mut explicit_index = variant_index;
+        variant_index: VariantIdx,
+    ) -> (Option<DefId>, u32) {
+        let mut explicit_index = variant_index.as_u32();
         let expr_did;
         loop {
-            match self.variants[explicit_index].discr {
+            match self.variants[VariantIdx::from_u32(explicit_index)].discr {
                 ty::VariantDiscr::Relative(0) => {
                     expr_did = None;
                     break;
@@ -2277,7 +2285,7 @@ pub fn discriminant_def_for_variant(
                 }
             }
         }
-        (expr_did, variant_index - explicit_index)
+        (expr_did, variant_index.as_u32() - explicit_index)
     }
 
     pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {
@@ -2371,8 +2379,8 @@ fn sized_constraint_for_ty(&self,
                     def_id: sized_trait,
                     substs: tcx.mk_substs_trait(ty, &[])
                 }).to_predicate();
-                let predicates = tcx.predicates_of(self.did).predicates;
-                if predicates.into_iter().any(|(p, _)| p == sized_predicate) {
+                let predicates = &tcx.predicates_of(self.did).predicates;
+                if predicates.iter().any(|(p, _)| *p == sized_predicate) {
                     vec![]
                 } else {
                     vec![ty]
@@ -2398,7 +2406,7 @@ pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx>
 
 /// Represents the various closure traits in the Rust language. This
 /// will determine the type of the environment (`self`, in the
-/// desuaring) argument that the closure expects.
+/// desugaring) argument that the closure expects.
 ///
 /// You can get the environment type of a closure using
 /// `tcx.closure_env_ty()`.