Skip to content

resolve: cleanup and groundwork for resolving the AST #33232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 29, 2016
32 changes: 22 additions & 10 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,24 @@ pub enum Visibility {
PrivateExternal,
}

pub trait NodeIdTree {
fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool;
}

impl<'a> NodeIdTree for ast_map::Map<'a> {
fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
let mut node_ancestor = node;
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
}
}

impl Visibility {
pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: &TyCtxt) -> Self {
match *visibility {
Expand All @@ -301,7 +319,7 @@ impl Visibility {
}

/// Returns true if an item with this visibility is accessible from the given block.
pub fn is_accessible_from(self, block: NodeId, map: &ast_map::Map) -> bool {
pub fn is_accessible_from<T: NodeIdTree>(self, block: NodeId, tree: &T) -> bool {
let restriction = match self {
// Public items are visible everywhere.
Visibility::Public => return true,
Expand All @@ -311,24 +329,18 @@ impl Visibility {
Visibility::Restricted(module) => module,
};

let mut block_ancestor = block;
loop {
if block_ancestor == restriction { return true }
let block_ancestor_parent = map.get_module_parent(block_ancestor);
if block_ancestor_parent == block_ancestor { return false }
block_ancestor = block_ancestor_parent;
}
tree.is_descendant_of(block, restriction)
}

/// Returns true if this visibility is at least as accessible as the given visibility
pub fn is_at_least(self, vis: Visibility, map: &ast_map::Map) -> bool {
pub fn is_at_least<T: NodeIdTree>(self, vis: Visibility, tree: &T) -> bool {
let vis_restriction = match vis {
Visibility::Public => return self == Visibility::Public,
Visibility::PrivateExternal => return true,
Visibility::Restricted(module) => module,
};

self.is_accessible_from(vis_restriction, map)
self.is_accessible_from(vis_restriction, tree)
}
}

Expand Down
51 changes: 28 additions & 23 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ trait ToNameBinding<'a> {
fn to_name_binding(self) -> NameBinding<'a>;
}

impl<'a> ToNameBinding<'a> for (Module<'a>, Span) {
impl<'a> ToNameBinding<'a> for (Module<'a>, Span, ty::Visibility) {
fn to_name_binding(self) -> NameBinding<'a> {
NameBinding::create_from_module(self.0, Some(self.1))
NameBinding { kind: NameBindingKind::Module(self.0), span: self.1, vis: self.2 }
}
}

impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) {
fn to_name_binding(self) -> NameBinding<'a> {
NameBinding { kind: NameBindingKind::Def(self.0), span: Some(self.1), vis: self.2 }
NameBinding { kind: NameBindingKind::Def(self.0), span: self.1, vis: self.2 }
}
}

Expand Down Expand Up @@ -247,8 +247,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
};
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(def_id);
let module = self.new_extern_crate_module(parent_link, def, vis, item.id);
self.define(parent, name, TypeNS, (module, sp));
let module = self.new_extern_crate_module(parent_link, def, item.id);
self.define(parent, name, TypeNS, (module, sp, vis));

self.build_reduced_graph_for_external_crate(module);
}
Expand All @@ -257,8 +257,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
ItemMod(..) => {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(self.ast_map.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), false, vis);
self.define(parent, name, TypeNS, (module, sp));
let module = self.new_module(parent_link, Some(def), false);
self.define(parent, name, TypeNS, (module, sp, vis));
self.module_map.insert(item.id, module);
*parent_ref = module;
}
Expand Down Expand Up @@ -289,12 +289,12 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
ItemEnum(ref enum_definition, _) => {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Enum(self.ast_map.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), false, vis);
self.define(parent, name, TypeNS, (module, sp));
let module = self.new_module(parent_link, Some(def), false);
self.define(parent, name, TypeNS, (module, sp, vis));

