[] CrateDisambiguator(CrateNum),
[] CrateHash(CrateNum),
[] OriginalCrateName(CrateNum),
+
+ [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
+ [] AllTraitImplementations(CrateNum),
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
- // trait info
- fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
-
// trait/impl-item info
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
fn item_generics_cloned(&self, def: DefId) -> ty::Generics
{ bug!("item_generics_cloned") }
- // trait info
- fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
-
// trait/impl-item info
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
{ bug!("associated_item_cloned") }
}
}
+impl<'tcx> QueryDescription for queries::implementations_of_trait<'tcx> {
+ fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
+ format!("looking up implementations of a trait in a crate")
+ }
+}
+
+impl<'tcx> QueryDescription for queries::all_trait_implementations<'tcx> {
+ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+ format!("looking up all (?) trait implementations")
+ }
+}
+
// If enabled, send a message to the profile-queries thread
macro_rules! profq_msg {
($tcx:expr, $msg:expr) => {
[] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> Symbol,
[] fn crate_hash: CrateHash(CrateNum) -> Svh,
[] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
+
+ [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId))
+ -> Rc<Vec<DefId>>,
+ [] fn all_trait_implementations: AllTraitImplementations(CrateNum)
+ -> Rc<Vec<DefId>>,
}
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
DepConstructor::Specializes { impl1: a, impl2: b }
}
+
+fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId))
+ -> DepConstructor<'tcx>
+{
+ DepConstructor::ImplementationsOfTrait { krate, trait_id }
+}
pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_id: DefId)
-> Rc<TraitImpls> {
- let remote_impls = if trait_id.is_local() {
- // Traits defined in the current crate can't have impls in upstream
- // crates, so we don't bother querying the cstore.
- Vec::new()
- } else {
- tcx.sess.cstore.implementations_of_trait(Some(trait_id))
- };
+ let mut remote_impls = Vec::new();
+
+ // Traits defined in the current crate can't have impls in upstream
+ // crates, so we don't bother querying the cstore.
+ if !trait_id.is_local() {
+ for cnum in tcx.sess.cstore.crates() {
+ let impls = tcx.implementations_of_trait((cnum, trait_id));
+ remote_impls.extend(impls.iter().cloned());
+ }
+ }
let mut blanket_impls = Vec::new();
let mut non_blanket_impls = FxHashMap();
use rustc::hir;
macro_rules! provide {
- (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident, $($name:ident => $compute:block)*) => {
+ (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
+ $($name:ident => $compute:block)*) => {
pub fn provide<$lt>(providers: &mut Providers<$lt>) {
$(fn $name<'a, $lt:$lt, T>($tcx: TyCtxt<'a, $lt, $lt>, def_id_arg: T)
-> <ty::queries::$name<$lt> as
QueryConfig>::Value
- where T: IntoDefId,
+ where T: IntoArgs,
{
- let $def_id = def_id_arg.into_def_id();
+ #[allow(unused_variables)]
+ let ($def_id, $other) = def_id_arg.into_args();
assert!(!$def_id.is_local());
let def_path_hash = $tcx.def_path_hash($def_id);
}
}
-trait IntoDefId {
- fn into_def_id(self) -> DefId;
+// small trait to work around different signature queries all being defined via
+// the macro above.
+trait IntoArgs {
+ fn into_args(self) -> (DefId, DefId);
}
-impl IntoDefId for DefId {
- fn into_def_id(self) -> DefId { self }
+impl IntoArgs for DefId {
+ fn into_args(self) -> (DefId, DefId) { (self, self) }
}
-impl IntoDefId for CrateNum {
- fn into_def_id(self) -> DefId { self.as_def_id() }
+impl IntoArgs for CrateNum {
+ fn into_args(self) -> (DefId, DefId) { (self.as_def_id(), self.as_def_id()) }
}
-provide! { <'tcx> tcx, def_id, cdata,
+impl IntoArgs for (CrateNum, DefId) {
+ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
+}
+
+provide! { <'tcx> tcx, def_id, other, cdata,
type_of => { cdata.get_type(def_id.index, tcx) }
generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index)) }
predicates_of => { cdata.get_predicates(def_id.index, tcx) }
crate_disambiguator => { cdata.disambiguator() }
crate_hash => { cdata.hash() }
original_crate_name => { cdata.name() }
+
+ implementations_of_trait => {
+ let mut result = vec![];
+ let filter = Some(other);
+ cdata.get_implementations_for_trait(filter, &tcx.dep_graph, &mut result);
+ Rc::new(result)
+ }
+
+ all_trait_implementations => {
+ let mut result = vec![];
+ cdata.get_implementations_for_trait(None, &tcx.dep_graph, &mut result);
+ Rc::new(result)
+ }
}
pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
self.get_crate_data(def.krate).get_generics(def.index)
}
- fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
- {
- let mut result = vec![];
-
- self.iter_crate_data(|_, cdata| {
- cdata.get_implementations_for_trait(filter, &self.dep_graph, &mut result)
- });
- result
- }
-
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
{
self.read_dep_node(def);
cx.populated_all_crate_impls.set(true);
- for did in tcx.sess.cstore.implementations_of_trait(None) {
- build_impl(cx, did, &mut impls);
+ for cnum in tcx.sess.cstore.crates() {
+ for did in tcx.all_trait_implementations(cnum).iter() {
+ build_impl(cx, *did, &mut impls);
+ }
}
// Also try to inline primitive impls from other crates.