]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Migrate `visible_parent_map` to a query
authorAlex Crichton <alex@alexcrichton.com>
Thu, 31 Aug 2017 18:30:22 +0000 (11:30 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 5 Sep 2017 14:37:58 +0000 (07:37 -0700)
Turns out it was basically already a query if you squinted hard enough!

src/librustc/dep_graph/dep_node.rs
src/librustc/middle/cstore.rs
src/librustc/ty/item_path.rs
src/librustc/ty/maps.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/cstore_impl.rs

index d6aa9cb341ee9d5f0033e590ebbbb58b6eddcfca..e5ed5df02609e326a124c3f3cc99e64b826fee03 100644 (file)
@@ -564,6 +564,9 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
     [] DefinedLangItems(CrateNum),
     [] MissingLangItems(CrateNum),
     [] ItemBody(DefId),
+    [] VisibleParentMap,
+    [] IsDirectExternCrate(CrateNum),
+    [] MissingExternCrateItem(CrateNum),
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
index f71a08280c63ce7eafc6e9fcde37022f921c00a3..e21de424d7e32ea69222ab96da6abea036ef793b 100644 (file)
@@ -31,7 +31,7 @@
 use ty::{self, TyCtxt};
 use session::Session;
 use session::search_paths::PathKind;
-use util::nodemap::{NodeSet, DefIdMap};
+use util::nodemap::NodeSet;
 
 use std::any::Any;
 use std::path::{Path, PathBuf};
@@ -235,7 +235,6 @@ pub trait CrateStore {
     fn metadata_loader(&self) -> &MetadataLoader;
 
     // item info
-    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/impl-item info
@@ -309,11 +308,6 @@ fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>
         { bug!("crate_data_as_rc_any") }
     // item info
     fn visibility_untracked(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
-    fn visible_parent_map<'a>(&'a self, session: &Session)
-        -> ::std::cell::Ref<'a, DefIdMap<DefId>>
-    {
-        bug!("visible_parent_map")
-    }
     fn item_generics_cloned(&self, def: DefId) -> ty::Generics
         { bug!("item_generics_cloned") }
 
index eadf80871fc95e3ee2742c5971f575235b7347de..75cf792d8ab40b59191d72af5130e460a570d844 100644 (file)
@@ -128,7 +128,7 @@ pub fn push_krate_path<T>(self, buffer: &mut T, cnum: CrateNum)
     pub fn try_push_visible_item_path<T>(self, buffer: &mut T, external_def_id: DefId) -> bool
         where T: ItemPathBuffer
     {
-        let visible_parent_map = self.sess.cstore.visible_parent_map(self.sess);
+        let visible_parent_map = self.visible_parent_map(LOCAL_CRATE);
 
         let (mut cur_def, mut cur_path) = (external_def_id, Vec::<ast::Name>::new());
         loop {
index 751beb4d0e9f10b9a36ecb2927ad5bd8b179fbb6..acf3aeec1432c6d1ca433cbe01c1201da1b32b11 100644 (file)
@@ -33,7 +33,7 @@
 use ty::steal::Steal;
 use ty::subst::Substs;
 use ty::fast_reject::SimplifiedType;
-use util::nodemap::{DefIdSet, NodeSet};
+use util::nodemap::{DefIdSet, NodeSet, DefIdMap};
 use util::common::{profq_msg, ProfileQueriesMsg};
 
 use rustc_data_structures::indexed_set::IdxSetBuf;
@@ -706,6 +706,18 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::visible_parent_map<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the visible parent map")
+    }
+}
+
+impl<'tcx> QueryDescription for queries::missing_extern_crate_item<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("seeing if we're missing an `extern crate` item for this crate")
+    }
+}
+
 // If enabled, send a message to the profile-queries thread
 macro_rules! profq_msg {
     ($tcx:expr, $msg:expr) => {
@@ -1316,6 +1328,9 @@ fn default() -> Self {
     [] defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>,
     [] missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
     [] item_body: ItemBody(DefId) -> &'tcx hir::Body,
+    [] visible_parent_map: visible_parent_map_node(CrateNum)
+        -> Rc<DefIdMap<DefId>>,
+    [] missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
 }
 
 fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@@ -1409,3 +1424,7 @@ fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
 fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::GetLangItems
 }
+
+fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::VisibleParentMap
+}
index 543d257018d0aaf0b03dd3735d9c2a728daba439..362fbf797430f464a4bfc21fcace60eb2a0b4d57 100644 (file)
@@ -20,7 +20,7 @@
 use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
 use rustc_back::PanicStrategy;
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
+use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
 
 use std::cell::{RefCell, Cell};
 use std::rc::Rc;
@@ -95,7 +95,6 @@ pub struct CStore {
     metas: RefCell<FxHashMap<CrateNum, Rc<CrateMetadata>>>,
     /// Map from NodeId's of local extern crate statements to crate numbers
     extern_mod_crate_map: RefCell<NodeMap<CrateNum>>,
-    pub visible_parent_map: RefCell<DefIdMap<DefId>>,
     pub metadata_loader: Box<MetadataLoader>,
 }
 
