Auto merge of #38490 - jseyfried:def_id_vis, r=nrc

Use `DefId`s instead of `NodeId`s for `pub(restricted)` visibilities

This is groundwork for hygiene 2.0, specifically privacy checking hygienic intercrate name resolutions.
r? @nrc
This commit is contained in:
bors 2016-12-25 21:32:37 +00:00
commit 44ad63e487
12 changed files with 137 additions and 161 deletions

View File

@ -219,26 +219,18 @@ pub enum Visibility {
/// Visible everywhere (including in other crates). /// Visible everywhere (including in other crates).
Public, Public,
/// Visible only in the given crate-local module. /// Visible only in the given crate-local module.
Restricted(NodeId), Restricted(DefId),
/// Not visible anywhere in the local crate. This is the visibility of private external items. /// Not visible anywhere in the local crate. This is the visibility of private external items.
PrivateExternal, Invisible,
} }
pub trait NodeIdTree { pub trait DefIdTree: Copy {
fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool; fn parent(self, id: DefId) -> Option<DefId>;
} }
impl<'a> NodeIdTree for ast_map::Map<'a> { impl<'a, 'gcx, 'tcx> DefIdTree for TyCtxt<'a, 'gcx, 'tcx> {
fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool { fn parent(self, id: DefId) -> Option<DefId> {
let mut node_ancestor = node; self.def_key(id).parent.map(|index| DefId { index: index, ..id })
while node_ancestor != ancestor {
let node_ancestor_parent = self.get_module_parent(node_ancestor);
if node_ancestor_parent == node_ancestor {
return false;
}
node_ancestor = node_ancestor_parent;
}
true
} }
} }
@ -246,36 +238,46 @@ impl Visibility {
pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self { pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
match *visibility { match *visibility {
hir::Public => Visibility::Public, hir::Public => Visibility::Public,
hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID), hir::Visibility::Crate => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
hir::Visibility::Restricted { ref path, .. } => match path.def { hir::Visibility::Restricted { ref path, .. } => match path.def {
// If there is no resolution, `resolve` will have already reported an error, so // If there is no resolution, `resolve` will have already reported an error, so
// assume that the visibility is public to avoid reporting more privacy errors. // assume that the visibility is public to avoid reporting more privacy errors.
Def::Err => Visibility::Public, Def::Err => Visibility::Public,
def => Visibility::Restricted(tcx.map.as_local_node_id(def.def_id()).unwrap()), def => Visibility::Restricted(def.def_id()),
}, },
hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)), hir::Inherited => {
Visibility::Restricted(tcx.map.local_def_id(tcx.map.get_module_parent(id)))
}
} }
} }
/// Returns true if an item with this visibility is accessible from the given block. /// Returns true if an item with this visibility is accessible from the given block.
pub fn is_accessible_from<T: NodeIdTree>(self, block: NodeId, tree: &T) -> bool { pub fn is_accessible_from<T: DefIdTree>(self, mut module: DefId, tree: T) -> bool {
let restriction = match self { let restriction = match self {
// Public items are visible everywhere. // Public items are visible everywhere.
Visibility::Public => return true, Visibility::Public => return true,
// Private items from other crates are visible nowhere. // Private items from other crates are visible nowhere.
Visibility::PrivateExternal => return false, Visibility::Invisible => return false,
// Restricted items are visible in an arbitrary local module. // Restricted items are visible in an arbitrary local module.
Visibility::Restricted(other) if other.krate != module.krate => return false,
Visibility::Restricted(module) => module, Visibility::Restricted(module) => module,
}; };
tree.is_descendant_of(block, restriction) while module != restriction {
match tree.parent(module) {
Some(parent) => module = parent,
None => return false,
}
}
true
} }
/// Returns true if this visibility is at least as accessible as the given visibility /// Returns true if this visibility is at least as accessible as the given visibility
pub fn is_at_least<T: NodeIdTree>(self, vis: Visibility, tree: &T) -> bool { pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
let vis_restriction = match vis { let vis_restriction = match vis {
Visibility::Public => return self == Visibility::Public, Visibility::Public => return self == Visibility::Public,
Visibility::PrivateExternal => return true, Visibility::Invisible => return true,
Visibility::Restricted(module) => module, Visibility::Restricted(module) => module,
}; };
@ -1779,7 +1781,7 @@ pub fn is_uninhabited_recurse(&self,
block: Option<NodeId>, block: Option<NodeId>,
tcx: TyCtxt<'a, 'gcx, 'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>,
substs: &'tcx Substs<'tcx>) -> bool { substs: &'tcx Substs<'tcx>) -> bool {
block.map_or(true, |b| self.vis.is_accessible_from(b, &tcx.map)) && block.map_or(true, |b| tcx.vis_is_accessible_from(self.vis, b)) &&
self.ty(tcx, substs).is_uninhabited_recurse(visited, block, tcx) self.ty(tcx, substs).is_uninhabited_recurse(visited, block, tcx)
} }
} }
@ -2266,6 +2268,10 @@ pub fn def_span(self, def_id: DefId) -> Span {
} }
} }
pub fn vis_is_accessible_from(self, vis: Visibility, block: NodeId) -> bool {
vis.is_accessible_from(self.map.local_def_id(self.map.get_module_parent(block)), self)
}
pub fn item_name(self, id: DefId) -> ast::Name { pub fn item_name(self, id: DefId) -> ast::Name {
if let Some(id) = self.map.as_local_node_id(id) { if let Some(id) = self.map.as_local_node_id(id) {
self.map.name(id) self.map.name(id)

View File

@ -588,7 +588,7 @@ fn get_variant(&self,
ty::FieldDef { ty::FieldDef {
did: self.local_def_id(index), did: self.local_def_id(index),
name: self.item_name(index), name: self.item_name(index),
vis: f.visibility vis: f.visibility.decode(self)
} }
}).collect(), }).collect(),
disr_val: ConstInt::Infer(data.disr), disr_val: ConstInt::Infer(data.disr),
@ -678,7 +678,7 @@ pub fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility { pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
match self.is_proc_macro(id) { match self.is_proc_macro(id) {
true => ty::Visibility::Public, true => ty::Visibility::Public,
false => self.entry(id).visibility, false => self.entry(id).visibility.decode(self),
} }
} }
@ -885,7 +885,7 @@ pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
ty::AssociatedItem { ty::AssociatedItem {
name: name, name: name,
kind: ty::AssociatedKind::Const, kind: ty::AssociatedKind::Const,
vis: item.visibility, vis: item.visibility.decode(self),
defaultness: container.defaultness(), defaultness: container.defaultness(),
def_id: self.local_def_id(id), def_id: self.local_def_id(id),
container: container.with_def_id(parent), container: container.with_def_id(parent),
@ -898,7 +898,7 @@ pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
ty::AssociatedItem { ty::AssociatedItem {
name: name, name: name,
kind: ty::AssociatedKind::Method, kind: ty::AssociatedKind::Method,
vis: item.visibility, vis: item.visibility.decode(self),
defaultness: data.container.defaultness(), defaultness: data.container.defaultness(),
def_id: self.local_def_id(id), def_id: self.local_def_id(id),
container: data.container.with_def_id(parent), container: data.container.with_def_id(parent),
@ -910,7 +910,7 @@ pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
ty::AssociatedItem { ty::AssociatedItem {
name: name, name: name,
kind: ty::AssociatedKind::Type, kind: ty::AssociatedKind::Type,
vis: item.visibility, vis: item.visibility.decode(self),
defaultness: container.defaultness(), defaultness: container.defaultness(),
def_id: self.local_def_id(id), def_id: self.local_def_id(id),
container: container.with_def_id(parent), container: container.with_def_id(parent),

View File

@ -268,7 +268,7 @@ fn encode_enum_variant_info(&mut self,
Entry { Entry {
kind: EntryKind::Variant(self.lazy(&data)), kind: EntryKind::Variant(self.lazy(&data)),
visibility: enum_vis.simplify(), visibility: self.lazy(&ty::Visibility::from_hir(enum_vis, enum_id, tcx)),
span: self.lazy(&tcx.def_span(def_id)), span: self.lazy(&tcx.def_span(def_id)),
attributes: self.encode_attributes(&tcx.get_attrs(def_id)), attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
children: self.lazy_seq(variant.fields.iter().map(|f| { children: self.lazy_seq(variant.fields.iter().map(|f| {
@ -306,7 +306,7 @@ fn encode_info_for_mod(&mut self,
Entry { Entry {
kind: EntryKind::Mod(self.lazy(&data)), kind: EntryKind::Mod(self.lazy(&data)),
visibility: vis.simplify(), visibility: self.lazy(&ty::Visibility::from_hir(vis, id, tcx)),
span: self.lazy(&md.inner), span: self.lazy(&md.inner),
attributes: self.encode_attributes(attrs), attributes: self.encode_attributes(attrs),
children: self.lazy_seq(md.item_ids.iter().map(|item_id| { children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
@ -327,30 +327,6 @@ fn encode_info_for_mod(&mut self,
} }
} }
trait Visibility {
fn simplify(&self) -> ty::Visibility;
}
impl Visibility for hir::Visibility {
fn simplify(&self) -> ty::Visibility {
if *self == hir::Public {
ty::Visibility::Public
} else {
ty::Visibility::PrivateExternal
}
}
}
impl Visibility for ty::Visibility {
fn simplify(&self) -> ty::Visibility {
if *self == ty::Visibility::Public {
ty::Visibility::Public
} else {
ty::Visibility::PrivateExternal
}
}
}
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
fn encode_fields(&mut self, adt_def_id: DefId) { fn encode_fields(&mut self, adt_def_id: DefId) {
let def = self.tcx.lookup_adt_def(adt_def_id); let def = self.tcx.lookup_adt_def(adt_def_id);
@ -386,7 +362,7 @@ fn encode_field(&mut self,
Entry { Entry {
kind: EntryKind::Field, kind: EntryKind::Field,
visibility: field.vis.simplify(), visibility: self.lazy(&field.vis),
span: self.lazy(&tcx.def_span(def_id)), span: self.lazy(&tcx.def_span(def_id)),
attributes: self.encode_attributes(&variant_data.fields()[field_index].attrs), attributes: self.encode_attributes(&variant_data.fields()[field_index].attrs),
children: LazySeq::empty(), children: LazySeq::empty(),
@ -419,7 +395,7 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
Entry { Entry {
kind: EntryKind::Struct(self.lazy(&data)), kind: EntryKind::Struct(self.lazy(&data)),
visibility: struct_vis.simplify(), visibility: self.lazy(&ty::Visibility::from_hir(struct_vis, struct_id, tcx)),
span: self.lazy(&tcx.def_span(def_id)), span: self.lazy(&tcx.def_span(def_id)),
attributes: LazySeq::empty(), attributes: LazySeq::empty(),
children: LazySeq::empty(), children: LazySeq::empty(),
@ -485,7 +461,7 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
Entry { Entry {
kind: kind, kind: kind,
visibility: trait_item.vis.simplify(), visibility: self.lazy(&trait_item.vis),
span: self.lazy(&ast_item.span), span: self.lazy(&ast_item.span),
attributes: self.encode_attributes(&ast_item.attrs), attributes: self.encode_attributes(&ast_item.attrs),
children: LazySeq::empty(), children: LazySeq::empty(),
@ -574,7 +550,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
Entry { Entry {
kind: kind, kind: kind,
visibility: impl_item.vis.simplify(), visibility: self.lazy(&impl_item.vis),
span: self.lazy(&ast_item.span), span: self.lazy(&ast_item.span),
attributes: self.encode_attributes(&ast_item.attrs), attributes: self.encode_attributes(&ast_item.attrs),
children: LazySeq::empty(), children: LazySeq::empty(),
@ -736,7 +712,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
Entry { Entry {
kind: kind, kind: kind,
visibility: item.vis.simplify(), visibility: self.lazy(&ty::Visibility::from_hir(&item.vis, item.id, tcx)),
span: self.lazy(&item.span), span: self.lazy(&item.span),
attributes: self.encode_attributes(&item.attrs), attributes: self.encode_attributes(&item.attrs),
children: match item.node { children: match item.node {
@ -849,7 +825,7 @@ fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx
kind: EntryKind::MacroDef(self.lazy(&MacroDef { kind: EntryKind::MacroDef(self.lazy(&MacroDef {
body: ::syntax::print::pprust::tts_to_string(&macro_def.body) body: ::syntax::print::pprust::tts_to_string(&macro_def.body)
})), })),
visibility: ty::Visibility::Public, visibility: self.lazy(&ty::Visibility::Public),
span: self.lazy(&macro_def.span), span: self.lazy(&macro_def.span),
attributes: self.encode_attributes(&macro_def.attrs), attributes: self.encode_attributes(&macro_def.attrs),
@ -950,7 +926,7 @@ fn encode_info_for_foreign_item(&mut self,
Entry { Entry {
kind: kind, kind: kind,
visibility: nitem.vis.simplify(), visibility: self.lazy(&ty::Visibility::from_hir(&nitem.vis, nitem.id, tcx)),
span: self.lazy(&nitem.span), span: self.lazy(&nitem.span),
attributes: self.encode_attributes(&nitem.attrs), attributes: self.encode_attributes(&nitem.attrs),
children: LazySeq::empty(), children: LazySeq::empty(),
@ -1032,7 +1008,7 @@ fn encode_info_for_anon_ty(&mut self, def_id: DefId) -> Entry<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
Entry { Entry {
kind: EntryKind::Type, kind: EntryKind::Type,
visibility: ty::Visibility::Public, visibility: self.lazy(&ty::Visibility::Public),
span: self.lazy(&tcx.def_span(def_id)), span: self.lazy(&tcx.def_span(def_id)),
attributes: LazySeq::empty(), attributes: LazySeq::empty(),
children: LazySeq::empty(), children: LazySeq::empty(),
@ -1060,7 +1036,7 @@ fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
Entry { Entry {
kind: EntryKind::Closure(self.lazy(&data)), kind: EntryKind::Closure(self.lazy(&data)),
visibility: ty::Visibility::Public, visibility: self.lazy(&ty::Visibility::Public),
span: self.lazy(&tcx.def_span(def_id)), span: self.lazy(&tcx.def_span(def_id)),
attributes: self.encode_attributes(&tcx.get_attrs(def_id)), attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
children: LazySeq::empty(), children: LazySeq::empty(),

View File

@ -201,7 +201,7 @@ pub struct TraitImpls {
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct Entry<'tcx> { pub struct Entry<'tcx> {
pub kind: EntryKind<'tcx>, pub kind: EntryKind<'tcx>,
pub visibility: ty::Visibility, pub visibility: Lazy<ty::Visibility>,
pub span: Lazy<Span>, pub span: Lazy<Span>,
pub attributes: LazySeq<ast::Attribute>, pub attributes: LazySeq<ast::Attribute>,
pub children: LazySeq<DefIndex>, pub children: LazySeq<DefIndex>,

View File

@ -28,7 +28,7 @@
use rustc::dep_graph::DepNode; use rustc::dep_graph::DepNode;
use rustc::hir::{self, PatKind}; use rustc::hir::{self, PatKind};
use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::DefId; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor; use rustc::hir::itemlikevisit::DeepVisitor;
use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@ -391,7 +391,7 @@ fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
struct PrivacyVisitor<'a, 'tcx: 'a> { struct PrivacyVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
curitem: ast::NodeId, curitem: DefId,
in_foreign: bool, in_foreign: bool,
} }
@ -401,12 +401,12 @@ fn item_is_accessible(&self, did: DefId) -> bool {
Some(node_id) => Some(node_id) =>
ty::Visibility::from_hir(&self.tcx.map.expect_item(node_id).vis, node_id, self.tcx), ty::Visibility::from_hir(&self.tcx.map.expect_item(node_id).vis, node_id, self.tcx),
None => self.tcx.sess.cstore.visibility(did), None => self.tcx.sess.cstore.visibility(did),
}.is_accessible_from(self.curitem, &self.tcx.map) }.is_accessible_from(self.curitem, self.tcx)
} }
// Checks that a field is in scope. // Checks that a field is in scope.
fn check_field(&mut self, span: Span, def: &'tcx ty::AdtDef, field: &'tcx ty::FieldDef) { fn check_field(&mut self, span: Span, def: &'tcx ty::AdtDef, field: &'tcx ty::FieldDef) {
if !def.is_enum() && !field.vis.is_accessible_from(self.curitem, &self.tcx.map) { if !def.is_enum() && !field.vis.is_accessible_from(self.curitem, self.tcx) {
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private", struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
field.name, def.variant_descr(), self.tcx.item_path_str(def.did)) field.name, def.variant_descr(), self.tcx.item_path_str(def.did))
.span_label(span, &format!("field `{}` is private", field.name)) .span_label(span, &format!("field `{}` is private", field.name))
@ -437,7 +437,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
} }
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
let orig_curitem = replace(&mut self.curitem, item.id); let orig_curitem = replace(&mut self.curitem, self.tcx.map.local_def_id(item.id));
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
self.curitem = orig_curitem; self.curitem = orig_curitem;
} }
@ -474,7 +474,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
if let Def::StructCtor(_, CtorKind::Fn) = path.def { if let Def::StructCtor(_, CtorKind::Fn) = path.def {
let adt_def = self.tcx.expect_variant_def(path.def); let adt_def = self.tcx.expect_variant_def(path.def);
let private_indexes = adt_def.fields.iter().enumerate().filter(|&(_, field)| { let private_indexes = adt_def.fields.iter().enumerate().filter(|&(_, field)| {
!field.vis.is_accessible_from(self.curitem, &self.tcx.map) !field.vis.is_accessible_from(self.curitem, self.tcx)
}).map(|(i, _)| i).collect::<Vec<_>>(); }).map(|(i, _)| i).collect::<Vec<_>>();
if !private_indexes.is_empty() { if !private_indexes.is_empty() {
@ -940,7 +940,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
ty::TyAdt(adt, _) => Some(adt.did), ty::TyAdt(adt, _) => Some(adt.did),
ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), ty::TyDynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
ty::TyProjection(ref proj) => { ty::TyProjection(ref proj) => {
if self.required_visibility == ty::Visibility::PrivateExternal { if self.required_visibility == ty::Visibility::Invisible {
// Conservatively approximate the whole type alias as public without // Conservatively approximate the whole type alias as public without
// recursing into its components when determining impl publicity. // recursing into its components when determining impl publicity.
// For example, `impl <Type as Trait>::Alias {...}` may be a public impl // For example, `impl <Type as Trait>::Alias {...}` may be a public impl
@ -961,10 +961,10 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
let item = self.tcx.map.expect_item(node_id); let item = self.tcx.map.expect_item(node_id);
let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
if !vis.is_at_least(self.min_visibility, &self.tcx.map) { if !vis.is_at_least(self.min_visibility, self.tcx) {
self.min_visibility = vis; self.min_visibility = vis;
} }
if !vis.is_at_least(self.required_visibility, &self.tcx.map) { if !vis.is_at_least(self.required_visibility, self.tcx) {
if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors { if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors {
let mut err = struct_span_err!(self.tcx.sess, self.span, E0446, let mut err = struct_span_err!(self.tcx.sess, self.span, E0446,
"private type `{}` in public interface", ty); "private type `{}` in public interface", ty);
@ -996,10 +996,10 @@ fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
let item = self.tcx.map.expect_item(node_id); let item = self.tcx.map.expect_item(node_id);
let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
if !vis.is_at_least(self.min_visibility, &self.tcx.map) { if !vis.is_at_least(self.min_visibility, self.tcx) {
self.min_visibility = vis; self.min_visibility = vis;
} }
if !vis.is_at_least(self.required_visibility, &self.tcx.map) { if !vis.is_at_least(self.required_visibility, self.tcx) {
if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors { if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors {
struct_span_err!(self.tcx.sess, self.span, E0445, struct_span_err!(self.tcx.sess, self.span, E0445,
"private trait `{}` in public interface", trait_ref) "private trait `{}` in public interface", trait_ref)
@ -1071,7 +1071,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
let tcx = self.tcx; let tcx = self.tcx;
let min = |vis1: ty::Visibility, vis2| { let min = |vis1: ty::Visibility, vis2| {
if vis1.is_at_least(vis2, &tcx.map) { vis2 } else { vis1 } if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 }
}; };
let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, tcx); let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, tcx);
@ -1137,8 +1137,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
// An inherent impl is public when its type is public // An inherent impl is public when its type is public
// Subitems of inherent impls have their own publicity // Subitems of inherent impls have their own publicity
hir::ItemImpl(.., None, _, ref impl_item_refs) => { hir::ItemImpl(.., None, _, ref impl_item_refs) => {
let ty_vis = self.check(item.id, ty::Visibility::PrivateExternal) let ty_vis =
.item_type().min_visibility; self.check(item.id, ty::Visibility::Invisible).item_type().min_visibility;
self.check(item.id, ty_vis).generics().predicates(); self.check(item.id, ty_vis).generics().predicates();
for impl_item_ref in impl_item_refs { for impl_item_ref in impl_item_refs {
@ -1156,7 +1156,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
// A trait impl is public when both its type and its trait are public // A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity // Subitems of trait impls have inherited publicity
hir::ItemImpl(.., Some(_), _, ref impl_item_refs) => { hir::ItemImpl(.., Some(_), _, ref impl_item_refs) => {
let vis = self.check(item.id, ty::Visibility::PrivateExternal) let vis = self.check(item.id, ty::Visibility::Invisible)
.item_type().impl_trait_ref().min_visibility; .item_type().impl_trait_ref().min_visibility;
self.check(item.id, vis).generics().predicates(); self.check(item.id, vis).generics().predicates();
for impl_item_ref in impl_item_refs { for impl_item_ref in impl_item_refs {
@ -1203,7 +1203,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Use the parent map to check the privacy of everything // Use the parent map to check the privacy of everything
let mut visitor = PrivacyVisitor { let mut visitor = PrivacyVisitor {
curitem: ast::DUMMY_NODE_ID, curitem: DefId::local(CRATE_DEF_INDEX),
in_foreign: false, in_foreign: false,
tcx: tcx, tcx: tcx,
}; };

View File

@ -229,7 +229,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
ViewPathGlob(_) => { ViewPathGlob(_) => {
let subclass = GlobImport { let subclass = GlobImport {
is_prelude: is_prelude, is_prelude: is_prelude,
max_vis: Cell::new(ty::Visibility::PrivateExternal), max_vis: Cell::new(ty::Visibility::Invisible),
}; };
self.add_import_directive( self.add_import_directive(
module_path, subclass, view_path.span, item.id, vis, expansion, module_path, subclass, view_path.span, item.id, vis, expansion,
@ -265,16 +265,16 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root
ItemKind::Mod(..) => { ItemKind::Mod(..) => {
let def = Def::Mod(self.definitions.local_def_id(item.id)); let def_id = self.definitions.local_def_id(item.id);
let module_kind = ModuleKind::Def(Def::Mod(def_id), ident.name);
let module = self.arenas.alloc_module(ModuleData { let module = self.arenas.alloc_module(ModuleData {
no_implicit_prelude: parent.no_implicit_prelude || { no_implicit_prelude: parent.no_implicit_prelude || {
attr::contains_name(&item.attrs, "no_implicit_prelude") attr::contains_name(&item.attrs, "no_implicit_prelude")
}, },
normal_ancestor_id: Some(item.id), ..ModuleData::new(Some(parent), module_kind, def_id)
..ModuleData::new(Some(parent), ModuleKind::Def(def, ident.name))
}); });
self.define(parent, ident, TypeNS, (module, vis, sp, expansion)); self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
self.module_map.insert(item.id, module); self.module_map.insert(def_id, module);
// Descend into the module. // Descend into the module.
self.current_module = module; self.current_module = module;
@ -305,7 +305,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
ItemKind::Enum(ref enum_definition, _) => { ItemKind::Enum(ref enum_definition, _) => {
let def = Def::Enum(self.definitions.local_def_id(item.id)); let def = Def::Enum(self.definitions.local_def_id(item.id));
let module = self.new_module(parent, ModuleKind::Def(def, ident.name), true); let module_kind = ModuleKind::Def(def, ident.name);
let module = self.new_module(parent, module_kind, parent.normal_ancestor_id);
self.define(parent, ident, TypeNS, (module, vis, sp, expansion)); self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
for variant in &(*enum_definition).variants { for variant in &(*enum_definition).variants {
@ -355,8 +356,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
let def_id = self.definitions.local_def_id(item.id); let def_id = self.definitions.local_def_id(item.id);
// Add all the items within to a new module. // Add all the items within to a new module.
let module = let module_kind = ModuleKind::Def(Def::Trait(def_id), ident.name);
self.new_module(parent, ModuleKind::Def(Def::Trait(def_id), ident.name), true); let module = self.new_module(parent, module_kind, parent.normal_ancestor_id);
self.define(parent, ident, TypeNS, (module, vis, sp, expansion)); self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
self.current_module = module; self.current_module = module;
} }
@ -404,15 +405,10 @@ fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion
fn build_reduced_graph_for_block(&mut self, block: &Block) { fn build_reduced_graph_for_block(&mut self, block: &Block) {
let parent = self.current_module; let parent = self.current_module;
if self.block_needs_anonymous_module(block) { if self.block_needs_anonymous_module(block) {
let block_id = block.id; let module =
self.new_module(parent, ModuleKind::Block(block.id), parent.normal_ancestor_id);
debug!("(building reduced graph for block) creating a new anonymous module for block \ self.block_map.insert(block.id, module);
{}", self.current_module = module; // Descend into the block.
block_id);
let new_module = self.new_module(parent, ModuleKind::Block(block_id), true);
self.module_map.insert(block_id, new_module);
self.current_module = new_module; // Descend into the block.
} }
} }
@ -429,7 +425,7 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, chi
match def { match def {
Def::Mod(..) | Def::Enum(..) => { Def::Mod(..) | Def::Enum(..) => {
let module = self.new_module(parent, ModuleKind::Def(def, ident.name), false); let module = self.new_module(parent, ModuleKind::Def(def, ident.name), def_id);
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root())); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
} }
Def::Variant(..) => { Def::Variant(..) => {
@ -446,7 +442,8 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, chi
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root())); self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
} }
Def::Trait(..) => { Def::Trait(..) => {
let module = self.new_module(parent, ModuleKind::Def(def, ident.name), false); let module_kind = ModuleKind::Def(def, ident.name);
let module = self.new_module(parent, module_kind, parent.normal_ancestor_id);
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root())); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
// If this is a trait, add all the trait item names to the trait info. // If this is a trait, add all the trait item names to the trait info.
@ -497,12 +494,10 @@ fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'a> {
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
let name = self.session.cstore.crate_name(cnum); let name = self.session.cstore.crate_name(cnum);
let macros_only = self.session.cstore.dep_kind(cnum).macros_only(); let macros_only = self.session.cstore.dep_kind(cnum).macros_only();
let module_kind = ModuleKind::Def(Def::Mod(def_id), name);
let arenas = self.arenas; let arenas = self.arenas;
*self.extern_crate_roots.entry((cnum, macros_only)).or_insert_with(|| { *self.extern_crate_roots.entry((cnum, macros_only)).or_insert_with(|| {
arenas.alloc_module(ModuleData { arenas.alloc_module(ModuleData::new(None, module_kind, def_id))
populated: Cell::new(false),
..ModuleData::new(None, ModuleKind::Def(Def::Mod(def_id), name))
})
}) })
} }

View File

@ -43,14 +43,13 @@
use rustc::session::Session; use rustc::session::Session;
use rustc::lint; use rustc::lint;
use rustc::hir::def::*; use rustc::hir::def::*;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
use rustc::ty; use rustc::ty;
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet};
use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::ast::{self, FloatTy}; use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, Ident, SpannedIdent, IntTy, UintTy};
use syntax::ext::base::SyntaxExtension; use syntax::ext::base::SyntaxExtension;
use syntax::ext::base::Determinacy::{Determined, Undetermined}; use syntax::ext::base::Determinacy::{Determined, Undetermined};
use syntax::symbol::{Symbol, keywords}; use syntax::symbol::{Symbol, keywords};
@ -771,8 +770,8 @@ pub struct ModuleData<'a> {
parent: Option<Module<'a>>, parent: Option<Module<'a>>,
kind: ModuleKind, kind: ModuleKind,
// The node id of the closest normal module (`mod`) ancestor (including this module). // The def id of the closest normal module (`mod`) ancestor (including this module).
normal_ancestor_id: Option<NodeId>, normal_ancestor_id: DefId,
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>, resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span)>>, legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span)>>,
@ -798,11 +797,11 @@ pub struct ModuleData<'a> {
pub type Module<'a> = &'a ModuleData<'a>; pub type Module<'a> = &'a ModuleData<'a>;
impl<'a> ModuleData<'a> { impl<'a> ModuleData<'a> {
fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self { fn new(parent: Option<Module<'a>>, kind: ModuleKind, normal_ancestor_id: DefId) -> Self {
ModuleData { ModuleData {
parent: parent, parent: parent,
kind: kind, kind: kind,
normal_ancestor_id: None, normal_ancestor_id: normal_ancestor_id,
resolutions: RefCell::new(FxHashMap()), resolutions: RefCell::new(FxHashMap()),
legacy_macro_resolutions: RefCell::new(Vec::new()), legacy_macro_resolutions: RefCell::new(Vec::new()),
macro_resolutions: RefCell::new(Vec::new()), macro_resolutions: RefCell::new(Vec::new()),
@ -811,7 +810,7 @@ fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self {
glob_importers: RefCell::new(Vec::new()), glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new((Vec::new())), globs: RefCell::new((Vec::new())),
traits: RefCell::new(None), traits: RefCell::new(None),
populated: Cell::new(true), populated: Cell::new(normal_ancestor_id.is_local()),
} }
} }
@ -848,7 +847,7 @@ fn is_trait(&self) -> bool {
} }
fn is_local(&self) -> bool { fn is_local(&self) -> bool {
self.normal_ancestor_id.is_some() self.normal_ancestor_id.is_local()
} }
} }
@ -1063,7 +1062,7 @@ pub struct Resolver<'a> {
pub export_map: ExportMap, pub export_map: ExportMap,
pub trait_map: TraitMap, pub trait_map: TraitMap,
// A map from nodes to modules, both normal (`mod`) modules and anonymous modules. // A map from nodes to anonymous modules.
// Anonymous modules are pseudo-modules that are implicitly created around items // Anonymous modules are pseudo-modules that are implicitly created around items
// contained within blocks. // contained within blocks.
// //
@ -1077,7 +1076,8 @@ pub struct Resolver<'a> {
// //
// There will be an anonymous module created around `g` with the ID of the // There will be an anonymous module created around `g` with the ID of the
// entry block for `f`. // entry block for `f`.
module_map: NodeMap<Module<'a>>, block_map: NodeMap<Module<'a>>,
module_map: FxHashMap<DefId, Module<'a>>,
extern_crate_roots: FxHashMap<(CrateNum, bool /* MacrosOnly? */), Module<'a>>, extern_crate_roots: FxHashMap<(CrateNum, bool /* MacrosOnly? */), Module<'a>>,
pub make_glob_map: bool, pub make_glob_map: bool,
@ -1153,15 +1153,12 @@ fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBindi
} }
} }
impl<'a> ty::NodeIdTree for Resolver<'a> { impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> {
fn is_descendant_of(&self, mut node: NodeId, ancestor: NodeId) -> bool { fn parent(self, id: DefId) -> Option<DefId> {
while node != ancestor { match id.krate {
node = match self.module_map[&node].parent { LOCAL_CRATE => self.definitions.def_key(id.index).parent,
Some(parent) => parent.normal_ancestor_id.unwrap(), _ => self.session.cstore.def_key(id).parent,
None => return false, }.map(|index| DefId { index: index, ..id })
}
}
true
} }
} }
@ -1202,14 +1199,14 @@ pub fn new(session: &'a Session,
crate_loader: &'a mut CrateLoader, crate_loader: &'a mut CrateLoader,
arenas: &'a ResolverArenas<'a>) arenas: &'a ResolverArenas<'a>)
-> Resolver<'a> { -> Resolver<'a> {
let root_def = Def::Mod(DefId::local(CRATE_DEF_INDEX)); let root_def_id = DefId::local(CRATE_DEF_INDEX);
let root_module_kind = ModuleKind::Def(Def::Mod(root_def_id), keywords::Invalid.name());
let graph_root = arenas.alloc_module(ModuleData { let graph_root = arenas.alloc_module(ModuleData {
normal_ancestor_id: Some(CRATE_NODE_ID),
no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"), no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
..ModuleData::new(None, ModuleKind::Def(root_def, keywords::Invalid.name())) ..ModuleData::new(None, root_module_kind, root_def_id)
}); });
let mut module_map = NodeMap(); let mut module_map = FxHashMap();
module_map.insert(CRATE_NODE_ID, graph_root); module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
let mut definitions = Definitions::new(); let mut definitions = Definitions::new();
DefCollector::new(&mut definitions).collect_root(); DefCollector::new(&mut definitions).collect_root();
@ -1254,6 +1251,7 @@ pub fn new(session: &'a Session,
export_map: NodeMap(), export_map: NodeMap(),
trait_map: NodeMap(), trait_map: NodeMap(),
module_map: module_map, module_map: module_map,
block_map: NodeMap(),
extern_crate_roots: FxHashMap(), extern_crate_roots: FxHashMap(),
make_glob_map: make_glob_map == MakeGlobMap::Yes, make_glob_map: make_glob_map == MakeGlobMap::Yes,
@ -1324,12 +1322,9 @@ pub fn resolve_crate(&mut self, krate: &Crate) {
self.crate_loader.postprocess(krate); self.crate_loader.postprocess(krate);
} }
fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Module<'a> { fn new_module(&self, parent: Module<'a>, kind: ModuleKind, normal_ancestor_id: DefId)
self.arenas.alloc_module(ModuleData { -> Module<'a> {
normal_ancestor_id: if local { self.current_module.normal_ancestor_id } else { None }, self.arenas.alloc_module(ModuleData::new(Some(parent), kind, normal_ancestor_id))
populated: Cell::new(local),
..ModuleData::new(Some(parent), kind)
})
} }
fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span) fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
@ -1462,6 +1457,7 @@ fn resolve_crate_var(&mut self, mut crate_var_ctxt: SyntaxContext) -> Module<'a>
fn with_scope<F>(&mut self, id: NodeId, f: F) fn with_scope<F>(&mut self, id: NodeId, f: F)
where F: FnOnce(&mut Resolver) where F: FnOnce(&mut Resolver)
{ {
let id = self.definitions.local_def_id(id);
let module = self.module_map.get(&id).cloned(); // clones a reference let module = self.module_map.get(&id).cloned(); // clones a reference
if let Some(module) = module { if let Some(module) = module {
// Move down in the graph. // Move down in the graph.
@ -1958,7 +1954,7 @@ fn resolve_block(&mut self, block: &Block) {
debug!("(resolving block) entering block"); debug!("(resolving block) entering block");
// Move down in the graph, if there's an anonymous module rooted here. // Move down in the graph, if there's an anonymous module rooted here.
let orig_module = self.current_module; let orig_module = self.current_module;
let anonymous_module = self.module_map.get(&block.id).cloned(); // clones a reference let anonymous_module = self.block_map.get(&block.id).cloned(); // clones a reference
let mut num_macro_definition_ribs = 0; let mut num_macro_definition_ribs = 0;
if let Some(anonymous_module) = anonymous_module { if let Some(anonymous_module) = anonymous_module {
@ -2334,13 +2330,13 @@ fn resolve_path(&mut self,
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
if i == 0 && ns == TypeNS && ident.name == keywords::SelfValue.name() { if i == 0 && ns == TypeNS && ident.name == keywords::SelfValue.name() {
module = Some(self.module_map[&self.current_module.normal_ancestor_id.unwrap()]); module = Some(self.module_map[&self.current_module.normal_ancestor_id]);
continue continue
} else if allow_super && ns == TypeNS && ident.name == keywords::Super.name() { } else if allow_super && ns == TypeNS && ident.name == keywords::Super.name() {
let current_module = if i == 0 { self.current_module } else { module.unwrap() }; let current_module = if i == 0 { self.current_module } else { module.unwrap() };
let self_module = self.module_map[&current_module.normal_ancestor_id.unwrap()]; let self_module = self.module_map[&current_module.normal_ancestor_id];
if let Some(parent) = self_module.parent { if let Some(parent) = self_module.parent {
module = Some(self.module_map[&parent.normal_ancestor_id.unwrap()]); module = Some(self.module_map[&parent.normal_ancestor_id]);
continue continue
} else { } else {
let msg = "There are too many initial `super`s.".to_string(); let msg = "There are too many initial `super`s.".to_string();
@ -3001,10 +2997,12 @@ fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
let (segments, span, id) = match *vis { let (segments, span, id) = match *vis {
ast::Visibility::Public => return ty::Visibility::Public, ast::Visibility::Public => return ty::Visibility::Public,
ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID), ast::Visibility::Crate(_) => {
return ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
}
ast::Visibility::Restricted { ref path, id } => (&path.segments, path.span, id), ast::Visibility::Restricted { ref path, id } => (&path.segments, path.span, id),
ast::Visibility::Inherited => { ast::Visibility::Inherited => {
return ty::Visibility::Restricted(self.current_module.normal_ancestor_id.unwrap()); return ty::Visibility::Restricted(self.current_module.normal_ancestor_id);
} }
}; };
@ -3013,7 +3011,7 @@ fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
let vis = match self.resolve_path(&path, None, Some(span)) { let vis = match self.resolve_path(&path, None, Some(span)) {
PathResult::Module(module) => { PathResult::Module(module) => {
path_resolution = PathResolution::new(module.def().unwrap()); path_resolution = PathResolution::new(module.def().unwrap());
ty::Visibility::Restricted(module.normal_ancestor_id.unwrap()) ty::Visibility::Restricted(module.normal_ancestor_id)
} }
PathResult::Failed(msg, _) => { PathResult::Failed(msg, _) => {
self.session.span_err(span, &format!("failed to resolve module path. {}", msg)); self.session.span_err(span, &format!("failed to resolve module path. {}", msg));
@ -3030,11 +3028,11 @@ fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
} }
fn is_accessible(&self, vis: ty::Visibility) -> bool { fn is_accessible(&self, vis: ty::Visibility) -> bool {
vis.is_accessible_from(self.current_module.normal_ancestor_id.unwrap(), self) vis.is_accessible_from(self.current_module.normal_ancestor_id, self)
} }
fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool { fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
vis.is_accessible_from(module.normal_ancestor_id.unwrap(), self) vis.is_accessible_from(module.normal_ancestor_id, self)
} }
fn report_errors(&mut self) { fn report_errors(&mut self) {

View File

@ -88,7 +88,7 @@ fn next_node_id(&mut self) -> ast::NodeId {
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark { fn get_module_scope(&mut self, id: ast::NodeId) -> Mark {
let mark = Mark::fresh(); let mark = Mark::fresh();
let module = self.module_map[&id]; let module = self.module_map[&self.definitions.local_def_id(id)];
self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData { self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData {
module: Cell::new(module), module: Cell::new(module),
def_index: module.def_id().unwrap().index, def_index: module.def_id().unwrap().index,
@ -154,7 +154,7 @@ fn add_ext(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
let binding = self.arenas.alloc_name_binding(NameBinding { let binding = self.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Def(Def::Macro(def_id)), kind: NameBindingKind::Def(Def::Macro(def_id)),
span: DUMMY_SP, span: DUMMY_SP,
vis: ty::Visibility::PrivateExternal, vis: ty::Visibility::Invisible,
expansion: Mark::root(), expansion: Mark::root(),
}); });
self.builtin_macros.insert(ident.name, binding); self.builtin_macros.insert(ident.name, binding);

View File

@ -19,6 +19,7 @@
use rustc::ty; use rustc::ty;
use rustc::lint::builtin::PRIVATE_IN_PUBLIC; use rustc::lint::builtin::PRIVATE_IN_PUBLIC;
use rustc::hir::def_id::DefId;
use rustc::hir::def::*; use rustc::hir::def::*;
use syntax::ast::{Ident, NodeId}; use syntax::ast::{Ident, NodeId};
@ -274,7 +275,7 @@ pub fn add_import_directive(&mut self,
// Given a binding and an import directive that resolves to it, // Given a binding and an import directive that resolves to it,
// return the corresponding binding defined by the import directive. // return the corresponding binding defined by the import directive.
pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>) pub fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
-> &'a NameBinding<'a> { -> &'a NameBinding<'a> {
let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
!directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC` !directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC`
@ -316,7 +317,7 @@ pub fn try_define(&mut self,
resolution.shadows_glob = Some(binding); resolution.shadows_glob = Some(binding);
} else if binding.def() != old_binding.def() { } else if binding.def() != old_binding.def() {
resolution.binding = Some(this.ambiguity(old_binding, binding)); resolution.binding = Some(this.ambiguity(old_binding, binding));
} else if !old_binding.vis.is_at_least(binding.vis, this) { } else if !old_binding.vis.is_at_least(binding.vis, &*this) {
// We are glob-importing the same item but with greater visibility. // We are glob-importing the same item but with greater visibility.
resolution.binding = Some(binding); resolution.binding = Some(binding);
} }
@ -339,7 +340,7 @@ pub fn try_define(&mut self,
}) })
} }
pub fn ambiguity(&mut self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>) pub fn ambiguity(&self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
-> &'a NameBinding<'a> { -> &'a NameBinding<'a> {
self.arenas.alloc_name_binding(NameBinding { self.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Ambiguity { b1: b1, b2: b2, legacy: false }, kind: NameBindingKind::Ambiguity { b1: b1, b2: b2, legacy: false },
@ -414,9 +415,9 @@ fn deref_mut(&mut self) -> &mut Resolver<'b> {
} }
} }
impl<'a, 'b: 'a> ty::NodeIdTree for ImportResolver<'a, 'b> { impl<'a, 'b: 'a> ty::DefIdTree for &'a ImportResolver<'a, 'b> {
fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool { fn parent(self, id: DefId) -> Option<DefId> {
self.resolver.is_descendant_of(node, ancestor) self.resolver.parent(id)
} }
} }
@ -489,7 +490,7 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
let vis = directive.vis.get(); let vis = directive.vis.get();
// For better failure detection, pretend that the import will not define any names // For better failure detection, pretend that the import will not define any names
// while resolving its module path. // while resolving its module path.
directive.vis.set(ty::Visibility::PrivateExternal); directive.vis.set(ty::Visibility::Invisible);
let result = self.resolve_path(&directive.module_path, None, None); let result = self.resolve_path(&directive.module_path, None, None);
directive.vis.set(vis); directive.vis.set(vis);
@ -579,8 +580,8 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
} }
GlobImport { is_prelude, ref max_vis } => { GlobImport { is_prelude, ref max_vis } => {
if !is_prelude && if !is_prelude &&
max_vis.get() != ty::Visibility::PrivateExternal && // Allow empty globs. max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
!max_vis.get().is_at_least(directive.vis.get(), self) { !max_vis.get().is_at_least(directive.vis.get(), &*self) {
let msg = "A non-empty glob must import something with the glob's visibility"; let msg = "A non-empty glob must import something with the glob's visibility";
self.session.span_err(directive.span, msg); self.session.span_err(directive.span, msg);
} }
@ -643,7 +644,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
self.per_ns(|this, ns| { self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() { if let Ok(binding) = result[ns].get() {
let vis = directive.vis.get(); let vis = directive.vis.get();
if !binding.pseudo_vis().is_at_least(vis, this) { if !binding.pseudo_vis().is_at_least(vis, &*this) {
reexport_error = Some((ns, binding)); reexport_error = Some((ns, binding));
} else { } else {
any_successful_reexport = true; any_successful_reexport = true;
@ -751,7 +752,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
match binding.kind { match binding.kind {
NameBindingKind::Import { binding: orig_binding, directive, .. } => { NameBindingKind::Import { binding: orig_binding, directive, .. } => {
if ns == TypeNS && orig_binding.is_variant() && if ns == TypeNS && orig_binding.is_variant() &&
!orig_binding.vis.is_at_least(binding.vis, self) { !orig_binding.vis.is_at_least(binding.vis, &*self) {
let msg = format!("variant `{}` is private, and cannot be reexported \ let msg = format!("variant `{}` is private, and cannot be reexported \
(error E0364), consider declaring its enum as `pub`", (error E0364), consider declaring its enum as `pub`",
ident); ident);

View File

@ -344,7 +344,7 @@ pub fn resolve_ufcs(&self,
self.tcx.check_stability(def.def_id(), expr_id, span); self.tcx.check_stability(def.def_id(), expr_id, span);
if let probe::InherentImplPick = pick.kind { if let probe::InherentImplPick = pick.kind {
if !pick.item.vis.is_accessible_from(self.body_id, &self.tcx.map) { if !self.tcx.vis_is_accessible_from(pick.item.vis, self.body_id) {
let msg = format!("{} `{}` is private", def.kind_name(), method_name); let msg = format!("{} `{}` is private", def.kind_name(), method_name);
self.tcx.sess.span_err(span, &msg); self.tcx.sess.span_err(span, &msg);
} }

View File

@ -503,7 +503,7 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
continue continue
} }
if !item.vis.is_accessible_from(self.body_id, &self.tcx.map) { if !self.tcx.vis_is_accessible_from(item.vis, self.body_id) {
self.private_candidate = Some(item.def()); self.private_candidate = Some(item.def());
continue continue
} }

View File

@ -3009,7 +3009,7 @@ fn check_field(&self,
debug!("struct named {:?}", base_t); debug!("struct named {:?}", base_t);
if let Some(field) = base_def.struct_variant().find_field_named(field.node) { if let Some(field) = base_def.struct_variant().find_field_named(field.node) {
let field_ty = self.field_ty(expr.span, field, substs); let field_ty = self.field_ty(expr.span, field, substs);
if field.vis.is_accessible_from(self.body_id, &self.tcx().map) { if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
autoderef.finalize(lvalue_pref, Some(base)); autoderef.finalize(lvalue_pref, Some(base));
self.write_autoderef_adjustment(base.id, autoderefs, base_t); self.write_autoderef_adjustment(base.id, autoderefs, base_t);
@ -3116,7 +3116,7 @@ fn check_tup_field(&self,
base_def.struct_variant().fields.get(idx.node).and_then(|field| { base_def.struct_variant().fields.get(idx.node).and_then(|field| {
let field_ty = self.field_ty(expr.span, field, substs); let field_ty = self.field_ty(expr.span, field, substs);
private_candidate = Some((base_def.did, field_ty)); private_candidate = Some((base_def.did, field_ty));
if field.vis.is_accessible_from(self.body_id, &self.tcx().map) { if self.tcx.vis_is_accessible_from(field.vis, self.body_id) {
self.tcx.check_stability(field.did, expr.id, expr.span); self.tcx.check_stability(field.did, expr.id, expr.span);
Some(field_ty) Some(field_ty)
} else { } else {