]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/lib.rs
Fix a rebasing issue and addressed reviewer comment
[rust.git] / src / librustc_resolve / lib.rs
index c7031f72af4639d738a68547f55f79d446938070..c698f72955320b6b033a58967fc82ba2d80dda89 100644 (file)
@@ -26,6 +26,7 @@
 extern crate log;
 #[macro_use]
 extern crate syntax;
+extern crate arena;
 #[macro_use]
 #[no_link]
 extern crate rustc_bitflags;
@@ -90,7 +91,7 @@
 use std::cell::{Cell, RefCell};
 use std::fmt;
 use std::mem::replace;
-use std::rc::{Rc, Weak};
+use std::rc::Rc;
 
 use resolve_imports::{Target, ImportDirective, ImportResolutionPerNamespace};
 use resolve_imports::Shadowable;
 pub mod diagnostics;
 
 mod check_unused;
-mod record_exports;
 mod build_reduced_graph;
 mod resolve_imports;
 
@@ -576,7 +576,7 @@ pub enum Namespace {
 /// a particular namespace. The result is either definitely-resolved,
 /// definitely- unresolved, or unknown.
 #[derive(Clone)]
-enum NamespaceResult {
+enum NamespaceResult<'a> {
     /// Means that resolve hasn't gathered enough information yet to determine
     /// whether the name is bound in this namespace. (That is, it hasn't
     /// resolved all `use` directives yet.)
@@ -586,10 +586,10 @@ enum NamespaceResult {
     UnboundResult,
     /// Means that resolve has determined that the name is bound in the Module
     /// argument, and specified by the NameBinding argument.
-    BoundResult(Rc<Module>, NameBinding),
+    BoundResult(Module<'a>, NameBinding<'a>),
 }
 
-impl NamespaceResult {
+impl<'a> NamespaceResult<'a> {
     fn is_unknown(&self) -> bool {
         match *self {
             UnknownResult => true,
@@ -737,7 +737,7 @@ enum TypeParameters<'a> {
 }
 
 // The rib kind controls the translation of local
-// definitions (`DefLocal`) to upvars (`DefUpvar`).
+// definitions (`Def::Local`) to upvars (`Def::Upvar`).
 #[derive(Copy, Clone, Debug)]
 enum RibKind {
     // No translation needs to be applied.
@@ -766,9 +766,9 @@ enum UseLexicalScopeFlag {
     UseLexicalScope,
 }
 
-enum ModulePrefixResult {
+enum ModulePrefixResult<'a> {
     NoPrefixFound,
-    PrefixFound(Rc<Module>, usize),
+    PrefixFound(Module<'a>, usize),
 }
 
 #[derive(Copy, Clone)]
@@ -830,24 +830,24 @@ fn from_def(def: Def) -> Self {
 
 /// The link from a module up to its nearest parent node.
 #[derive(Clone,Debug)]
-enum ParentLink {
+enum ParentLink<'a> {
     NoParentLink,
-    ModuleParentLink(Weak<Module>, Name),
-    BlockParentLink(Weak<Module>, NodeId),
+    ModuleParentLink(Module<'a>, Name),
+    BlockParentLink(Module<'a>, NodeId),
 }
 
 /// One node in the tree of modules.
-pub struct Module {
-    parent_link: ParentLink,
+pub struct ModuleS<'a> {
+    parent_link: ParentLink<'a>,
     def: Cell<Option<Def>>,
     is_public: bool,
 
-    children: RefCell<HashMap<Name, NameBindings>>,
+    children: RefCell<HashMap<Name, NameBindings<'a>>>,
     imports: RefCell<Vec<ImportDirective>>,
 
     // The external module children of this node that were declared with
     // `extern crate`.
-    external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
+    external_module_children: RefCell<HashMap<Name, Module<'a>>>,
 
     // The anonymous children of this node. Anonymous children are pseudo-
     // modules that are implicitly created around items contained within
@@ -863,10 +863,10 @@ pub struct Module {
     //
     // There will be an anonymous module created around `g` with the ID of the
     // entry block for `f`.
-    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
+    anonymous_children: RefCell<NodeMap<Module<'a>>>,
 
     // The status of resolving each import in this module.
-    import_resolutions: RefCell<HashMap<Name, ImportResolutionPerNamespace>>,
+    import_resolutions: RefCell<HashMap<Name, ImportResolutionPerNamespace<'a>>>,
 
     // The number of unresolved globs that this module exports.
     glob_count: Cell<usize>,
@@ -886,13 +886,11 @@ pub struct Module {
     populated: Cell<bool>,
 }
 
-impl Module {
-    fn new(parent_link: ParentLink,
-           def: Option<Def>,
-           external: bool,
-           is_public: bool)
-           -> Rc<Module> {
-        Rc::new(Module {
+pub type Module<'a> = &'a ModuleS<'a>;
+
+impl<'a> ModuleS<'a> {
+    fn new(parent_link: ParentLink<'a>, def: Option<Def>, external: bool, is_public: bool) -> Self {
+        ModuleS {
             parent_link: parent_link,
             def: Cell::new(def),
             is_public: is_public,
@@ -906,7 +904,7 @@ fn new(parent_link: ParentLink,
             pub_glob_count: Cell::new(0),
             resolved_import_count: Cell::new(0),
             populated: Cell::new(!external),
-        })
+        }
     }
 
     fn def_id(&self) -> Option<DefId> {
@@ -915,14 +913,14 @@ fn def_id(&self) -> Option<DefId> {
 
     fn is_normal(&self) -> bool {
         match self.def.get() {
-            Some(DefMod(_)) | Some(DefForeignMod(_)) => true,
+            Some(Def::Mod(_)) | Some(Def::ForeignMod(_)) => true,
             _ => false,
         }
     }
 
     fn is_trait(&self) -> bool {
         match self.def.get() {
-            Some(DefTrait(_)) => true,
+            Some(Def::Trait(_)) => true,
             _ => false,
         }
     }
@@ -935,9 +933,7 @@ fn all_imports_resolved(&self) -> bool {
             self.imports.borrow().len() == self.resolved_import_count.get()
         }
     }
-}
 
-impl Module {
     pub fn inc_glob_count(&self) {
         self.glob_count.set(self.glob_count.get() + 1);
     }
@@ -961,7 +957,7 @@ pub fn dec_pub_glob_count(&self) {
     }
 }
 
-impl fmt::Debug for Module {
+impl<'a> fmt::Debug for ModuleS<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f,
                "{:?}, {}",
@@ -989,20 +985,20 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 // Records a possibly-private value, type, or module definition.
 #[derive(Debug)]
-struct NsDef {
+struct NsDef<'a> {
     modifiers: DefModifiers, // see note in ImportResolutionPerNamespace about how to use this
-    def_or_module: DefOrModule,
+    def_or_module: DefOrModule<'a>,
     span: Option<Span>,
 }
 
 #[derive(Debug)]
-enum DefOrModule {
+enum DefOrModule<'a> {
     Def(Def),
-    Module(Rc<Module>),
+    Module(Module<'a>),
 }
 
-impl NsDef {
-    fn create_from_module(module: Rc<Module>, span: Option<Span>) -> Self {
+impl<'a> NsDef<'a> {
+    fn create_from_module(module: Module<'a>, span: Option<Span>) -> Self {
         let modifiers = if module.is_public {
             DefModifiers::PUBLIC
         } else {
@@ -1016,9 +1012,9 @@ fn create_from_def(def: Def, modifiers: DefModifiers, span: Option<Span>) -> Sel
         NsDef { modifiers: modifiers, def_or_module: DefOrModule::Def(def), span: span }
     }
 
-    fn module(&self) -> Option<Rc<Module>> {
+    fn module(&self) -> Option<Module<'a>> {
         match self.def_or_module {
-            DefOrModule::Module(ref module) => Some(module.clone()),
+            DefOrModule::Module(ref module) => Some(module),
             DefOrModule::Def(_) => None,
         }
     }
@@ -1033,18 +1029,18 @@ fn def(&self) -> Option<Def> {
 
 // Records at most one definition that a name in a namespace is bound to
 #[derive(Clone,Debug)]
-pub struct NameBinding(Rc<RefCell<Option<NsDef>>>);
+pub struct NameBinding<'a>(Rc<RefCell<Option<NsDef<'a>>>>);
 
-impl NameBinding {
+impl<'a> NameBinding<'a> {
     fn new() -> Self {
         NameBinding(Rc::new(RefCell::new(None)))
     }
 
-    fn create_from_module(module: Rc<Module>) -> Self {
+    fn create_from_module(module: Module<'a>) -> Self {
         NameBinding(Rc::new(RefCell::new(Some(NsDef::create_from_module(module, None)))))
     }
 
-    fn set(&self, ns_def: NsDef) {
+    fn set(&self, ns_def: NsDef<'a>) {
         *self.0.borrow_mut() = Some(ns_def);
     }
 
@@ -1054,7 +1050,7 @@ fn set_modifiers(&self, modifiers: DefModifiers) {
         }
     }
 
-    fn borrow(&self) -> ::std::cell::Ref<Option<NsDef>> {
+    fn borrow(&self) -> ::std::cell::Ref<Option<NsDef<'a>>> {
         self.0.borrow()
     }
 
@@ -1062,7 +1058,7 @@ fn borrow(&self) -> ::std::cell::Ref<Option<NsDef>> {
     fn def(&self) -> Option<Def> {
         self.borrow().as_ref().and_then(NsDef::def)
     }
-    fn module(&self) -> Option<Rc<Module>> {
+    fn module(&self) -> Option<Module<'a>> {
         self.borrow().as_ref().and_then(NsDef::module)
     }
     fn span(&self) -> Option<Span> {
@@ -1093,20 +1089,20 @@ fn def_and_lp(&self) -> (Def, LastPrivate) {
 // Records the definitions (at most one for each namespace) that a name is
 // bound to.
 #[derive(Clone,Debug)]
-pub struct NameBindings {
-    type_ns: NameBinding, // < Meaning in type namespace.
-    value_ns: NameBinding, // < Meaning in value namespace.
+pub struct NameBindings<'a> {
+    type_ns: NameBinding<'a>, // < Meaning in type namespace.
+    value_ns: NameBinding<'a>, // < Meaning in value namespace.
 }
 
-impl ::std::ops::Index<Namespace> for NameBindings {
-    type Output = NameBinding;
-    fn index(&self, namespace: Namespace) -> &NameBinding {
+impl<'a> ::std::ops::Index<Namespace> for NameBindings<'a> {
+    type Output = NameBinding<'a>;
+    fn index(&self, namespace: Namespace) -> &NameBinding<'a> {
         match namespace { TypeNS => &self.type_ns, ValueNS => &self.value_ns }
     }
 }
 
-impl NameBindings {
-    fn new() -> NameBindings {
+impl<'a> NameBindings<'a> {
+    fn new() -> Self {
         NameBindings {
             type_ns: NameBinding::new(),
             value_ns: NameBinding::new(),
@@ -1114,7 +1110,7 @@ fn new() -> NameBindings {
     }
 
     /// Creates a new module in this set of name bindings.
-    fn define_module(&self, module: Rc<Module>, sp: Span) {
+    fn define_module(&self, module: Module<'a>, sp: Span) {
         self.type_ns.set(NsDef::create_from_module(module, Some(sp)));
     }
 
@@ -1170,7 +1166,7 @@ pub struct Resolver<'a, 'tcx: 'a> {
 
     ast_map: &'a hir_map::Map<'tcx>,
 
-    graph_root: Rc<Module>,
+    graph_root: Module<'a>,
 
     trait_item_map: FnvHashMap<(Name, DefId), DefId>,
 
@@ -1180,7 +1176,7 @@ pub struct Resolver<'a, 'tcx: 'a> {
     unresolved_imports: usize,
 
     // The module that represents the current item scope.
-    current_module: Rc<Module>,
+    current_module: Module<'a>,
 
     // The current set of local scopes, for values.
     // FIXME #4948: Reuse ribs to avoid allocation.
@@ -1226,6 +1222,12 @@ pub struct Resolver<'a, 'tcx: 'a> {
     // The intention is that the callback modifies this flag.
     // Once set, the resolver falls out of the walk, preserving the ribs.
     resolved: bool,
+
+    arenas: &'a ResolverArenas<'a>,
+}
+
+pub struct ResolverArenas<'a> {
+    modules: arena::TypedArena<ModuleS<'a>>,
 }
 
 #[derive(PartialEq)]
@@ -1237,10 +1239,12 @@ enum FallbackChecks {
 impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn new(session: &'a Session,
            ast_map: &'a hir_map::Map<'tcx>,
-           make_glob_map: MakeGlobMap)
+           make_glob_map: MakeGlobMap,
+           arenas: &'a ResolverArenas<'a>)
            -> Resolver<'a, 'tcx> {
         let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
-        let graph_root = Module::new(NoParentLink, Some(DefMod(root_def_id)), false, true);
+        let graph_root = ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, true);
+        let graph_root = arenas.modules.alloc(graph_root);
 
         Resolver {
             session: session,
@@ -1249,7 +1253,7 @@ fn new(session: &'a Session,
 
             // The outermost module has def ID 0; this is not reflected in the
             // AST.
-            graph_root: graph_root.clone(),
+            graph_root: graph_root,
 
             trait_item_map: FnvHashMap(),
             structs: FnvHashMap(),
@@ -1281,9 +1285,25 @@ fn new(session: &'a Session,
 
             callback: None,
             resolved: false,
+
+            arenas: arenas,
+        }
+    }
+
+    fn arenas() -> ResolverArenas<'a> {
+        ResolverArenas {
+            modules: arena::TypedArena::new(),
         }
     }
 
+    fn new_module(&self,
+                  parent_link: ParentLink<'a>,
+                  def: Option<Def>,
+                  external: bool,
+                  is_public: bool) -> Module<'a> {
+        self.arenas.modules.alloc(ModuleS::new(parent_link, def, external, is_public))
+    }
+
     #[inline]
     fn record_import_use(&mut self, import_id: NodeId, name: Name) {
         if !self.make_glob_map {
@@ -1308,7 +1328,7 @@ fn get_trait_name(&self, did: DefId) -> Name {
     }
 
     /// Check that an external crate doesn't collide with items or other external crates.
-    fn check_for_conflicts_for_external_crate(&self, module: &Module, name: Name, span: Span) {
+    fn check_for_conflicts_for_external_crate(&self, module: Module<'a>, name: Name, span: Span) {
         if module.external_module_children.borrow().contains_key(&name) {
             span_err!(self.session,
                       span,
@@ -1328,7 +1348,7 @@ fn check_for_conflicts_for_external_crate(&self, module: &Module, name: Name, sp
 
     /// Checks that the names of items don't collide with external crates.
     fn check_for_conflicts_between_external_crates_and_items(&self,
-                                                             module: &Module,
+                                                             module: Module<'a>,
                                                              name: Name,
                                                              span: Span) {
         if module.external_module_children.borrow().contains_key(&name) {
@@ -1338,19 +1358,20 @@ fn check_for_conflicts_between_external_crates_and_items(&self,
 
     /// Resolves the given module path from the given root `module_`.
     fn resolve_module_path_from_root(&mut self,
-                                     module_: Rc<Module>,
+                                     module_: Module<'a>,
                                      module_path: &[Name],
                                      index: usize,
                                      span: Span,
                                      name_search_type: NameSearchType,
                                      lp: LastPrivate)
-                                     -> ResolveResult<(Rc<Module>, LastPrivate)> {
-        fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Module>> {
+                                     -> ResolveResult<(Module<'a>, LastPrivate)> {
+        fn search_parent_externals<'a>(needle: Name, module: Module<'a>)
+                                       -> Option<Module<'a>> {
             match module.external_module_children.borrow().get(&needle) {
-                Some(_) => Some(module.clone()),
+                Some(_) => Some(module),
                 None => match module.parent_link {
                     ModuleParentLink(ref parent, _) => {
-                        search_parent_externals(needle, &parent.upgrade().unwrap())
+                        search_parent_externals(needle, parent)
                     }
                     _ => None,
                 },
@@ -1367,14 +1388,14 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Modul
         // modules as we go.
         while index < module_path_len {
             let name = module_path[index];
-            match self.resolve_name_in_module(search_module.clone(),
+            match self.resolve_name_in_module(search_module,
                                               name,
                                               TypeNS,
                                               name_search_type,
                                               false) {
                 Failed(None) => {
                     let segment_name = name.as_str();
-                    let module_name = module_to_string(&*search_module);
+                    let module_name = module_to_string(search_module);
                     let mut span = span;
                     let msg = if "???" == &module_name[..] {
                         span.hi = span.lo + Pos::from_usize(segment_name.len());
@@ -1445,12 +1466,12 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Modul
     /// On success, returns the resolved module, and the closest *private*
     /// module found to the destination when resolving this path.
     fn resolve_module_path(&mut self,
-                           module_: Rc<Module>,
+                           module_: Module<'a>,
                            module_path: &[Name],
                            use_lexical_scope: UseLexicalScopeFlag,
                            span: Span,
                            name_search_type: NameSearchType)
-                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
+                           -> ResolveResult<(Module<'a>, LastPrivate)> {
         let module_path_len = module_path.len();
         assert!(module_path_len > 0);
 
@@ -1459,7 +1480,7 @@ fn resolve_module_path(&mut self,
                module_to_string(&*module_));
 
         // Resolve the module prefix, if any.
-        let module_prefix_result = self.resolve_module_prefix(module_.clone(), module_path);
+        let module_prefix_result = self.resolve_module_prefix(module_, module_path);
 
         let search_module;
         let start_index;
@@ -1495,7 +1516,7 @@ fn resolve_module_path(&mut self,
                     DontUseLexicalScope => {
                         // This is a crate-relative path. We will start the
                         // resolution process at index zero.
-                        search_module = self.graph_root.clone();
+                        search_module = self.graph_root;
                         start_index = 0;
                         last_private = LastMod(AllPublic);
                     }
@@ -1519,7 +1540,7 @@ fn resolve_module_path(&mut self,
                 }
             }
             Success(PrefixFound(ref containing_module, index)) => {
-                search_module = containing_module.clone();
+                search_module = containing_module;
                 start_index = index;
                 last_private = LastMod(DependsOn(containing_module.def_id()
                                                                   .unwrap()));
@@ -1537,11 +1558,11 @@ fn resolve_module_path(&mut self,
     /// Invariant: This must only be called during main resolution, not during
     /// import resolution.
     fn resolve_item_in_lexical_scope(&mut self,
-                                     module_: Rc<Module>,
+                                     module_: Module<'a>,
                                      name: Name,
                                      namespace: Namespace,
                                      record_used: bool)
-                                     -> ResolveResult<(Target, bool)> {
+                                     -> ResolveResult<(Target<'a>, bool)> {
         debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
                name,
                namespace,
@@ -1554,7 +1575,7 @@ fn resolve_item_in_lexical_scope(&mut self,
         match module_.children.borrow().get(&name) {
             Some(name_bindings) if name_bindings[namespace].defined() => {
                 debug!("top name bindings succeeded");
-                return Success((Target::new(module_.clone(),
+                return Success((Target::new(module_,
                                             name_bindings[namespace].clone(),
                                             Shadowable::Never),
                                 false));
@@ -1594,9 +1615,8 @@ fn resolve_item_in_lexical_scope(&mut self,
 
         // Search for external modules.
         if namespace == TypeNS {
-            // FIXME (21114): In principle unclear `child` *has* to be lifted.
-            let child = module_.external_module_children.borrow().get(&name).cloned();
-            if let Some(module) = child {
+            let children = module_.external_module_children.borrow();
+            if let Some(module) = children.get(&name) {
                 let name_binding = NameBinding::create_from_module(module);
                 debug!("lower name bindings succeeded");
                 return Success((Target::new(module_, name_binding, Shadowable::Never),
@@ -1608,7 +1628,7 @@ fn resolve_item_in_lexical_scope(&mut self,
         let mut search_module = module_;
         loop {
             // Go to the next parent.
-            match search_module.parent_link.clone() {
+            match search_module.parent_link {
                 NoParentLink => {
                     // No more parents. This module was unresolved.
                     debug!("(resolving item in lexical scope) unresolved module");
@@ -1621,16 +1641,16 @@ fn resolve_item_in_lexical_scope(&mut self,
                                 searching through module parents");
                             return Failed(None);
                     } else {
-                        search_module = parent_module_node.upgrade().unwrap();
+                        search_module = parent_module_node;
                     }
                 }
-                BlockParentLink(ref parent_module_node, _) => {
-                    search_module = parent_module_node.upgrade().unwrap();
+                BlockParentLink(parent_module_node, _) => {
+                    search_module = parent_module_node;
                 }
             }
 
             // Resolve the name in the parent module.
-            match self.resolve_name_in_module(search_module.clone(),
+            match self.resolve_name_in_module(search_module,
                                               name,
                                               namespace,
                                               PathSearch,
@@ -1657,9 +1677,9 @@ fn resolve_item_in_lexical_scope(&mut self,
 
     /// Resolves a module name in the current lexical scope.
     fn resolve_module_in_lexical_scope(&mut self,
-                                       module_: Rc<Module>,
+                                       module_: Module<'a>,
                                        name: Name)
-                                       -> ResolveResult<Rc<Module>> {
+                                       -> ResolveResult<Module<'a>> {
         // If this module is an anonymous module, resolve the item in the
         // lexical scope. Otherwise, resolve the item from the crate root.
         let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS, true);
@@ -1685,14 +1705,14 @@ fn resolve_module_in_lexical_scope(&mut self,
     }
 
     /// Returns the nearest normal module parent of the given module.
-    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) -> Option<Rc<Module>> {
+    fn get_nearest_normal_module_parent(&mut self, module_: Module<'a>) -> Option<Module<'a>> {
         let mut module_ = module_;
         loop {
-            match module_.parent_link.clone() {
+            match module_.parent_link {
                 NoParentLink => return None,
                 ModuleParentLink(new_module, _) |
                 BlockParentLink(new_module, _) => {
-                    let new_module = new_module.upgrade().unwrap();
+                    let new_module = new_module;
                     if new_module.is_normal() {
                         return Some(new_module);
                     }
@@ -1704,11 +1724,11 @@ fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) -> Option<Rc
 
     /// Returns the nearest normal module parent of the given module, or the
     /// module itself if it is a normal module.
-    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) -> Rc<Module> {
+    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Module<'a>) -> Module<'a> {
         if module_.is_normal() {
             return module_;
         }
-        match self.get_nearest_normal_module_parent(module_.clone()) {
+        match self.get_nearest_normal_module_parent(module_) {
             None => module_,
             Some(new_module) => new_module,
         }
@@ -1718,9 +1738,9 @@ fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) -> R
     /// (b) some chain of `super::`.
     /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
     fn resolve_module_prefix(&mut self,
-                             module_: Rc<Module>,
+                             module_: Module<'a>,
                              module_path: &[Name])
-                             -> ResolveResult<ModulePrefixResult> {
+                             -> ResolveResult<ModulePrefixResult<'a>> {
         // Start at the current module if we see `self` or `super`, or at the
         // top of the crate otherwise.
         let mut i = match &*module_path[0].as_str() {
@@ -1756,12 +1776,12 @@ fn resolve_module_prefix(&mut self,
     /// The boolean returned on success is an indicator of whether this lookup
     /// passed through a public re-export proxy.
     fn resolve_name_in_module(&mut self,
-                              module_: Rc<Module>,
+                              module_: Module<'a>,
                               name: Name,
                               namespace: Namespace,
                               name_search_type: NameSearchType,
                               allow_private_imports: bool)
-                              -> ResolveResult<(Target, bool)> {
+                              -> ResolveResult<(Target<'a>, bool)> {
         debug!("(resolving name in module) resolving `{}` in `{}`",
                name,
                module_to_string(&*module_));
@@ -1769,10 +1789,11 @@ fn resolve_name_in_module(&mut self,
         // First, check the direct children of the module.
         build_reduced_graph::populate_module_if_necessary(self, &module_);
 
-        match module_.children.borrow().get(&name) {
+        let children = module_.children.borrow();
+        match children.get(&name) {
             Some(name_bindings) if name_bindings[namespace].defined() => {
                 debug!("(resolving name in module) found node as child");
-                return Success((Target::new(module_.clone(),
+                return Success((Target::new(module_,
                                             name_bindings[namespace].clone(),
                                             Shadowable::Never),
                                 false));
@@ -1791,7 +1812,8 @@ fn resolve_name_in_module(&mut self,
         }
 
         // Check the list of resolved imports.
-        match module_.import_resolutions.borrow().get(&name) {
+        let children = module_.import_resolutions.borrow();
+        match children.get(&name) {
             Some(import_resolution) if allow_private_imports ||
                                        import_resolution[namespace].is_public => {
 
@@ -1823,9 +1845,8 @@ fn resolve_name_in_module(&mut self,
 
         // Finally, search through external children.
         if namespace == TypeNS {
-            // FIXME (21114): In principle unclear `child` *has* to be lifted.
-            let child = module_.external_module_children.borrow().get(&name).cloned();
-            if let Some(module) = child {
+            let children = module_.external_module_children.borrow();
+            if let Some(module) = children.get(&name) {
                 let name_binding = NameBinding::create_from_module(module);
                 return Success((Target::new(module_, name_binding, Shadowable::Never),
                                 false));
@@ -1837,7 +1858,7 @@ fn resolve_name_in_module(&mut self,
         return Failed(None);
     }
 
-    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
+    fn report_unresolved_imports(&mut self, module_: Module<'a>) {
         let index = module_.resolved_import_count.get();
         let imports = module_.imports.borrow();
         let import_count = imports.len();
@@ -1862,7 +1883,7 @@ fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
         }
 
         for (_, module_) in module_.anonymous_children.borrow().iter() {
-            self.report_unresolved_imports(module_.clone());
+            self.report_unresolved_imports(module_);
         }
     }
 
@@ -1887,7 +1908,7 @@ fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
     fn with_scope<F>(&mut self, name: Option<Name>, f: F)
         where F: FnOnce(&mut Resolver)
     {
-        let orig_module = self.current_module.clone();
+        let orig_module = self.current_module;
 
         // Move down in the graph.
         match name {
@@ -1999,7 +2020,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                ItemRibKind),
                                              |this| {
                     let local_def_id = this.ast_map.local_def_id(item.id);
-                    this.with_self_rib(DefSelfTy(Some(local_def_id), None), |this| {
+                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_ty_param_bound, bounds);
 
@@ -2055,7 +2076,8 @@ fn resolve_item(&mut self, item: &Item) {
                 // check for imports shadowing primitive types
                 let check_rename = |this: &Self, id, name| {
                     match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
-                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
+                        Some(Def::Enum(..)) | Some(Def::TyAlias(..)) | Some(Def::Struct(..)) |
+                        Some(Def::Trait(..)) | None => {
                             this.check_if_primitive_type_name(name, item.span);
                         }
                         _ => {}
@@ -2121,7 +2143,7 @@ fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F)
                     // plain insert (no renaming)
                     function_type_rib.bindings
                                      .insert(name,
-                                             DlDef(DefTyParam(space,
+                                             DlDef(Def::TyParam(space,
                                                               index as u32,
                                                               self.ast_map
                                                                   .local_def_id(type_parameter.id),
@@ -2204,7 +2226,7 @@ fn resolve_trait_reference(&mut self,
                                path_depth: usize)
                                -> Result<PathResolution, ()> {
         if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
-            if let DefTrait(_) = path_res.base_def {
+            if let Def::Trait(_) = path_res.base_def {
                 debug!("(resolving trait) found trait def: {:?}", path_res);
                 Ok(path_res)
             } else {
@@ -2215,7 +2237,7 @@ fn resolve_trait_reference(&mut self,
                                                                                       path_depth)));
 
                 // If it's a typedef, give a note
-                if let DefTy(..) = path_res.base_def {
+                if let Def::TyAlias(..) = path_res.base_def {
                     err.span_note(trait_path.span,
                                   "`type` aliases cannot be used for traits");
                 }
@@ -2241,7 +2263,7 @@ fn resolve_generics(&mut self, generics: &Generics) {
                 &hir::WherePredicate::RegionPredicate(_) => {}
                 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
                     let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
-                    if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
+                    if let Some(PathResolution { base_def: Def::TyParam(..), .. }) = path_res {
                         self.record_def(eq_pred.id, path_res.unwrap());
                     } else {
                         resolve_error(self,
@@ -2323,7 +2345,7 @@ fn resolve_implementation(&mut self,
                 // Resolve the self type.
                 this.visit_ty(self_type);
 
-                this.with_self_rib(DefSelfTy(trait_id, Some((item_id, self_type.id))), |this| {
+                this.with_self_rib(Def::SelfTy(trait_id, Some((item_id, self_type.id))), |this| {
                     this.with_current_self_type(self_type, |this| {
                         for impl_item in impl_items {
                             match impl_item.node {
@@ -2475,14 +2497,14 @@ fn resolve_block(&mut self, block: &Block) {
         self.value_ribs.push(Rib::new(NormalRibKind));
 
         // Move down in the graph, if there's an anonymous module rooted here.
-        let orig_module = self.current_module.clone();
+        let orig_module = self.current_module;
         match orig_module.anonymous_children.borrow().get(&block.id) {
             None => {
                 // Nothing to do.
             }
             Some(anonymous_module) => {
                 debug!("(resolving block) found anonymous module, moving down");
-                self.current_module = anonymous_module.clone();
+                self.current_module = anonymous_module;
             }
         }
 
@@ -2659,7 +2681,7 @@ fn resolve_pattern(&mut self,
                             debug!("(resolving pattern) binding `{}`", renamed);
 
                             let def_id = self.ast_map.local_def_id(pattern.id);
-                            let def = DefLocal(def_id, pattern.id);
+                            let def = Def::Local(def_id, pattern.id);
 
                             // Record the definition so that later passes
                             // will be able to distinguish variants from
@@ -2730,10 +2752,13 @@ fn resolve_pattern(&mut self,
                     };
                     if let Some(path_res) = resolution {
                         match path_res.base_def {
-                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
+                            Def::Struct(..) if path_res.depth == 0 => {
+                                self.record_def(pattern.id, path_res);
+                            }
+                            Def::Variant(..) | Def::Const(..) => {
                                 self.record_def(pattern.id, path_res);
                             }
-                            DefStatic(..) => {
+                            Def::Static(..) => {
                                 resolve_error(&self,
                                               path.span,
                                               ResolutionError::StaticVariableReference);
@@ -2808,7 +2833,7 @@ fn resolve_pattern(&mut self,
                         match path_res.base_def {
                             // All `<T as Trait>::CONST` should end up here, and
                             // have the trait already selected.
-                            DefAssociatedConst(..) => {
+                            Def::AssociatedConst(..) => {
                                 self.record_def(pattern.id, path_res);
                             }
                             _ => {
@@ -2871,7 +2896,7 @@ fn resolve_bare_identifier_pattern(&mut self,
                                        name: Name,
                                        span: Span)
                                        -> BareIdentifierPatternResolution {
-        let module = self.current_module.clone();
+        let module = self.current_module;
         match self.resolve_item_in_lexical_scope(module, name, ValueNS, true) {
             Success((target, _)) => {
                 debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
@@ -2885,13 +2910,13 @@ fn resolve_bare_identifier_pattern(&mut self,
                     // For the two success cases, this lookup can be
                     // considered as not having a private component because
                     // the lookup happened only within the current module.
-                    Some(def @ DefVariant(..)) | Some(def @ DefStruct(..)) => {
+                    Some(def @ Def::Variant(..)) | Some(def @ Def::Struct(..)) => {
                         return FoundStructOrEnumVariant(def, LastMod(AllPublic));
                     }
-                    Some(def @ DefConst(..)) | Some(def @ DefAssociatedConst(..)) => {
+                    Some(def @ Def::Const(..)) | Some(def @ Def::AssociatedConst(..)) => {
                         return FoundConst(def, LastMod(AllPublic), name);
                     }
-                    Some(DefStatic(..)) => {
+                    Some(Def::Static(..)) => {
                         resolve_error(self, span, ResolutionError::StaticVariableReference);
                         return BareIdentifierPatternUnresolved;
                     }
@@ -2951,7 +2976,7 @@ fn resolve_possibly_assoc_item(&mut self,
                 resolution = this.resolve_path(id, path, depth, TypeNS, true);
             });
         }
-        if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
+        if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
             // A module is not a valid type or value.
             resolution = None;
         }
@@ -3012,12 +3037,16 @@ fn resolve_identifier(&mut self,
                           check_ribs: bool,
                           record_used: bool)
                           -> Option<LocalDef> {
+        if identifier.name == special_idents::invalid.name {
+            return Some(LocalDef::from_def(Def::Err));
+        }
+
         // First, check to see whether the name is a primitive type.
         if namespace == TypeNS {
             if let Some(&prim_ty) = self.primitive_type_table
                                         .primitive_types
                                         .get(&identifier.unhygienic_name) {
-                return Some(LocalDef::from_def(DefPrimTy(prim_ty)));
+                return Some(LocalDef::from_def(Def::PrimTy(prim_ty)));
             }
         }
 
@@ -3041,10 +3070,10 @@ fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
         };
         let mut def = local_def.def;
         match def {
-            DefUpvar(..) => {
+            Def::Upvar(..) => {
                 self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
             }
-            DefLocal(_, node_id) => {
+            Def::Local(_, node_id) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind => {
@@ -3058,7 +3087,7 @@ fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
                                            .entry(function_id)
                                            .or_insert_with(|| NodeMap());
                             if let Some(&index) = seen.get(&node_id) {
-                                def = DefUpvar(node_def_id, node_id, index, function_id);
+                                def = Def::Upvar(node_def_id, node_id, index, function_id);
                                 continue;
                             }
                             let vec = self.freevars
@@ -3070,7 +3099,7 @@ fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
                                 span: span,
                             });
 
-                            def = DefUpvar(node_def_id, node_id, depth, function_id);
+                            def = Def::Upvar(node_def_id, node_id, depth, function_id);
                             seen.insert(node_id, depth);
                         }
                         ItemRibKind | MethodRibKind => {
@@ -3092,7 +3121,7 @@ fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
                     }
                 }
             }
-            DefTyParam(..) | DefSelfTy(..) => {
+            Def::TyParam(..) | Def::SelfTy(..) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
@@ -3135,7 +3164,7 @@ fn resolve_module_relative_path(&mut self,
 
         let containing_module;
         let last_private;
-        let current_module = self.current_module.clone();
+        let current_module = self.current_module;
         match self.resolve_module_path(current_module,
                                        &module_path[..],
                                        UseLexicalScope,
@@ -3162,7 +3191,7 @@ fn resolve_module_relative_path(&mut self,
         }
 
         let name = segments.last().unwrap().identifier.name;
-        let def = match self.resolve_name_in_module(containing_module.clone(),
+        let def = match self.resolve_name_in_module(containing_module,
                                                     name,
                                                     namespace,
                                                     NameSearchType::PathSearch,
@@ -3193,7 +3222,7 @@ fn resolve_crate_relative_path(&mut self,
                                   .map(|ps| ps.identifier.name)
                                   .collect::<Vec<_>>();
 
-        let root_module = self.graph_root.clone();
+        let root_module = self.graph_root;
 
         let containing_module;
         let last_private;
@@ -3283,7 +3312,7 @@ fn resolve_item_by_name_in_lexical_scope(&mut self,
                                              record_used: bool)
                                              -> Option<Def> {
         // Check the items.
-        let module = self.current_module.clone();
+        let module = self.current_module;
         match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
             Success((target, _)) => {
                 match target.binding.def() {
@@ -3345,11 +3374,11 @@ fn extract_path_and_node_id(t: &Ty,
             }
         }
 
-        fn get_module(this: &mut Resolver,
-                      span: Span,
-                      name_path: &[ast::Name])
-                      -> Option<Rc<Module>> {
-            let root = this.current_module.clone();
+        fn get_module<'a, 'tcx>(this: &mut Resolver<'a, 'tcx>,
+                                span: Span,
+                                name_path: &[ast::Name])
+                                -> Option<Module<'a>> {
+            let root = this.current_module;
             let last_name = name_path.last().unwrap();
 
             if name_path.len() == 1 {
@@ -3404,9 +3433,10 @@ fn is_static_method(this: &Resolver, did: DefId) -> bool {
         if allowed == Everything {
             // Look for a field with the same name in the current self_type.
             match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
-                Some(DefTy(did, _)) |
-                Some(DefStruct(did)) |
-                Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
+                Some(Def::Enum(did)) |
+                Some(Def::TyAlias(did)) |
+                Some(Def::Struct(did)) |
+                Some(Def::Variant(_, did)) => match self.structs.get(&did) {
                     None => {}
                     Some(fields) => {
                         if fields.iter().any(|&field_name| name == field_name) {
@@ -3423,7 +3453,7 @@ fn is_static_method(this: &Resolver, did: DefId) -> bool {
         // Look for a method in the current self type's impl module.
         if let Some(module) = get_module(self, path.span, &name_path) {
             if let Some(binding) = module.children.borrow().get(&name) {
-                if let Some(DefMethod(did)) = binding.value_ns.def() {
+                if let Some(Def::Method(did)) = binding.value_ns.def() {
                     if is_static_method(self, did) {
                         return StaticMethod(path_names_to_string(&path, 0));
                     }
@@ -3497,7 +3527,13 @@ fn resolve_expr(&mut self, expr: &Expr) {
                 // scopes looking for it.
                 if let Some(path_res) = resolution {
                     // Check if struct variant
-                    if let DefVariant(_, _, true) = path_res.base_def {
+                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
+                        self.structs.contains_key(&variant_id)
+                    } else {
+                        false
+                    };
+                    if is_struct_variant {
+                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
                         let path_name = path_names_to_string(path, 0);
 
                         let mut err = resolve_struct_error(self,
@@ -3540,7 +3576,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
 
                     self.record_def(expr.id, err_path_resolution());
                     match type_res.map(|r| r.base_def) {
-                        Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
+                        Some(Def::Struct(..)) => {
                             let mut err = resolve_struct_error(self,
                                 expr.span,
                                 ResolutionError::StructVariantUsedAsFunction(&*path_name));
@@ -3603,7 +3639,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                     let name_path = path.segments.iter()
                                                         .map(|seg| seg.identifier.name)
                                                         .collect::<Vec<_>>();
-                                    let current_module = self.current_module.clone();
+                                    let current_module = self.current_module;
 
                                     match self.resolve_module_path(current_module,
                                                    &name_path[..],
@@ -3652,7 +3688,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
 
             ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
                 self.with_label_rib(|this| {
-                    let def_like = DlDef(DefLabel(expr.id));
+                    let def_like = DlDef(Def::Label(expr.id));
 
                     {
                         let rib = this.label_ribs.last_mut().unwrap();
@@ -3671,7 +3707,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                       label.span,
                                       ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
                     }
-                    Some(DlDef(def @ DefLabel(_))) => {
+                    Some(DlDef(def @ Def::Label(_))) => {
                         // Since this def is a label, it is never read.
                         self.record_def(expr.id,
                                         PathResolution {
@@ -3725,7 +3761,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name
         }
 
         let mut found_traits = Vec::new();
-        let mut search_module = self.current_module.clone();
+        let mut search_module = self.current_module;
         loop {
             // Look for the current trait.
             match self.current_trait_ref {
@@ -3747,7 +3783,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name
                         None => continue,
                     };
                     let trait_def_id = match def {
-                        DefTrait(trait_def_id) => trait_def_id,
+                        Def::Trait(trait_def_id) => trait_def_id,
                         _ => continue,
                     };
                     if self.trait_item_map.contains_key(&(name, trait_def_id)) {
@@ -3763,7 +3799,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name
                     Some(ref target) => target,
                 };
                 let did = match target.binding.def() {
-                    Some(DefTrait(trait_def_id)) => trait_def_id,
+                    Some(Def::Trait(trait_def_id)) => trait_def_id,
                     Some(..) | None => continue,
                 };
                 if self.trait_item_map.contains_key(&(name, did)) {
@@ -3778,10 +3814,10 @@ fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name
                 }
             }
 
-            match search_module.parent_link.clone() {
+            match search_module.parent_link {
                 NoParentLink | ModuleParentLink(..) => break,
                 BlockParentLink(parent_module, _) => {
-                    search_module = parent_module.upgrade().unwrap();
+                    search_module = parent_module;
                 }
             }
         }
@@ -3828,7 +3864,7 @@ fn enforce_default_binding_mode(&mut self,
     //
 
     #[allow(dead_code)]   // useful for debugging
-    fn dump_module(&mut self, module_: Rc<Module>) {
+    fn dump_module(&mut self, module_: Module<'a>) {
         debug!("Dump of module `{}`:", module_to_string(&*module_));
 
         debug!("Children:");
@@ -3891,20 +3927,20 @@ fn path_names_to_string(path: &Path, depth: usize) -> String {
 }
 
 /// A somewhat inefficient routine to obtain the name of a module.
-fn module_to_string(module: &Module) -> String {
+fn module_to_string<'a>(module: Module<'a>) -> String {
     let mut names = Vec::new();
 
-    fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
+    fn collect_mod<'a>(names: &mut Vec<ast::Name>, module: Module<'a>) {
         match module.parent_link {
             NoParentLink => {}
             ModuleParentLink(ref module, name) => {
                 names.push(name);
-                collect_mod(names, &*module.upgrade().unwrap());
+                collect_mod(names, module);
             }
             BlockParentLink(ref module, _) => {
                 // danger, shouldn't be ident?
                 names.push(special_idents::opaque.name);
-                collect_mod(names, &*module.upgrade().unwrap());
+                collect_mod(names, module);
             }
         }
     }
@@ -3918,7 +3954,7 @@ fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
 
 fn err_path_resolution() -> PathResolution {
     PathResolution {
-        base_def: DefErr,
+        base_def: Def::Err,
         last_private: LastMod(AllPublic),
         depth: 0,
     }
@@ -3946,7 +3982,8 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                                make_glob_map: MakeGlobMap)
                                -> CrateMap {
     let krate = ast_map.krate();
-    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
+    let arenas = Resolver::arenas();
+    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
 
     resolver.resolve_crate(krate);
 
@@ -3978,20 +4015,16 @@ pub fn create_resolver<'a, 'tcx>(session: &'a Session,
                                  ast_map: &'a hir_map::Map<'tcx>,
                                  krate: &'a Crate,
                                  make_glob_map: MakeGlobMap,
+                                 arenas: &'a ResolverArenas<'a>,
                                  callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
                                  -> Resolver<'a, 'tcx> {
-    let mut resolver = Resolver::new(session, ast_map, make_glob_map);
+    let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas);
 
     resolver.callback = callback;
 
     build_reduced_graph::build_reduced_graph(&mut resolver, krate);
-    session.abort_if_errors();
 
     resolve_imports::resolve_imports(&mut resolver);
-    session.abort_if_errors();
-
-    record_exports::record(&mut resolver);
-    session.abort_if_errors();
 
     resolver
 }