@@ -105,7 +104,6 @@ pub fn new(dep_graph: &DepGraph, metadata_loader: Box<MetadataLoader>) -> CStore
             dep_graph: dep_graph.clone(),
             metas: RefCell::new(FxHashMap()),
             extern_mod_crate_map: RefCell::new(FxHashMap()),
-            visible_parent_map: RefCell::new(FxHashMap()),
             metadata_loader,
         }
     }
index 7675a4f6e5fcbc1bbee5380403b3893fa79c1757..90bccf92b19bfb50a1b0530ea86c7c91cf9cc6c6 100644 (file)
@@ -222,6 +222,13 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
         debug!("item_body({:?}): inlining item", def_id);
         cdata.item_body(tcx, def_id.index)
     }
+
+    missing_extern_crate_item => {
+        match cdata.extern_crate.get() {
+            Some(extern_crate) if !extern_crate.direct => true,
+            _ => false,
+        }
+    }
 }
 
 pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
@@ -267,6 +274,64 @@ fn is_const_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
             let id = tcx.hir.definitions().find_node_for_hir_id(id);
             tcx.sess.cstore.extern_mod_stmt_cnum_untracked(id)
         },
+
+        // Returns a map from a sufficiently visible external item (i.e. an
+        // external item that is visible from at least one local module) to a
+        // sufficiently visible parent (considering modules that re-export the
+        // external item to be parents).
+        visible_parent_map: |tcx, cnum| {
+            use std::collections::vec_deque::VecDeque;
+            use std::collections::hash_map::Entry;
+
+            assert_eq!(cnum, LOCAL_CRATE);
+            let mut visible_parent_map: DefIdMap<DefId> = DefIdMap();
+
+            for cnum in tcx.sess.cstore.crates() {
+                // Ignore crates without a corresponding local `extern crate` item.
+                if tcx.missing_extern_crate_item(cnum) {
+                    continue
+                }
+
+                let bfs_queue = &mut VecDeque::new();
+                let visible_parent_map = &mut visible_parent_map;
+                let mut add_child = |bfs_queue: &mut VecDeque<_>,
+                                     child: &def::Export,
+                                     parent: DefId| {
+                    let child = child.def.def_id();
+
+                    if tcx.visibility(child) != ty::Visibility::Public {
+                        return;
+                    }
+
+                    match visible_parent_map.entry(child) {
+                        Entry::Occupied(mut entry) => {
+                            // If `child` is defined in crate `cnum`, ensure
+                            // that it is mapped to a parent in `cnum`.
+                            if child.krate == cnum && entry.get().krate != cnum {
+                                entry.insert(parent);
+                            }
+                        }
+                        Entry::Vacant(entry) => {
+                            entry.insert(parent);
+                            bfs_queue.push_back(child);
+                        }
+                    }
+                };
+
+                bfs_queue.push_back(DefId {
+                    krate: cnum,
+                    index: CRATE_DEF_INDEX
+                });
+                while let Some(def) = bfs_queue.pop_front() {
+                    for child in tcx.item_children(def).iter() {
+                        add_child(bfs_queue, child, def);
+                    }
+                }
+            }
+
+            Rc::new(visible_parent_map)
+        },
+
         ..*providers
     };
 }
@@ -440,67 +505,4 @@ fn metadata_encoding_version(&self) -> &[u8]
     {
         schema::METADATA_HEADER
     }
-
-    /// Returns a map from a sufficiently visible external item (i.e. an external item that is
-    /// visible from at least one local module) to a sufficiently visible parent (considering
-    /// modules that re-export the external item to be parents).
-    fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
-        {
-            let visible_parent_map = self.visible_parent_map.borrow();
-            if !visible_parent_map.is_empty() {
-                return visible_parent_map;
-            }
-        }
-
-        use std::collections::vec_deque::VecDeque;
-        use std::collections::hash_map::Entry;
-
-        let mut visible_parent_map = self.visible_parent_map.borrow_mut();
-
-        for cnum in (1 .. self.next_crate_num().as_usize()).map(CrateNum::new) {
-            let cdata = self.get_crate_data(cnum);
-
-            match cdata.extern_crate.get() {
-                // Ignore crates without a corresponding local `extern crate` item.
-                Some(extern_crate) if !extern_crate.direct => continue,
-                _ => {},
-            }
-
-            let bfs_queue = &mut VecDeque::new();
-            let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
-                let child = child.def.def_id();
-
-                if self.visibility_untracked(child) != ty::Visibility::Public {
-                    return;
-                }
-
-                match visible_parent_map.entry(child) {
-                    Entry::Occupied(mut entry) => {
-                        // If `child` is defined in crate `cnum`, ensure
-                        // that it is mapped to a parent in `cnum`.
-                        if child.krate == cnum && entry.get().krate != cnum {
-                            entry.insert(parent);
-                        }
-                    }
-                    Entry::Vacant(entry) => {
-                        entry.insert(parent);
-                        bfs_queue.push_back(child);
-                    }
-                }
-            };
-
-            bfs_queue.push_back(DefId {
-                krate: cnum,
-                index: CRATE_DEF_INDEX
-            });
-            while let Some(def) = bfs_queue.pop_front() {
-                for child in self.item_children_untracked(def, sess) {
-                    add_child(bfs_queue, child, def);
-                }
-            }
-        }
-
-        drop(visible_parent_map);
-        self.visible_parent_map.borrow()
-    }
 }