1
Fork 0

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:
Alex Crichton 2017-08-31 11:30:22 -07:00
parent 84ae4b75be
commit 88399a985a
6 changed files with 91 additions and 75 deletions

View file

@ -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 {

View file

@ -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") }

View file

@ -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 {

View file

@ -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
}

View file

@ -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,
}
}

View file

@ -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()
}
}