for variant in &(*enum_definition).variants {
let item_def_id = self.ast_map.local_def_id(item.id);
self.build_reduced_graph_for_variant(variant, item_def_id, module);
self.build_reduced_graph_for_variant(variant, item_def_id, module, vis);
}
}

Expand Down Expand Up @@ -328,21 +328,25 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
// Add all the items within to a new module.
let parent_link = ModuleParentLink(parent, name);
let def = Def::Trait(def_id);
let module_parent = self.new_module(parent_link, Some(def), false, vis);
self.define(parent, name, TypeNS, (module_parent, sp));
let module_parent = self.new_module(parent_link, Some(def), false);
self.define(parent, name, TypeNS, (module_parent, sp, vis));

// Add the names of all the items to the trait info.
for item in items {
let item_def_id = self.ast_map.local_def_id(item.id);
let mut is_static_method = false;
let (def, ns) = match item.node {
hir::ConstTraitItem(..) => (Def::AssociatedConst(item_def_id), ValueNS),
hir::MethodTraitItem(..) => (Def::Method(item_def_id), ValueNS),
hir::MethodTraitItem(ref sig, _) => {
is_static_method = sig.explicit_self.node == hir::SelfStatic;
(Def::Method(item_def_id), ValueNS)
}
hir::TypeTraitItem(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
};

self.define(module_parent, item.name, ns, (def, item.span, vis));

self.trait_item_map.insert((item.name, def_id), item_def_id);
self.trait_item_map.insert((item.name, def_id), is_static_method);
}
}
}
Expand All @@ -353,7 +357,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
fn build_reduced_graph_for_variant(&mut self,
variant: &Variant,
item_id: DefId,
parent: Module<'b>) {
parent: Module<'b>,
vis: ty::Visibility) {
let name = variant.node.name;
if variant.node.data.is_struct() {
// Not adding fields for variants as they are not accessed with a self receiver
Expand All @@ -364,8 +369,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
// Variants are always treated as importable to allow them to be glob used.
// All variants are defined in both type and value namespaces as future-proofing.
let def = Def::Variant(item_id, self.ast_map.local_def_id(variant.node.data.id()));
self.define(parent, name, ValueNS, (def, variant.span, parent.vis));
self.define(parent, name, TypeNS, (def, variant.span, parent.vis));
self.define(parent, name, ValueNS, (def, variant.span, vis));
self.define(parent, name, TypeNS, (def, variant.span, vis));
}

/// Constructs the reduced graph for one foreign item.
Expand Down Expand Up @@ -396,7 +401,7 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
block_id);

let parent_link = BlockParentLink(parent, block_id);
let new_module = self.new_module(parent_link, None, false, parent.vis);
let new_module = self.new_module(parent_link, None, false);
self.module_map.insert(block_id, new_module);
*parent = new_module;
}
Expand Down Expand Up @@ -425,8 +430,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
debug!("(building reduced graph for external crate) building module {} {:?}",
name, vis);
let parent_link = ModuleParentLink(parent, name);
let module = self.new_module(parent_link, Some(def), true, vis);
self.try_define(parent, name, TypeNS, (module, DUMMY_SP));
let module = self.new_module(parent_link, Some(def), true);
self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::Variant(_, variant_id) => {
debug!("(building reduced graph for external crate) building variant {}", name);
Expand Down Expand Up @@ -463,12 +468,12 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
'{}'",
trait_item_name);

self.trait_item_map.insert((trait_item_name, def_id), trait_item_def.def_id());
self.trait_item_map.insert((trait_item_name, def_id), false);
}

let parent_link = ModuleParentLink(parent, name);
let module = self.new_module(parent_link, Some(def), true, vis);
self.try_define(parent, name, TypeNS, (module, DUMMY_SP));
let module = self.new_module(parent_link, Some(def), true);
self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::TyAlias(..) | Def::AssociatedTy(..) => {
debug!("(building reduced graph for external crate) building type {}", name);
Expand Down
Loading