/// Constructs the reduced graph for one item.
fn build_reduced_graph_for_item(&mut self, item: &Item) {
let parent = self.current_module;
+ let parent_vis = self.current_vis;
let name = item.ident.name;
let sp = item.span;
let vis = self.resolve_visibility(&item.vis);
});
self.define(parent, name, TypeNS, (module, sp, vis));
self.module_map.insert(item.id, module);
- self.current_module = module; // Descend into the module.
+
+ // Descend into the module.
+ self.current_module = module;
+ self.current_vis = ty::Visibility::Restricted(item.id);
}
ItemKind::ForeignMod(..) => {}
visit::walk_item(&mut BuildReducedGraphVisitor { resolver: self }, item);
self.current_module = parent;
+ self.current_vis = parent_vis;
}
// Constructs the reduced graph for one variant. Variants exist in the
// The module that represents the current item scope.
current_module: Module<'a>,
+ // The visibility of `pub(self)` items in the current scope.
+ // Equivalently, the visibility required for an item to be accessible from the current scope.
+ current_vis: ty::Visibility,
+
// The current set of local scopes, for values.
// FIXME #4948: Reuse ribs to avoid allocation.
value_ribs: Vec<Rib<'a>>,
indeterminate_imports: Vec::new(),
current_module: graph_root,
+ current_vis: ty::Visibility::Restricted(ast::CRATE_NODE_ID),
value_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
type_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
label_ribs: Vec::new(),
/// Entry point to crate resolution.
pub fn resolve_crate(&mut self, krate: &Crate) {
self.current_module = self.graph_root;
+ self.current_vis = ty::Visibility::Restricted(ast::CRATE_NODE_ID);
visit::walk_crate(self, krate);
check_unused::check_crate(self, krate);
let module = self.module_map.get(&id).cloned(); // clones a reference
if let Some(module) = module {
// Move down in the graph.
- let orig_module = ::std::mem::replace(&mut self.current_module, module);
+ let orig_module = replace(&mut self.current_module, module);
+ let orig_vis = replace(&mut self.current_vis, ty::Visibility::Restricted(id));
self.value_ribs.push(Rib::new(ModuleRibKind(module)));
self.type_ribs.push(Rib::new(ModuleRibKind(module)));
f(self);
self.current_module = orig_module;
+ self.current_vis = orig_vis;
self.value_ribs.pop();
self.type_ribs.pop();
} else {
fn with_empty_ribs<T, F>(&mut self, f: F) -> T
where F: FnOnce(&mut Resolver<'a>) -> T,
{
- use ::std::mem::replace;
let value_ribs = replace(&mut self.value_ribs, Vec::new());
let type_ribs = replace(&mut self.type_ribs, Vec::new());
let label_ribs = replace(&mut self.label_ribs, Vec::new());
ast::Visibility::Public => return ty::Visibility::Public,
ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID),
ast::Visibility::Restricted { ref path, id } => (path, id),
- ast::Visibility::Inherited => {
- let current_module =
- self.get_nearest_normal_module_parent_or_self(self.current_module);
- let id =
- self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap();
- return ty::Visibility::Restricted(id);
- }
+ ast::Visibility::Inherited => return self.current_vis,
};
let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier.name).collect();
}
fn is_accessible(&self, vis: ty::Visibility) -> bool {
- let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module);
- let node_id = self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap();
- vis.is_accessible_from(node_id, self)
+ vis.is_at_least(self.current_vis, self)
}
fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) {
// remain or unsuccessfully when no forward progress in resolving imports
// is made.
+ fn set_current_module(&mut self, module: Module<'b>) {
+ self.current_module = module;
+ self.current_vis = ty::Visibility::Restricted({
+ let normal_module = self.get_nearest_normal_module_parent_or_self(module);
+ self.definitions.as_local_node_id(normal_module.def_id().unwrap()).unwrap()
+ });
+ }
+
/// Resolves all imports for the crate. This method performs the fixed-
/// point iteration.
fn resolve_imports(&mut self) {
module_to_string(self.current_module));
let module = directive.parent;
- self.current_module = module;
+ self.set_current_module(module);
let target_module = match directive.target_module.get() {
Some(module) => module,