]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/ty/maps.rs
Remove interior mutability from TraitDef by turning fields into queries.
[rust.git] / src / librustc / ty / maps.rs
index b37dbc6411baf82ce6e4319d08e757dff8d09c31..188ef289ba9e42ece0540ff1bf86ce9453f953ea 100644 (file)
 use mir;
 use mir::transform::{MirSuite, MirPassIndex};
 use session::CompileResult;
+use traits::specialization_graph;
 use ty::{self, CrateInherentImpls, Ty, TyCtxt};
 use ty::item_path;
 use ty::steal::Steal;
 use ty::subst::Substs;
+use ty::fast_reject::SimplifiedType;
 use util::nodemap::{DefIdSet, NodeSet};
 
 use rustc_data_structures::indexed_vec::IndexVec;
 use std::cell::{RefCell, RefMut};
-use std::option;
 use std::fmt::Debug;
 use std::hash::Hash;
-use std::iter::{self, Once};
 use std::mem;
 use std::collections::BTreeMap;
 use std::ops::Deref;
 use std::rc::Rc;
-use std::vec;
 use syntax_pos::{Span, DUMMY_SP};
+use syntax::attr;
+use syntax::ast;
 use syntax::symbol::Symbol;
 
 pub trait Key: Clone + Hash + Eq + Debug {
@@ -99,6 +100,15 @@ fn default_span(&self, tcx: TyCtxt) -> Span {
     }
 }
 
+impl Key for (DefId, SimplifiedType) {
+    fn map_crate(&self) -> CrateNum {
+        self.0.krate
+    }
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        self.0.default_span(tcx)
+    }
+}
+
 impl<'tcx> Key for (DefId, &'tcx Substs<'tcx>) {
     fn map_crate(&self) -> CrateNum {
         self.0.krate
@@ -161,67 +171,6 @@ fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
     }
 }
 
-trait IntoKeyValues<K: Key, V> {
-    type KeyValues: IntoIterator<Item=(K, V)>;
-
-    fn into_key_values(key: &K, value: Self) -> Self::KeyValues;
-}
-
-impl<K: Key, V> IntoKeyValues<K, V> for V {
-    type KeyValues = Once<(K, V)>;
-
-    fn into_key_values(key: &K, value: Self) -> Self::KeyValues {
-        iter::once((key.clone(), value))
-    }
-}
-
-/// Return type for a multi-query, which is a query which may (if it
-/// chooses) return more than one (key, value) pair. Construct a
-/// `Multi` using `Multi::from(...)`.
-pub struct Multi<K: Key, V> {
-    single: Option<V>,
-    map: Vec<(K, V)>,
-}
-
-impl<K: Key, V> Multi<K, V> {
-    pub fn iter<'a>(&'a self, key: &'a K) -> impl Iterator<Item = (&'a K, &'a V)> + 'a {
-        self.single.iter()
-                   .map(move |v| (key, v))
-                   .chain(self.map.iter().map(move |&(ref k, ref v)| (k, v)))
-    }
-}
-
-/// Construct a `Multi` from a single value.
-impl<K: Key, V> From<V> for Multi<K, V> {
-    fn from(value: V) -> Self {
-        Multi {
-            single: Some(value),
-            map: vec![],
-        }
-    }
-}
-
-/// Construct a `Multi` from a hashmap of (K, V) pairs.
-impl<K: Key, V> From<Vec<(K, V)>> for Multi<K, V> {
-    fn from(value: Vec<(K, V)>) -> Self {
-        Multi {
-            single: None,
-            map: value
-        }
-    }
-}
-
-impl<K: Key, V> IntoKeyValues<K, V> for Multi<K, V> {
-    type KeyValues = iter::Chain<option::IntoIter<(K, V)>, vec::IntoIter<(K, V)>>;
-
-    fn into_key_values(key: &K, value: Self) -> Self::KeyValues {
-        value.single
-             .map(|v| (key.clone(), v))
-             .into_iter()
-             .chain(value.map)
-    }
-}
-
 pub struct CycleError<'a, 'tcx: 'a> {
     span: Span,
     cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
