]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc_typeck/variance/terms.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / librustc_typeck / variance / terms.rs
index d9e7e8cbf7df4eb16c948e1666bf239366605784..f6732f36e355aabc1647c50178fafce02c7e16af 100644 (file)
@@ -21,7 +21,6 @@
 
 use arena::TypedArena;
 use dep_graph::DepTrackingMapConfig;
-use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace};
 use rustc::ty::{self, TyCtxt};
 use rustc::ty::maps::ItemVariances;
 use std::fmt;
@@ -32,7 +31,6 @@ use rustc::hir::intravisit::Visitor;
 use util::nodemap::NodeMap;
 
 use self::VarianceTerm::*;
-use self::ParamKind::*;
 
 pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
 
@@ -51,7 +49,12 @@ impl<'a> fmt::Debug for VarianceTerm<'a> {
         match *self {
             ConstantTerm(c1) => write!(f, "{:?}", c1),
             TransformTerm(v1, v2) => write!(f, "({:?} \u{00D7} {:?})", v1, v2),
-            InferredTerm(id) => write!(f, "[{}]", { let InferredIndex(i) = id; i })
+            InferredTerm(id) => {
+                write!(f, "[{}]", {
+                    let InferredIndex(i) = id;
+                    i
+                })
+            }
         }
     }
 }
@@ -62,7 +65,7 @@ pub struct TermsContext<'a, 'tcx: 'a> {
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
     pub arena: &'a TypedArena<VarianceTerm<'a>>,
 
-    pub empty_variances: Rc<ty::ItemVariances>,
+    pub empty_variances: Rc<Vec<ty::Variance>>,
 
     // For marker types, UnsafeCell, and other lang items where
     // variance is hardcoded, records the item-id and the hardcoded
@@ -74,19 +77,11 @@ pub struct TermsContext<'a, 'tcx: 'a> {
     pub inferred_map: NodeMap<InferredIndex>,
 
     // Maps from an InferredIndex to the info for that variable.
-    pub inferred_infos: Vec<InferredInfo<'a>> ,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum ParamKind {
-    TypeParam,
-    RegionParam,
+    pub inferred_infos: Vec<InferredInfo<'a>>,
 }
 
 pub struct InferredInfo<'a> {
     pub item_id: ast::NodeId,
-    pub kind: ParamKind,
-    pub space: ParamSpace,
     pub index: usize,
     pub param_id: ast::NodeId,
     pub term: VarianceTermPtr<'a>,
@@ -97,11 +92,9 @@ pub struct InferredInfo<'a> {
     pub initial_variance: ty::Variance,
 }
 
-pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    arena: &'a mut TypedArena<VarianceTerm<'a>>)
-    -> TermsContext<'a, 'tcx>
-{
+pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                                     arena: &'a mut TypedArena<VarianceTerm<'a>>)
+                                                     -> TermsContext<'a, 'tcx> {
     let mut terms_cx = TermsContext {
         tcx: tcx,
         arena: arena,
@@ -112,20 +105,16 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
 
         // cache and share the variance struct used for items with
         // no type/region parameters
-        empty_variances: Rc::new(ty::ItemVariances {
-            types: VecPerParamSpace::empty(),
-            regions: VecPerParamSpace::empty()
-        })
+        empty_variances: Rc::new(vec![]),
     };
 
     // See README.md for a discussion on dep-graph management.
-    tcx.visit_all_items_in_krate(|def_id| ItemVariances::to_dep_node(&def_id),
-                                 &mut terms_cx);
+    tcx.visit_all_items_in_krate(|def_id| ItemVariances::to_dep_node(&def_id), &mut terms_cx);
 
     terms_cx
 }
 
-fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
+fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId, Vec<ty::Variance>)> {
     let all = vec![
         (tcx.lang_items.phantom_data(), vec![ty::Covariant]),
         (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
@@ -151,15 +140,13 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
     fn add_inferreds_for_item(&mut self,
                               item_id: ast::NodeId,
                               has_self: bool,
-                              generics: &hir::Generics)
-    {
-        /*!
-         * Add "inferreds" for the generic parameters declared on this
-         * item. This has a lot of annoying parameters because we are
-         * trying to drive this from the AST, rather than the
-         * ty::Generics, so that we can get span info -- but this
-         * means we must accommodate syntactic distinctions.
-         */
+                              generics: &hir::Generics) {
+        //! Add "inferreds" for the generic parameters declared on this
+        //! item. This has a lot of annoying parameters because we are
+        //! trying to drive this from the AST, rather than the
+        //! ty::Generics, so that we can get span info -- but this
+        //! means we must accommodate syntactic distinctions.
+        //!
 
         // NB: In the code below for writing the results back into the
         // tcx, we rely on the fact that all inferreds for a particular
@@ -168,16 +155,18 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
         let inferreds_on_entry = self.num_inferred();
 
         if has_self {
-            self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id);
+            self.add_inferred(item_id, 0, item_id);
         }
 
         for (i, p) in generics.lifetimes.iter().enumerate() {
             let id = p.lifetime.id;
-            self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
+            let i = has_self as usize + i;
+            self.add_inferred(item_id, i, id);
         }
 
         for (i, p) in generics.ty_params.iter().enumerate() {
-            self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
+            let i = has_self as usize + generics.lifetimes.len() + i;
+            self.add_inferred(item_id, i, p.id);
         }
 
         // If this item has no type or lifetime parameters,
@@ -189,63 +178,47 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
         // parameters".
         if self.num_inferred() == inferreds_on_entry {
             let item_def_id = self.tcx.map.local_def_id(item_id);
-            let newly_added =
-                self.tcx.item_variance_map.borrow_mut().insert(
-                    item_def_id,
-                    self.empty_variances.clone()).is_none();
+            let newly_added = self.tcx
+                .item_variance_map
+                .borrow_mut()
+                .insert(item_def_id, self.empty_variances.clone())
+                .is_none();
             assert!(newly_added);
         }
     }
 
-    fn add_inferred(&mut self,
-                    item_id: ast::NodeId,
-                    kind: ParamKind,
-                    space: ParamSpace,
-                    index: usize,
-                    param_id: ast::NodeId) {
+    fn add_inferred(&mut self, item_id: ast::NodeId, index: usize, param_id: ast::NodeId) {
         let inf_index = InferredIndex(self.inferred_infos.len());
         let term = self.arena.alloc(InferredTerm(inf_index));
-        let initial_variance = self.pick_initial_variance(item_id, space, index);
-        self.inferred_infos.push(InferredInfo { item_id: item_id,
-                                                kind: kind,
-                                                space: space,
-                                                index: index,
-                                                param_id: param_id,
-                                                term: term,
-                                                initial_variance: initial_variance });
+        let initial_variance = self.pick_initial_variance(item_id, index);
+        self.inferred_infos.push(InferredInfo {
+            item_id: item_id,
+            index: index,
+            param_id: param_id,
+            term: term,
+            initial_variance: initial_variance,
+        });
         let newly_added = self.inferred_map.insert(param_id, inf_index).is_none();
         assert!(newly_added);
 
         debug!("add_inferred(item_path={}, \
                 item_id={}, \
-                kind={:?}, \
-                space={:?}, \
                 index={}, \
                 param_id={}, \
                 inf_index={:?}, \
                 initial_variance={:?})",
                self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)),
-               item_id, kind, space, index, param_id, inf_index,
+               item_id,
+               index,
+               param_id,
+               inf_index,
                initial_variance);
     }
 
-    fn pick_initial_variance(&self,
-                             item_id: ast::NodeId,
-                             space: ParamSpace,
-                             index: usize)
-                             -> ty::Variance
-    {
-        match space {
-            SelfSpace | FnSpace => {
-                ty::Bivariant
-            }
-
-            TypeSpace => {
-                match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
-                    Some(&(_, ref variances)) => variances[index],
-                    None => ty::Bivariant
-                }
-            }
+    fn pick_initial_variance(&self, item_id: ast::NodeId, index: usize) -> ty::Variance {
+        match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
+            Some(&(_, ref variances)) => variances[index],
+            None => ty::Bivariant,
         }
     }
 
@@ -256,14 +229,16 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
-        debug!("add_inferreds for item {}", self.tcx.map.node_to_string(item.id));
+        debug!("add_inferreds for item {}",
+               self.tcx.map.node_to_string(item.id));
 
         match item.node {
             hir::ItemEnum(_, ref generics) |
-            hir::ItemStruct(_, ref generics) => {
+            hir::ItemStruct(_, ref generics) |
+            hir::ItemUnion(_, ref generics) => {
                 self.add_inferreds_for_item(item.id, false, generics);
             }
-            hir::ItemTrait(_, ref generics, _, _) => {
+            hir::ItemTrait(_, ref generics, ..) => {
                 // Note: all inputs for traits are ultimately
                 // constrained to be invariant. See `visit_item` in
                 // the impl for `ConstraintContext` in `constraints.rs`.
@@ -279,9 +254,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
             hir::ItemFn(..) |
             hir::ItemMod(..) |
             hir::ItemForeignMod(..) |
-            hir::ItemTy(..) => {
-            }
+            hir::ItemTy(..) => {}
         }
     }
 }
-