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 {
}
}
+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
}
}
-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>)]>,
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)));
}
}
+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 `{}`",
}
}
+
+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))
}
}
-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))
}
}
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)
}
};
- // 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)*),
}
};
- // 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)*),
}
};
- // Skip modifiers other than `multi`.
+ // Skip modifiers.
(tcx: $tcx:tt,
input: (([$other_modifier:tt $($modifiers:tt)*] $($fields:tt)*) $($input:tt)*),
output: $output:tt) => {
/// 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>>,
/// 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.
/// 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>,
[] 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> {
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()
}
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)
}