]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Move implementations_of_trait to a query
authorAlex Crichton <alex@alexcrichton.com>
Wed, 30 Aug 2017 18:40:02 +0000 (11:40 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 5 Sep 2017 14:37:28 +0000 (07:37 -0700)
While we're at it, make it two separate queries so one's for rustdoc and one's
for the compiler, hopefully being a bit more targeted.

src/librustc/dep_graph/dep_node.rs
src/librustc/middle/cstore.rs
src/librustc/ty/maps.rs
src/librustc/ty/trait_def.rs
src/librustc_metadata/cstore_impl.rs
src/librustdoc/clean/inline.rs

index c3285a7ac0470a12d3caaa3cdb03a2b4d470d4dd..a3e38e5b8ad77288905174c3dd3c2038284e1b2f 100644 (file)
@@ -542,6 +542,9 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
     [] CrateDisambiguator(CrateNum),
     [] CrateHash(CrateNum),
     [] OriginalCrateName(CrateNum),
+
+    [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
+    [] AllTraitImplementations(CrateNum),
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
index aa84682821edcdf8d576e3d0167150b99dc78840..495b357b613d8409abc5b4bf1f7a51a5e6a8cf92 100644 (file)
@@ -233,9 +233,6 @@ pub trait CrateStore {
     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;
 
@@ -328,9 +325,6 @@ fn visible_parent_map<'a>(&'a self, session: &Session)
     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") }
index 4b37b2aa7ec672ac49af9c84bebd8325a249c336..41caaa30b5c8d7fd5756120dd984d5806766ba3c 100644 (file)
@@ -630,6 +630,18 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
     }
 }
 
+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) => {
@@ -1213,6 +1225,11 @@ fn default() -> Self {
     [] 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> {
@@ -1292,3 +1309,9 @@ fn lint_levels_node<'tcx>(_: CrateNum) -> 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 }
+}
index 9990472c6b4caa60eb52ff8019f4a42ae2141326..4687fc654092449cd8c359d1b0a7eaa4d161a493 100644 (file)
@@ -141,13 +141,16 @@ pub fn for_each_relevant_impl<F: FnMut(DefId)>(self,
 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();
index e08f0f2c752dfaf057ef871bbaec80935883a775..67fe62d69beea6ef4111136603bbf489a12849af 100644 (file)
 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);
@@ -71,19 +73,25 @@ pub fn provide<$lt>(providers: &mut Providers<$lt>) {
     }
 }
 
-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) }
@@ -178,6 +186,19 @@ fn into_def_id(self) -> DefId { self.as_def_id() }
     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>) {
@@ -217,16 +238,6 @@ fn item_generics_cloned(&self, def: DefId) -> ty::Generics {
         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);
index 5d39d1d27f4c321ee47ecc380cbffc2a828efe13..bd49e46f6fb54a40480bac64eccceb8841f1d0e0 100644 (file)
@@ -236,8 +236,10 @@ pub fn build_impls(cx: &DocContext, did: DefId) -> Vec<clean::Item> {
 
     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.