Refactor away ParentLink.

This commit is contained in:
Jeffrey Seyfried 2016-09-18 09:45:06 +00:00
parent 1cf592fa40
commit 9a0e88a339
3 changed files with 78 additions and 101 deletions

View File

@ -14,10 +14,9 @@
//! any imports resolved.
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
use Module;
use {Module, ModuleKind};
use Namespace::{self, TypeNS, ValueNS};
use {NameBinding, NameBindingKind, ToNameBinding};
use ParentLink::{ModuleParentLink, BlockParentLink};
use Resolver;
use {resolve_error, resolve_struct_error, ResolutionError};
@ -196,9 +195,8 @@ impl<'b> Resolver<'b> {
krate: crate_id,
index: CRATE_DEF_INDEX,
};
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(def_id);
let module = self.new_extern_crate_module(parent_link, def, item.id);
let module = self.new_extern_crate_module(parent, name, def, item.id);
self.define(parent, name, TypeNS, (module, sp, vis));
self.populate_module_if_necessary(module);
@ -206,9 +204,8 @@ impl<'b> Resolver<'b> {
}
ItemKind::Mod(..) => {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(self.definitions.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), Some(item.id));
let module = self.new_module(parent, ModuleKind::Def(def, name), Some(item.id));
module.no_implicit_prelude.set({
parent.no_implicit_prelude.get() ||
attr::contains_name(&item.attrs, "no_implicit_prelude")
@ -244,9 +241,8 @@ impl<'b> Resolver<'b> {
}
ItemKind::Enum(ref enum_definition, _) => {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Enum(self.definitions.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), parent.normal_ancestor_id);
let kind = ModuleKind::Def(Def::Enum(self.definitions.local_def_id(item.id)), name);
let module = self.new_module(parent, kind, parent.normal_ancestor_id);
self.define(parent, name, TypeNS, (module, sp, vis));
for variant in &(*enum_definition).variants {
@ -297,10 +293,8 @@ impl<'b> Resolver<'b> {
let def_id = self.definitions.local_def_id(item.id);
// 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), parent.normal_ancestor_id);
let kind = ModuleKind::Def(Def::Trait(def_id), name);
let module_parent = self.new_module(parent, kind, parent.normal_ancestor_id);
self.define(parent, name, TypeNS, (module_parent, sp, vis));
// Add the names of all the items to the trait info.
@ -375,8 +369,8 @@ impl<'b> Resolver<'b> {
{}",
block_id);
let parent_link = BlockParentLink(parent, block_id);
let new_module = self.new_module(parent_link, None, parent.normal_ancestor_id);
let new_module =
self.new_module(parent, ModuleKind::Block(block_id), parent.normal_ancestor_id);
self.module_map.insert(block_id, new_module);
self.current_module = new_module; // Descend into the block.
}
@ -407,8 +401,7 @@ impl<'b> Resolver<'b> {
Def::Mod(_) | Def::Enum(..) => {
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), None);
let module = self.new_module(parent, ModuleKind::Def(def, name), None);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::Variant(variant_id) => {
@ -451,8 +444,7 @@ impl<'b> Resolver<'b> {
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), None);
let module = self.new_module(parent, ModuleKind::Def(def, name), None);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::TyAlias(..) | Def::AssociatedTy(..) => {

View File

@ -41,7 +41,6 @@ use self::TypeParameters::*;
use self::RibKind::*;
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
use self::ParentLink::*;
use rustc::hir::map::Definitions;
use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
@ -753,18 +752,15 @@ impl<'a> LexicalScopeBinding<'a> {
}
}
/// The link from a module up to its nearest parent node.
#[derive(Clone,Debug)]
enum ParentLink<'a> {
NoParentLink,
ModuleParentLink(Module<'a>, Name),
BlockParentLink(Module<'a>, NodeId),
enum ModuleKind {
Block(NodeId),
Def(Def, Name),
}
/// One node in the tree of modules.
pub struct ModuleS<'a> {
parent_link: ParentLink<'a>,
def: Option<Def>,
parent: Option<Module<'a>>,
kind: ModuleKind,
// The node id of the closest normal module (`mod`) ancestor (including this module).
normal_ancestor_id: Option<NodeId>,
@ -792,11 +788,11 @@ pub struct ModuleS<'a> {
pub type Module<'a> = &'a ModuleS<'a>;
impl<'a> ModuleS<'a> {
fn new(parent_link: ParentLink<'a>, def: Option<Def>, normal_ancestor_id: Option<NodeId>)
fn new(parent: Option<Module<'a>>, kind: ModuleKind, normal_ancestor_id: Option<NodeId>)
-> Self {
ModuleS {
parent_link: parent_link,
def: def,
parent: parent,
kind: kind,
normal_ancestor_id: normal_ancestor_id,
extern_crate_id: None,
resolutions: RefCell::new(FnvHashMap()),
@ -814,36 +810,36 @@ impl<'a> ModuleS<'a> {
}
}
fn def(&self) -> Option<Def> {
match self.kind {
ModuleKind::Def(def, _) => Some(def),
_ => None,
}
}
fn def_id(&self) -> Option<DefId> {
self.def.as_ref().map(Def::def_id)
self.def().as_ref().map(Def::def_id)
}
// `self` resolves to the first module ancestor that `is_normal`.
fn is_normal(&self) -> bool {
match self.def {
Some(Def::Mod(_)) => true,
match self.kind {
ModuleKind::Def(Def::Mod(_), _) => true,
_ => false,
}
}
fn is_trait(&self) -> bool {
match self.def {
Some(Def::Trait(_)) => true,
match self.kind {
ModuleKind::Def(Def::Trait(_), _) => true,
_ => false,
}
}
fn parent(&self) -> Option<&'a Self> {
match self.parent_link {
ModuleParentLink(parent, _) | BlockParentLink(parent, _) => Some(parent),
NoParentLink => None,
}
}
}
impl<'a> fmt::Debug for ModuleS<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.def)
write!(f, "{:?}", self.def())
}
}
@ -903,7 +899,7 @@ impl<'a> NameBinding<'a> {
fn def(&self) -> Def {
match self.kind {
NameBindingKind::Def(def) => def,
NameBindingKind::Module(module) => module.def.unwrap(),
NameBindingKind::Module(module) => module.def().unwrap(),
NameBindingKind::Import { binding, .. } => binding.def(),
NameBindingKind::Ambiguity { .. } => Def::Err,
}
@ -1111,7 +1107,7 @@ impl<'a> ResolverArenas<'a> {
impl<'a> ty::NodeIdTree for Resolver<'a> {
fn is_descendant_of(&self, mut node: NodeId, ancestor: NodeId) -> bool {
while node != ancestor {
node = match self.module_map[&node].parent() {
node = match self.module_map[&node].parent {
Some(parent) => parent.normal_ancestor_id.unwrap(),
None => return false,
}
@ -1178,10 +1174,10 @@ impl<'a> Resolver<'a> {
macro_loader: &'a mut MacroLoader,
arenas: &'a ResolverArenas<'a>)
-> Resolver<'a> {
let root_def_id = DefId::local(CRATE_DEF_INDEX);
let graph_root_kind =
ModuleKind::Def(Def::Mod(DefId::local(CRATE_DEF_INDEX)), keywords::Invalid.name());
let graph_root =
ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), Some(CRATE_NODE_ID));
let graph_root = arenas.alloc_module(graph_root);
arenas.alloc_module(ModuleS::new(None, graph_root_kind, Some(CRATE_NODE_ID)));
let mut module_map = NodeMap();
module_map.insert(CRATE_NODE_ID, graph_root);
@ -1263,18 +1259,15 @@ impl<'a> Resolver<'a> {
self.report_errors();
}
fn new_module(&self,
parent_link: ParentLink<'a>,
def: Option<Def>,
normal_ancestor_id: Option<NodeId>)
fn new_module(&self, parent: Module<'a>, kind: ModuleKind, normal_ancestor_id: Option<NodeId>)
-> Module<'a> {
self.arenas.alloc_module(ModuleS::new(parent_link, def, normal_ancestor_id))
self.arenas.alloc_module(ModuleS::new(Some(parent), kind, normal_ancestor_id))
}
fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def, local_node_id: NodeId)
fn new_extern_crate_module(&self, parent: Module<'a>, name: Name, def: Def, node_id: NodeId)
-> Module<'a> {
let mut module = ModuleS::new(parent_link, Some(def), Some(local_node_id));
module.extern_crate_id = Some(local_node_id);
let mut module = ModuleS::new(Some(parent), ModuleKind::Def(def, name), Some(node_id));
module.extern_crate_id = Some(node_id);
module.populated.set(false);
self.arenas.modules.alloc(module)
}
@ -1336,11 +1329,10 @@ impl<'a> Resolver<'a> {
-> Option<Module<'a>> {
match this.resolve_name_in_module(module, needle, TypeNS, false, None) {
Success(binding) if binding.is_extern_crate() => Some(module),
_ => match module.parent_link {
ModuleParentLink(ref parent, _) => {
search_parent_externals(this, needle, parent)
}
_ => None,
_ => if let (&ModuleKind::Def(..), Some(parent)) = (&module.kind, module.parent) {
search_parent_externals(this, needle, parent)
} else {
None
},
}
}
@ -1516,15 +1508,13 @@ impl<'a> Resolver<'a> {
return Some(LexicalScopeBinding::Item(binding));
}
// We can only see through anonymous modules
if module.def.is_some() {
return match self.prelude {
Some(prelude) if !module.no_implicit_prelude.get() => {
self.resolve_name_in_module(prelude, name, ns, false, None).success()
.map(LexicalScopeBinding::Item)
}
_ => None,
};
if let ModuleKind::Block(..) = module.kind { // We can see through blocks
} else if !module.no_implicit_prelude.get() {
return self.prelude.and_then(|prelude| {
self.resolve_name_in_module(prelude, name, ns, false, None).success()
}).map(LexicalScopeBinding::Item)
} else {
return None;
}
}
@ -1561,7 +1551,7 @@ impl<'a> Resolver<'a> {
while i < module_path.len() && "super" == module_path[i].as_str() {
debug!("(resolving module prefix) resolving `super` at {}",
module_to_string(&containing_module));
if let Some(parent) = containing_module.parent() {
if let Some(parent) = containing_module.parent {
containing_module = self.module_map[&parent.normal_ancestor_id.unwrap()];
i += 1;
} else {
@ -2954,7 +2944,7 @@ impl<'a> Resolver<'a> {
UseLexicalScope,
Some(expr.span)) {
Success(e) => {
if let Some(def_type) = e.def {
if let Some(def_type) = e.def() {
def = def_type;
}
context = UnresolvedNameContext::PathIsMod(parent);
@ -3163,16 +3153,13 @@ impl<'a> Resolver<'a> {
};
search_in_module(self, search_module);
match search_module.parent_link {
NoParentLink | ModuleParentLink(..) => {
if !search_module.no_implicit_prelude.get() {
self.prelude.map(|prelude| search_in_module(self, prelude));
}
break;
}
BlockParentLink(parent_module, _) => {
search_module = parent_module;
if let ModuleKind::Block(..) = search_module.kind {
search_module = search_module.parent.unwrap();
} else {
if !search_module.no_implicit_prelude.get() {
self.prelude.map(|prelude| search_in_module(self, prelude));
}
break;
}
}
@ -3240,9 +3227,9 @@ impl<'a> Resolver<'a> {
// collect submodules to explore
if let Ok(module) = name_binding.module() {
// form the path
let path_segments = match module.parent_link {
NoParentLink => path_segments.clone(),
ModuleParentLink(_, name) => {
let path_segments = match module.kind {
_ if module.parent.is_none() => path_segments.clone(),
ModuleKind::Def(_, name) => {
let mut paths = path_segments.clone();
let ident = ast::Ident::with_empty_ctxt(name);
let params = PathParameters::none();
@ -3259,7 +3246,7 @@ impl<'a> Resolver<'a> {
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
// add the module to the lookup
let is_extern = in_module_is_extern || name_binding.is_extern_crate();
if !worklist.iter().any(|&(m, ..)| m.def == module.def) {
if !worklist.iter().any(|&(m, ..)| m.def() == module.def()) {
worklist.push((module, path_segments, is_extern));
}
}
@ -3294,7 +3281,7 @@ impl<'a> Resolver<'a> {
let mut path_resolution = err_path_resolution();
let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, Some(path.span)) {
Success(module) => {
path_resolution = PathResolution::new(module.def.unwrap());
path_resolution = PathResolution::new(module.def().unwrap());
ty::Visibility::Restricted(module.normal_ancestor_id.unwrap())
}
Indeterminate => unreachable!(),
@ -3360,10 +3347,10 @@ impl<'a> Resolver<'a> {
return self.report_conflict(parent, name, ns, old_binding, binding);
}
let container = match parent.def {
Some(Def::Mod(_)) => "module",
Some(Def::Trait(_)) => "trait",
None => "block",
let container = match parent.kind {
ModuleKind::Def(Def::Mod(_), _) => "module",
ModuleKind::Def(Def::Trait(_), _) => "trait",
ModuleKind::Block(..) => "block",
_ => "enum",
};
@ -3510,17 +3497,15 @@ fn module_to_string(module: Module) -> String {
let mut names = Vec::new();
fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
match module.parent_link {
NoParentLink => {}
ModuleParentLink(ref module, name) => {
if let ModuleKind::Def(_, name) = module.kind {
if let Some(parent) = module.parent {
names.push(name);
collect_mod(names, module);
}
BlockParentLink(ref module, _) => {
// danger, shouldn't be ident?
names.push(token::intern("<opaque>"));
collect_mod(names, module);
collect_mod(names, parent);
}
} else {
// danger, shouldn't be ident?
names.push(token::intern("<opaque>"));
collect_mod(names, module);
}
}
collect_mod(&mut names, module);

View File

@ -733,7 +733,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
let module = directive.imported_module.get().unwrap();
self.populate_module_if_necessary(module);
if let Some(Def::Trait(_)) = module.def {
if let Some(Def::Trait(_)) = module.def() {
self.session.span_err(directive.span, "items in traits are not importable.");
return;
} else if module.def_id() == directive.parent.def_id() {