rustc_metadata: split the Def description of a DefId from item_children.
This commit is contained in:
parent
adddfccf2b
commit
24aef24e1a
9 changed files with 95 additions and 109 deletions
|
@ -96,13 +96,6 @@ pub enum InlinedItemRef<'a> {
|
|||
ImplItem(DefId, &'a hir::ImplItem)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ChildItem {
|
||||
pub def: Def,
|
||||
pub name: ast::Name,
|
||||
pub vis: ty::Visibility,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct ExternCrate {
|
||||
/// def_id of an `extern crate` in the current crate that caused
|
||||
|
@ -128,6 +121,7 @@ pub struct ExternCrate {
|
|||
/// can be accessed.
|
||||
pub trait CrateStore<'tcx> {
|
||||
// item info
|
||||
fn describe_def(&self, def: DefId) -> Option<Def>;
|
||||
fn stability(&self, def: DefId) -> Option<attr::Stability>;
|
||||
fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
|
||||
fn visibility(&self, def: DefId) -> ty::Visibility;
|
||||
|
@ -209,7 +203,7 @@ pub trait CrateStore<'tcx> {
|
|||
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
|
||||
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
|
||||
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
|
||||
fn item_children(&self, did: DefId) -> Vec<ChildItem>;
|
||||
fn item_children(&self, did: DefId) -> Vec<def::Export>;
|
||||
|
||||
// misc. metadata
|
||||
fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
|
@ -286,6 +280,7 @@ pub struct DummyCrateStore;
|
|||
#[allow(unused_variables)]
|
||||
impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
||||
// item info
|
||||
fn describe_def(&self, def: DefId) -> Option<Def> { bug!("describe_def") }
|
||||
fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
|
||||
fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
|
||||
fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
|
||||
|
@ -386,7 +381,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
|
||||
{ bug!("struct_ctor_def_id") }
|
||||
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
|
||||
fn item_children(&self, did: DefId) -> Vec<ChildItem> { bug!("item_children") }
|
||||
fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }
|
||||
|
||||
// misc. metadata
|
||||
fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
|
|
|
@ -13,9 +13,9 @@ use common;
|
|||
use encoder;
|
||||
use loader;
|
||||
|
||||
use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate};
|
||||
use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, ExternCrate};
|
||||
use rustc::middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
|
||||
use rustc::hir::def;
|
||||
use rustc::hir::def::{self, Def};
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
|
@ -37,6 +37,11 @@ use rustc_back::target::Target;
|
|||
use rustc::hir;
|
||||
|
||||
impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||
fn describe_def(&self, def: DefId) -> Option<Def> {
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
self.get_crate_data(def.krate).get_def(def.index)
|
||||
}
|
||||
|
||||
fn stability(&self, def: DefId) -> Option<attr::Stability> {
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
self.get_crate_data(def.krate).get_stability(def.index)
|
||||
|
@ -158,10 +163,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId> {
|
||||
self.dep_graph.read(DepNode::MetaData(def_id));
|
||||
let mut result = vec![];
|
||||
let get_crate_data = &mut |cnum| self.get_crate_data(cnum);
|
||||
self.get_crate_data(def_id.krate)
|
||||
.each_child_of_item(def_id.index, get_crate_data,
|
||||
&mut |def, _, _| result.push(def.def_id()));
|
||||
.each_child_of_item(def_id.index, |child| result.push(child.def_id));
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -366,20 +369,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
self.get_crate_data(def.krate).get_struct_field_names(def.index)
|
||||
}
|
||||
|
||||
fn item_children(&self, def_id: DefId) -> Vec<ChildItem>
|
||||
fn item_children(&self, def_id: DefId) -> Vec<def::Export>
|
||||
{
|
||||
self.dep_graph.read(DepNode::MetaData(def_id));
|
||||
let mut result = vec![];
|
||||
let get_crate_data = &mut |cnum| self.get_crate_data(cnum);
|
||||
self.get_crate_data(def_id.krate)
|
||||
.each_child_of_item(def_id.index, get_crate_data,
|
||||
&mut |def, name, vis| {
|
||||
result.push(ChildItem {
|
||||
def: def,
|
||||
name: name,
|
||||
vis: vis
|
||||
});
|
||||
});
|
||||
.each_child_of_item(def_id.index, |child| result.push(child));
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -567,7 +562,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
let mut visible_parent_map = self.visible_parent_map.borrow_mut();
|
||||
if !visible_parent_map.is_empty() { return visible_parent_map; }
|
||||
|
||||
use rustc::middle::cstore::ChildItem;
|
||||
use std::collections::vec_deque::VecDeque;
|
||||
use std::collections::hash_map::Entry;
|
||||
for cnum in (1 .. self.next_crate_num().as_usize()).map(CrateNum::new) {
|
||||
|
@ -580,12 +574,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
}
|
||||
|
||||
let mut bfs_queue = &mut VecDeque::new();
|
||||
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: ChildItem, parent: DefId| {
|
||||
let child = if child.vis == ty::Visibility::Public {
|
||||
child.def.def_id()
|
||||
} else {
|
||||
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
|
||||
let child = child.def_id;
|
||||
|
||||
if self.visibility(child) != ty::Visibility::Public {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
match visible_parent_map.entry(child) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
|
|
|
@ -23,7 +23,7 @@ use rustc::hir;
|
|||
use rustc::hir::intravisit::IdRange;
|
||||
|
||||
use rustc::middle::cstore::{InlinedItem, LinkagePreference};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{self, Def};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::ty::{ImplContainer, TraitContainer};
|
||||
|
@ -505,6 +505,10 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
self.maybe_get(doc, item_tag::ty).map(|dcx| dcx.typed(tcx).decode())
|
||||
}
|
||||
|
||||
pub fn get_def(&self, index: DefIndex) -> Option<Def> {
|
||||
self.item_family(self.entry(index)).to_def(self.local_def_id(index))
|
||||
}
|
||||
|
||||
pub fn get_trait_def(&self,
|
||||
item_id: DefIndex,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::TraitDef<'tcx> {
|
||||
|
@ -664,11 +668,8 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
}
|
||||
|
||||
/// Iterates over each child of the given item.
|
||||
pub fn each_child_of_item<F, G>(&self, id: DefIndex,
|
||||
mut get_crate_data: &mut G,
|
||||
mut callback: &mut F)
|
||||
where F: FnMut(Def, ast::Name, ty::Visibility),
|
||||
G: FnMut(CrateNum) -> Rc<CrateMetadata>,
|
||||
pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
|
||||
where F: FnMut(def::Export)
|
||||
{
|
||||
// Find the item.
|
||||
let item_doc = match self.maybe_entry(id) {
|
||||
|
@ -682,15 +683,31 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
};
|
||||
|
||||
// Iterate over all children.
|
||||
for child_index in dcx.seq::<DefIndex>() {
|
||||
for child_index in dcx.seq() {
|
||||
// Get the item.
|
||||
if let Some(child) = self.maybe_entry(child_index) {
|
||||
// Hand off the item to the callback.
|
||||
let family = self.item_family(child);
|
||||
if let Family::ForeignMod = family {
|
||||
self.each_child_of_item(child_index, get_crate_data, callback);
|
||||
} else if let Some(def) = family.to_def(self.local_def_id(child_index)) {
|
||||
callback(def, self.item_name(child), self.item_visibility(child));
|
||||
match self.item_family(child) {
|
||||
// FIXME(eddyb) Don't encode these in children.
|
||||
Family::ForeignMod => {
|
||||
for child_index in self.get(child, item_tag::children).seq() {
|
||||
callback(def::Export {
|
||||
def_id: self.local_def_id(child_index),
|
||||
name: self.item_name(self.entry(child_index))
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Family::Impl | Family::DefaultImpl => continue,
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(name) = self.maybe_item_name(child) {
|
||||
callback(def::Export {
|
||||
def_id: self.local_def_id(child_index),
|
||||
name: name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,26 +717,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
_ => return
|
||||
};
|
||||
for exp in reexports {
|
||||
// This reexport may be in yet another crate.
|
||||
let crate_data = if exp.def_id.krate == self.cnum {
|
||||
None
|
||||
} else {
|
||||
Some(get_crate_data(exp.def_id.krate))
|
||||
};
|
||||
let crate_data = match crate_data {
|
||||
Some(ref cdata) => &**cdata,
|
||||
None => self
|
||||
};
|
||||
|
||||
// Get the item.
|
||||
if let Some(child) = crate_data.maybe_entry(exp.def_id.index) {
|
||||
// Hand off the item to the callback.
|
||||
if let Some(def) = self.item_family(child).to_def(exp.def_id) {
|
||||
// These items have a public visibility because they're part of
|
||||
// a public re-export.
|
||||
callback(def, exp.name, ty::Visibility::Public);
|
||||
}
|
||||
}
|
||||
callback(exp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -373,6 +373,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
fn encode_struct_ctor(&mut self, ctor_def_id: DefId) {
|
||||
self.encode_def_key(ctor_def_id);
|
||||
self.encode_family(Family::Struct);
|
||||
self.encode_visibility(ty::Visibility::Public);
|
||||
self.encode_bounds_and_type_for_item(ctor_def_id);
|
||||
|
||||
self.encode_stability(ctor_def_id);
|
||||
|
|
|
@ -21,7 +21,6 @@ use ParentLink::{ModuleParentLink, BlockParentLink};
|
|||
use Resolver;
|
||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
||||
|
||||
use rustc::middle::cstore::ChildItem;
|
||||
use rustc::hir::def::*;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use rustc::hir::map::DefPathData;
|
||||
|
@ -387,10 +386,22 @@ impl<'b> Resolver<'b> {
|
|||
}
|
||||
|
||||
/// Builds the reduced graph for a single item in an external crate.
|
||||
fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, child: ChildItem) {
|
||||
let def = child.def;
|
||||
fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
|
||||
child: Export) {
|
||||
let def_id = child.def_id;
|
||||
let name = child.name;
|
||||
let vis = if parent.is_trait() { ty::Visibility::Public } else { child.vis };
|
||||
|
||||
let def = if let Some(def) = self.session.cstore.describe_def(def_id) {
|
||||
def
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let vis = if parent.is_trait() {
|
||||
ty::Visibility::Public
|
||||
} else {
|
||||
self.session.cstore.visibility(def_id)
|
||||
};
|
||||
|
||||
match def {
|
||||
Def::Mod(_) | Def::Enum(..) => {
|
||||
|
@ -416,7 +427,7 @@ impl<'b> Resolver<'b> {
|
|||
name);
|
||||
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
|
||||
}
|
||||
Def::Trait(def_id) => {
|
||||
Def::Trait(_) => {
|
||||
debug!("(building reduced graph for external crate) building type {}", name);
|
||||
|
||||
// If this is a trait, add all the trait item names to the trait
|
||||
|
@ -443,7 +454,7 @@ impl<'b> Resolver<'b> {
|
|||
debug!("(building reduced graph for external crate) building type {}", name);
|
||||
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
|
||||
}
|
||||
Def::Struct(def_id)
|
||||
Def::Struct(_)
|
||||
if self.session.cstore.def_key(def_id).disambiguated_data.data !=
|
||||
DefPathData::StructCtor
|
||||
=> {
|
||||
|
@ -459,7 +470,7 @@ impl<'b> Resolver<'b> {
|
|||
let fields = self.session.cstore.struct_field_names(def_id);
|
||||
self.structs.insert(def_id, fields);
|
||||
}
|
||||
Def::Union(def_id) => {
|
||||
Def::Union(_) => {
|
||||
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
|
||||
|
||||
// Record the def ID and fields of this union.
|
||||
|
|
|
@ -451,27 +451,27 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
|
|||
fn handle_external_def(ccx: &CrateCtxt,
|
||||
traits: &mut AllTraitsVec,
|
||||
external_mods: &mut FnvHashSet<DefId>,
|
||||
def: Def) {
|
||||
match def {
|
||||
Def::Trait(did) => {
|
||||
traits.push(TraitInfo::new(did));
|
||||
def_id: DefId) {
|
||||
match ccx.tcx.sess.cstore.describe_def(def_id) {
|
||||
Some(Def::Trait(_)) => {
|
||||
traits.push(TraitInfo::new(def_id));
|
||||
}
|
||||
Def::Mod(did) => {
|
||||
if !external_mods.insert(did) {
|
||||
Some(Def::Mod(_)) => {
|
||||
if !external_mods.insert(def_id) {
|
||||
return;
|
||||
}
|
||||
for child in ccx.tcx.sess.cstore.item_children(did) {
|
||||
handle_external_def(ccx, traits, external_mods, child.def)
|
||||
for child in ccx.tcx.sess.cstore.item_children(def_id) {
|
||||
handle_external_def(ccx, traits, external_mods, child.def_id)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
for cnum in ccx.tcx.sess.cstore.crates() {
|
||||
handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(DefId {
|
||||
handle_external_def(ccx, &mut traits, &mut external_mods, DefId {
|
||||
krate: cnum,
|
||||
index: CRATE_DEF_INDEX
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
*ccx.all_traits.borrow_mut() = Some(traits);
|
||||
|
|
|
@ -498,10 +498,12 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// visit each node at most once.
|
||||
let mut visited = FnvHashSet();
|
||||
for item in tcx.sess.cstore.item_children(did) {
|
||||
if item.vis == ty::Visibility::Public {
|
||||
if !visited.insert(item.def) { continue }
|
||||
if let Some(i) = try_inline_def(cx, tcx, item.def) {
|
||||
items.extend(i)
|
||||
if tcx.sess.cstore.visibility(item.def_id) == ty::Visibility::Public {
|
||||
if !visited.insert(item.def_id) { continue }
|
||||
if let Some(def) = tcx.sess.cstore.describe_def(item.def_id) {
|
||||
if let Some(i) = try_inline_def(cx, tcx, def) {
|
||||
items.extend(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,11 +240,7 @@ impl Clean<ExternalCrate> for CrateNum {
|
|||
let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
|
||||
cx.tcx_opt().map(|tcx| {
|
||||
for item in tcx.sess.cstore.item_children(root) {
|
||||
let did = match item.def {
|
||||
Def::Mod(did) => did,
|
||||
_ => continue
|
||||
};
|
||||
let attrs = inline::load_attrs(cx, tcx, did);
|
||||
let attrs = inline::load_attrs(cx, tcx, item.def_id);
|
||||
PrimitiveType::find(&attrs).map(|prim| primitives.push(prim));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::middle::cstore::{CrateStore, ChildItem};
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::middle::privacy::{AccessLevels, AccessLevel};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
|
||||
|
@ -64,38 +64,27 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn visit_mod(&mut self, did: DefId) {
|
||||
for item in self.cstore.item_children(did) {
|
||||
match item.def {
|
||||
Def::Mod(did) |
|
||||
Def::Trait(did) |
|
||||
Def::Struct(did) |
|
||||
Def::Union(did) |
|
||||
Def::Enum(did) |
|
||||
Def::TyAlias(did) |
|
||||
Def::Fn(did) |
|
||||
Def::Method(did) |
|
||||
Def::Static(did, _) |
|
||||
Def::Const(did) => self.visit_item(did, item),
|
||||
_ => {}
|
||||
}
|
||||
pub fn visit_mod(&mut self, def_id: DefId) {
|
||||
for item in self.cstore.item_children(def_id) {
|
||||
self.visit_item(item.def_id);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, did: DefId, item: ChildItem) {
|
||||
let inherited_item_level = if item.vis == Visibility::Public {
|
||||
fn visit_item(&mut self, def_id: DefId) {
|
||||
let vis = self.cstore.visibility(def_id);
|
||||
let inherited_item_level = if vis == Visibility::Public {
|
||||
self.prev_level
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let item_level = self.update(did, inherited_item_level);
|
||||
let item_level = self.update(def_id, inherited_item_level);
|
||||
|
||||
if let Def::Mod(did) = item.def {
|
||||
if let Some(Def::Mod(_)) = self.cstore.describe_def(def_id) {
|
||||
let orig_level = self.prev_level;
|
||||
|
||||
self.prev_level = item_level;
|
||||
self.visit_mod(did);
|
||||
self.visit_mod(def_id);
|
||||
self.prev_level = orig_level;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue