rustc: Migrate visible_parent_map
to a query
Turns out it was basically already a query if you squinted hard enough!
This commit is contained in:
parent
84ae4b75be
commit
88399a985a
6 changed files with 91 additions and 75 deletions
|
@ -564,6 +564,9 @@ define_dep_nodes!( <'tcx>
|
|||
[] DefinedLangItems(CrateNum),
|
||||
[] MissingLangItems(CrateNum),
|
||||
[] ItemBody(DefId),
|
||||
[] VisibleParentMap,
|
||||
[] IsDirectExternCrate(CrateNum),
|
||||
[] MissingExternCrateItem(CrateNum),
|
||||
);
|
||||
|
||||
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
|
||||
|
|
|
@ -31,7 +31,7 @@ use ich;
|
|||
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 @@ impl CrateStore for DummyCrateStore {
|
|||
{ 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") }
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
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 {
|
||||
|
|
|
@ -33,7 +33,7 @@ use ty::item_path;
|
|||
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 @@ impl<'tcx> QueryDescription for queries::missing_lang_items<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ define_maps! { <'tcx>
|
|||
[] 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
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use rustc::hir::svh::Svh;
|
|||
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 @@ impl 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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,6 +222,13 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
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 @@ 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
|
||||
};
|
||||
}
|
||||
|
@ -440,67 +505,4 @@ impl CrateStore for cstore::CStore {
|
|||
{
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue