From 9a0e88a339ca76159abaf7523ee5aaa8b19052b1 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sun, 18 Sep 2016 09:45:06 +0000 Subject: [PATCH] Refactor away `ParentLink`. --- src/librustc_resolve/build_reduced_graph.rs | 30 ++-- src/librustc_resolve/lib.rs | 147 +++++++++----------- src/librustc_resolve/resolve_imports.rs | 2 +- 3 files changed, 78 insertions(+), 101 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c9591c31831a8..8c36d712a0dd7 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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(..) => { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 016b621eabd4c..0a8514ffc73fb 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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, + parent: Option>, + kind: ModuleKind, // The node id of the closest normal module (`mod`) ancestor (including this module). normal_ancestor_id: Option, @@ -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, normal_ancestor_id: Option) + fn new(parent: Option>, kind: ModuleKind, normal_ancestor_id: Option) -> 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 { + match self.kind { + ModuleKind::Def(def, _) => Some(def), + _ => None, + } + } + fn def_id(&self) -> Option { - 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, - normal_ancestor_id: Option) + fn new_module(&self, parent: Module<'a>, kind: ModuleKind, normal_ancestor_id: Option) -> 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> { 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, 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("")); - collect_mod(names, module); + collect_mod(names, parent); } + } else { + // danger, shouldn't be ident? + names.push(token::intern("")); + collect_mod(names, module); } } collect_mod(&mut names, module); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 29add1f9b9d49..ba45b773c09f3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -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() {