Skip to content

Commit 88399a9

Browse files
committed
rustc: Migrate visible_parent_map to a query
Turns out it was basically already a query if you squinted hard enough!
1 parent 84ae4b7 commit 88399a9

File tree

6 files changed

+91
-75
lines changed

6 files changed

+91
-75
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,9 @@ define_dep_nodes!( <'tcx>
564564
[] DefinedLangItems(CrateNum),
565565
[] MissingLangItems(CrateNum),
566566
[] ItemBody(DefId),
567+
[] VisibleParentMap,
568+
[] IsDirectExternCrate(CrateNum),
569+
[] MissingExternCrateItem(CrateNum),
567570
);
568571

569572
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/middle/cstore.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ich;
3131
use ty::{self, TyCtxt};
3232
use session::Session;
3333
use session::search_paths::PathKind;
34-
use util::nodemap::{NodeSet, DefIdMap};
34+
use util::nodemap::NodeSet;
3535

3636
use std::any::Any;
3737
use std::path::{Path, PathBuf};
@@ -235,7 +235,6 @@ pub trait CrateStore {
235235
fn metadata_loader(&self) -> &MetadataLoader;
236236

237237
// item info
238-
fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
239238
fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
240239

241240
// trait/impl-item info
@@ -309,11 +308,6 @@ impl CrateStore for DummyCrateStore {
309308
{ bug!("crate_data_as_rc_any") }
310309
// item info
311310
fn visibility_untracked(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
312-
fn visible_parent_map<'a>(&'a self, session: &Session)
313-
-> ::std::cell::Ref<'a, DefIdMap<DefId>>
314-
{
315-
bug!("visible_parent_map")
316-
}
317311
fn item_generics_cloned(&self, def: DefId) -> ty::Generics
318312
{ bug!("item_generics_cloned") }
319313

src/librustc/ty/item_path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
128128
pub fn try_push_visible_item_path<T>(self, buffer: &mut T, external_def_id: DefId) -> bool
129129
where T: ItemPathBuffer
130130
{
131-
let visible_parent_map = self.sess.cstore.visible_parent_map(self.sess);
131+
let visible_parent_map = self.visible_parent_map(LOCAL_CRATE);
132132

133133
let (mut cur_def, mut cur_path) = (external_def_id, Vec::<ast::Name>::new());
134134
loop {

src/librustc/ty/maps.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use ty::item_path;
3333
use ty::steal::Steal;
3434
use ty::subst::Substs;
3535
use ty::fast_reject::SimplifiedType;
36-
use util::nodemap::{DefIdSet, NodeSet};
36+
use util::nodemap::{DefIdSet, NodeSet, DefIdMap};
3737
use util::common::{profq_msg, ProfileQueriesMsg};
3838

3939
use rustc_data_structures::indexed_set::IdxSetBuf;
@@ -706,6 +706,18 @@ impl<'tcx> QueryDescription for queries::missing_lang_items<'tcx> {
706706
}
707707
}
708708

709+
impl<'tcx> QueryDescription for queries::visible_parent_map<'tcx> {
710+
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
711+
format!("calculating the visible parent map")
712+
}
713+
}
714+
715+
impl<'tcx> QueryDescription for queries::missing_extern_crate_item<'tcx> {
716+
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
717+
format!("seeing if we're missing an `extern crate` item for this crate")
718+
}
719+
}
720+
709721
// If enabled, send a message to the profile-queries thread
710722
macro_rules! profq_msg {
711723
($tcx:expr, $msg:expr) => {
@@ -1316,6 +1328,9 @@ define_maps! { <'tcx>
13161328
[] defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>,
13171329
[] missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
13181330
[] item_body: ItemBody(DefId) -> &'tcx hir::Body,
1331+
[] visible_parent_map: visible_parent_map_node(CrateNum)
1332+
-> Rc<DefIdMap<DefId>>,
1333+
[] missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
13191334
}
13201335

13211336
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> {
14091424
fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
14101425
DepConstructor::GetLangItems
14111426
}
1427+
1428+
fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
1429+
DepConstructor::VisibleParentMap
1430+
}

src/librustc_metadata/cstore.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc::hir::svh::Svh;
2020
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
2121
use rustc_back::PanicStrategy;
2222
use rustc_data_structures::indexed_vec::IndexVec;
23-
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
23+
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
2424

2525
use std::cell::{RefCell, Cell};
2626
use std::rc::Rc;
@@ -95,7 +95,6 @@ pub struct CStore {
9595
metas: RefCell<FxHashMap<CrateNum, Rc<CrateMetadata>>>,
9696
/// Map from NodeId's of local extern crate statements to crate numbers
9797
extern_mod_crate_map: RefCell<NodeMap<CrateNum>>,
98-
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
9998
pub metadata_loader: Box<MetadataLoader>,
10099
}
101100

@@ -105,7 +104,6 @@ impl CStore {
105104
dep_graph: dep_graph.clone(),
106105
metas: RefCell::new(FxHashMap()),
107106
extern_mod_crate_map: RefCell::new(FxHashMap()),
108-
visible_parent_map: RefCell::new(FxHashMap()),
109107
metadata_loader,
110108
}
111109
}

src/librustc_metadata/cstore_impl.rs

Lines changed: 65 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,13 @@ provide! { <'tcx> tcx, def_id, other, cdata,
222222
debug!("item_body({:?}): inlining item", def_id);
223223
cdata.item_body(tcx, def_id.index)
224224
}
225+
226+
missing_extern_crate_item => {
227+
match cdata.extern_crate.get() {
228+
Some(extern_crate) if !extern_crate.direct => true,
229+
_ => false,
230+
}
231+
}
225232
}
226233

227234
pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
@@ -267,6 +274,64 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
267274
let id = tcx.hir.definitions().find_node_for_hir_id(id);
268275
tcx.sess.cstore.extern_mod_stmt_cnum_untracked(id)
269276
},
277+
278+
// Returns a map from a sufficiently visible external item (i.e. an
279+
// external item that is visible from at least one local module) to a
280+
// sufficiently visible parent (considering modules that re-export the
281+
// external item to be parents).
282+
visible_parent_map: |tcx, cnum| {
283+
use std::collections::vec_deque::VecDeque;
284+
use std::collections::hash_map::Entry;
285+
286+
assert_eq!(cnum, LOCAL_CRATE);
287+
let mut visible_parent_map: DefIdMap<DefId> = DefIdMap();
288+
289+
for cnum in tcx.sess.cstore.crates() {
290+
// Ignore crates without a corresponding local `extern crate` item.
291+
if tcx.missing_extern_crate_item(cnum) {
292+
continue
293+
}
294+
295+
let bfs_queue = &mut VecDeque::new();
296+
let visible_parent_map = &mut visible_parent_map;
297+
let mut add_child = |bfs_queue: &mut VecDeque<_>,
298+
child: &def::Export,
299+
parent: DefId| {
300+
let child = child.def.def_id();
301+
302+
if tcx.visibility(child) != ty::Visibility::Public {
303+
return;
304+
}
305+
306+
match visible_parent_map.entry(child) {
307+
Entry::Occupied(mut entry) => {
308+
// If `child` is defined in crate `cnum`, ensure
309+
// that it is mapped to a parent in `cnum`.
310+
if child.krate == cnum && entry.get().krate != cnum {
311+
entry.insert(parent);
312+
}
313+
}
314+
Entry::Vacant(entry) => {
315+
entry.insert(parent);
316+
bfs_queue.push_back(child);
317+
}
318+
}
319+
};
320+
321+
bfs_queue.push_back(DefId {
322+
krate: cnum,
323+
index: CRATE_DEF_INDEX
324+
});
325+
while let Some(def) = bfs_queue.pop_front() {
326+
for child in tcx.item_children(def).iter() {
327+
add_child(bfs_queue, child, def);
328+
}
329+
}
330+
}
331+
332+
Rc::new(visible_parent_map)
333+
},
334+
270335
..*providers
271336
};
272337
}
@@ -440,67 +505,4 @@ impl CrateStore for cstore::CStore {
440505
{
441506
schema::METADATA_HEADER
442507
}
443-
444-
/// Returns a map from a sufficiently visible external item (i.e. an external item that is
445-
/// visible from at least one local module) to a sufficiently visible parent (considering
446-
/// modules that re-export the external item to be parents).
447-
fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
448-
{
449-
let visible_parent_map = self.visible_parent_map.borrow();
450-
if !visible_parent_map.is_empty() {
451-
return visible_parent_map;
452-
}
453-
}
454-
455-
use std::collections::vec_deque::VecDeque;
456-
use std::collections::hash_map::Entry;
457-
458-
let mut visible_parent_map = self.visible_parent_map.borrow_mut();
459-
460-
for cnum in (1 .. self.next_crate_num().as_usize()).map(CrateNum::new) {
461-
let cdata = self.get_crate_data(cnum);
462-
463-
match cdata.extern_crate.get() {
464-
// Ignore crates without a corresponding local `extern crate` item.
465-
Some(extern_crate) if !extern_crate.direct => continue,
466-
_ => {},
467-
}
468-
469-
let bfs_queue = &mut VecDeque::new();
470-
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
471-
let child = child.def.def_id();
472-
473-
if self.visibility_untracked(child) != ty::Visibility::Public {
474-
return;
475-
}
476-
477-
match visible_parent_map.entry(child) {
478-
Entry::Occupied(mut entry) => {
479-
// If `child` is defined in crate `cnum`, ensure
480-
// that it is mapped to a parent in `cnum`.
481-
if child.krate == cnum && entry.get().krate != cnum {
482-
entry.insert(parent);
483-
}
484-
}
485-
Entry::Vacant(entry) => {
486-
entry.insert(parent);
487-
bfs_queue.push_back(child);
488-
}
489-
}
490-
};
491-
492-
bfs_queue.push_back(DefId {
493-
krate: cnum,
494-
index: CRATE_DEF_INDEX
495-
});
496-
while let Some(def) = bfs_queue.pop_front() {
497-
for child in self.item_children_untracked(def, sess) {
498-
add_child(bfs_queue, child, def);
499-
}
500-
}
501-
}
502-
503-
drop(visible_parent_map);
504-
self.visible_parent_map.borrow()
505-
}
506508
}

0 commit comments

Comments
 (0)