1
Fork 0

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

View file

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

View file

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