@@ -244,7 +193,7 @@ pub fn report_cycle(self, CycleError { span, cycle }: CycleError) {
             let mut err =
                 struct_span_err!(self.sess, span, E0391,
                                  "unsupported cyclic reference between types/traits detected");
-            err.span_label(span, &format!("cyclic reference"));
+            err.span_label(span, "cyclic reference");
 
             err.span_note(stack[0].0, &format!("the cycle begins when {}...",
                                                stack[0].1.describe(self)));
@@ -329,6 +278,12 @@ fn describe(_: TyCtxt, _: CrateNum) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::crate_variances<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("computing the variances for items in this crate")
+    }
+}
+
 impl<'tcx> QueryDescription for queries::mir_shims<'tcx> {
     fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
         format!("generating MIR shim for `{}`",
@@ -384,6 +339,49 @@ fn describe(_: TyCtxt, _: DefId) -> String {
     }
 }
 
+
+impl<'tcx> QueryDescription for queries::stability<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("stability")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::deprecation<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("deprecation")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::item_attrs<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("item_attrs")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::is_exported_symbol<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("is_exported_symbol")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::fn_arg_names<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("fn_arg_names")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::impl_parent<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("impl_parent")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::trait_of_item<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        bug!("trait_of_item")
+    }
+}
+
 impl<'tcx> QueryDescription for queries::item_body_nested_bodies<'tcx> {
     fn describe(tcx: TyCtxt, def_id: DefId) -> String {
         format!("nested item bodies of `{}`", tcx.item_path_str(def_id))
@@ -397,22 +395,28 @@ fn describe(tcx: TyCtxt, def_id: DefId) -> String {
     }
 }
 
-impl<'tcx> QueryDescription for queries::is_item_mir_available<'tcx> {
+impl<'tcx> QueryDescription for queries::is_mir_available<'tcx> {
     fn describe(tcx: TyCtxt, def_id: DefId) -> String {
         format!("checking if item is mir available: `{}`",
             tcx.item_path_str(def_id))
     }
 }
 
-impl<'tcx> QueryDescription for queries::mir_suite<'tcx> {
-    fn describe(_: TyCtxt, (suite, _): (MirSuite, DefId)) -> String {
-        format!("MIR suite #{}.*", suite.0)
+impl<'tcx> QueryDescription for queries::trait_impls_of<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("trait impls of `{}`", tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription for queries::relevant_trait_impls_for<'tcx> {
+    fn describe(tcx: TyCtxt, (def_id, ty): (DefId, SimplifiedType)) -> String {
+        format!("relevant impls for: `({}, {:?})`", tcx.item_path_str(def_id), ty)
     }
 }
 
-impl<'tcx> QueryDescription for queries::mir_pass<'tcx> {
-    fn describe(_: TyCtxt, (suite, pass_num, _): (MirSuite, MirPassIndex, DefId)) -> String {
-        format!("MIR pass #{}.{}", suite.0, pass_num.0)
+impl<'tcx> QueryDescription for queries::is_object_safe<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("determine object safety of trait `{}`", tcx.item_path_str(def_id))
     }
 }
 
@@ -502,14 +506,7 @@ fn try_get_with<F, R>(tcx: TyCtxt<'a, $tcx, 'lcx>,
                     provider(tcx.global_tcx(), key)
                 })?;
 
-                {
-                    let map = &mut *tcx.maps.$name.borrow_mut();
-                    for (k, v) in IntoKeyValues::<$K, $V>::into_key_values(&key, result) {
-                        map.insert(k, v);
-                    }
-                }
-
-                Ok(f(tcx.maps.$name.borrow().get(&key).expect("value just generated")))
+                Ok(f(tcx.maps.$name.borrow_mut().entry(key).or_insert(result)))
             }
 
             pub fn try_get(tcx: TyCtxt<'a, $tcx, 'lcx>, span: Span, key: $K)
@@ -618,18 +615,6 @@ pub struct Maps<$tcx> {
         }
     };
 
-    // Detect things with the `pub` modifier
-    (tcx: $tcx:tt,
-     input: (([pub $($other_modifiers:tt)*] $attrs:tt $name:tt) $($input:tt)*),
-     output: $output:tt) => {
-        define_map_struct! {
-            tcx: $tcx,
-            ready: ([pub] $attrs $name),
-            input: ($($input)*),
-            output: $output
-        }
-    };
-
     // No modifiers left? This is a private item.
     (tcx: $tcx:tt,
      input: (([] $attrs:tt $name:tt) $($input:tt)*),
@@ -695,20 +680,6 @@ fn default() -> Self {
         }
     };
 
-    // The `multi` modifier indicates a **multiquery**, in which case
-    // the function returns a `Multi<K,V>` instead of just a value
-    // `V`.
-    (tcx: $tcx:tt,
-     input: (([multi $($other_modifiers:tt)*] $name:tt [$K:ty] [$V:ty]) $($input:tt)*),
-     output: $output:tt) => {
-        define_provider_struct! {
-            tcx: $tcx,
-            ready: ($name [$K] [Multi<$K,$V>]),
-            input: ($($input)*),
-            output: $output
-        }
-    };
-
     // Regular queries produce a `V` only.
     (tcx: $tcx:tt,
      input: (([] $name:tt $K:tt $V:tt) $($input:tt)*),
@@ -721,7 +692,7 @@ fn default() -> Self {
         }
     };
 
-    // Skip modifiers other than `multi`.
+    // Skip modifiers.
     (tcx: $tcx:tt,
      input: (([$other_modifier:tt $($modifiers:tt)*] $($fields:tt)*) $($input:tt)*),
      output: $output:tt) => {
@@ -770,9 +741,13 @@ fn default() -> Self {
     /// True if this is a foreign item (i.e., linked via `extern { ... }`).
     [] is_foreign_item: IsForeignItem(DefId) -> bool,
 
+    /// Get a map with the variance of every item; use `item_variance`
+    /// instead.
+    [] crate_variances: crate_variances(CrateNum) -> Rc<ty::CrateVariancesMap>,
+
     /// Maps from def-id of a type or region parameter to its
     /// (inferred) variance.
-    [pub] variances_of: ItemSignature(DefId) -> Rc<Vec<ty::Variance>>,
+    [] variances_of: ItemVariances(DefId) -> Rc<Vec<ty::Variance>>,
 
     /// Maps from an impl/trait def-id to a list of the def-ids of its items
     [] associated_item_def_ids: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>>,
@@ -798,27 +773,13 @@ fn default() -> Self {
     /// the value isn't known except to the pass itself.
     [] mir_const_qualif: Mir(DefId) -> u8,
 
-    /// Performs the initial MIR construction. You almost certainly do not
-    /// want to use this query, because its output is intended to be stolen
-    /// immediately by the MIR passes below. Consider `optimized_mir` instead.
-    ///
-    /// See the README for the `mir` module for details.
-    [] mir_build: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-    /// Fetch the MIR for a given def-id after the given set of passes has ben
-    /// applied to it. This is mostly an "intermediate" query. Normally, you would
-    /// prefer to use `optimized_mir(def_id)`, which will fetch the MIR after all
-    /// optimizations and so forth.
+    /// Fetch the MIR for a given def-id up till the point where it is
+    /// ready for const evaluation.
     ///
     /// See the README for the `mir` module for details.
-    [] mir_suite: mir_suite((MirSuite, DefId)) -> &'tcx Steal<mir::Mir<'tcx>>,
+    [] mir_const: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
 
-    /// Fetch the MIR for a given def-id after a given pass has been executed. This is
-    /// **only** intended to be used by the `mir_suite` provider -- if you are using it
-    /// manually, you're doing it wrong.
-    ///
-    /// See the README for the `mir` module for details.
-    [multi] mir_pass: mir_pass((MirSuite, MirPassIndex, DefId)) -> &'tcx Steal<mir::Mir<'tcx>>,
+    [] mir_validated: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
 
     /// MIR after our optimization passes have run. This is MIR that is ready
     /// for trans. This is also the only query that can fetch non-local MIR, at present.
@@ -869,7 +830,7 @@ fn default() -> Self {
     /// Per-function `RegionMaps`. The `DefId` should be the owner-def-id for the fn body;
     /// in the case of closures or "inline" expressions, this will be redirected to the enclosing
     /// fn item.
-    [] region_maps: RegionMaps(DefId) -> Rc<RegionMaps<'tcx>>,
+    [] region_maps: RegionMaps(DefId) -> Rc<RegionMaps>,
 
     [] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>,
 
@@ -878,10 +839,23 @@ fn default() -> Self {
 
     [] describe_def: DescribeDef(DefId) -> Option<Def>,
     [] def_span: DefSpan(DefId) -> Span,
-
-    [] item_body_nested_bodies: metadata_dep_node(DefId) -> Rc<BTreeMap<hir::BodyId, hir::Body>>,
-    [] const_is_rvalue_promotable_to_static: metadata_dep_node(DefId) -> bool,
-    [] is_item_mir_available: metadata_dep_node(DefId) -> bool,
+    [] stability: Stability(DefId) -> Option<attr::Stability>,
+    [] deprecation: Deprecation(DefId) -> Option<attr::Deprecation>,
+    [] item_attrs: ItemAttrs(DefId) -> Rc<[ast::Attribute]>,
+    [] fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
+    [] impl_parent: ImplParent(DefId) -> Option<DefId>,
+    [] trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
+    [] is_exported_symbol: IsExportedSymbol(DefId) -> bool,
+    [] item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> Rc<BTreeMap<hir::BodyId, hir::Body>>,
+    [] const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
+    [] is_mir_available: IsMirAvailable(DefId) -> bool,
+
+    [] trait_impls_of: TraitImpls(DefId) -> Rc<Vec<DefId>>,
+    // Note that TraitDef::for_each_relevant_impl() will do type simplication for you.
+    [] relevant_trait_impls_for: relevant_trait_impls_for((DefId, SimplifiedType))
+        -> Rc<Vec<DefId>>,
+    [] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
+    [] is_object_safe: ObjectSafety(DefId) -> bool,
 }
 
 fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -896,10 +870,6 @@ fn reachability_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::Reachability
 }
 
-fn metadata_dep_node(def_id: DefId) -> DepNode<DefId> {
-    DepNode::MetaData(def_id)
-}
-
 fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode<DefId> {
     instance.dep_node()
 }
@@ -922,10 +892,10 @@ fn mir_keys(_: CrateNum) -> DepNode<DefId> {
     DepNode::MirKeys
 }
 
-fn mir_suite((_suite, def_id): (MirSuite, DefId)) -> DepNode<DefId> {
-    DepNode::Mir(def_id)
+fn crate_variances(_: CrateNum) -> DepNode<DefId> {
+    DepNode::CrateVariances
 }
 
-fn mir_pass((_suite, _pass_num, def_id): (MirSuite, MirPassIndex, DefId)) -> DepNode<DefId> {
-    DepNode::Mir(def_id)
+fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode<DefId> {
+    DepNode::TraitImpls(def_id)
 }