[] DefinedLangItems(CrateNum),
[] MissingLangItems(CrateNum),
[] ItemBody(DefId),
+ [] VisibleParentMap,
+ [] IsDirectExternCrate(CrateNum),
+ [] MissingExternCrateItem(CrateNum),
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
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};
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
{ 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") }
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 {
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;
}
}
+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) => {
[] 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> {
fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::GetLangItems
}
+
+fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+ DepConstructor::VisibleParentMap
+}
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;
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>,
}
dep_graph: dep_graph.clone(),
metas: RefCell::new(FxHashMap()),
extern_mod_crate_map: RefCell::new(FxHashMap()),
- visible_parent_map: RefCell::new(FxHashMap()),
metadata_loader,
}
}
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>) {
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
};
}
{
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()
- }
}