]> git.lizzy.rs Git - rust.git/commitdiff
Refactor away `module.resolve_name()`.
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Mon, 1 Aug 2016 20:43:48 +0000 (20:43 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Thu, 18 Aug 2016 03:22:47 +0000 (03:22 +0000)
src/librustc_resolve/lib.rs
src/librustc_resolve/resolve_imports.rs

index 08cfc662e9bea71ef88b5124a7e80d5b6c5303f9..71dee48f3396d82ed7961fdfa4d12b8a232f4d94 100644 (file)
@@ -1250,12 +1250,13 @@ fn resolve_module_path_from_root(&mut self,
                                      index: usize,
                                      span: Span)
                                      -> ResolveResult<Module<'a>> {
-        fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
-            match module.resolve_name(needle, TypeNS, false) {
+        fn search_parent_externals<'a>(this: &mut Resolver<'a>, needle: Name, module: Module<'a>)
+                                       -> Option<Module<'a>> {
+            match this.resolve_name_in_module(module, needle, TypeNS, false, false) {
                 Success(binding) if binding.is_extern_crate() => Some(module),
                 _ => match module.parent_link {
                     ModuleParentLink(ref parent, _) => {
-                        search_parent_externals(needle, parent)
+                        search_parent_externals(this, needle, parent)
                     }
                     _ => None,
                 },
@@ -1275,11 +1276,12 @@ fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
                     let segment_name = name.as_str();
                     let module_name = module_to_string(search_module);
                     let msg = if "???" == &module_name {
-                        match search_parent_externals(name, &self.current_module) {
+                        let current_module = self.current_module;
+                        match search_parent_externals(self, name, current_module) {
                             Some(module) => {
                                 let path_str = names_to_string(module_path);
                                 let target_mod_str = module_to_string(&module);
-                                let current_mod_str = module_to_string(&self.current_module);
+                                let current_mod_str = module_to_string(current_module);
 
                                 let prefix = if target_mod_str == current_mod_str {
                                     "self::".to_string()
@@ -1436,8 +1438,8 @@ fn resolve_ident_in_lexical_scope(&mut self,
                 if module.def.is_some() {
                     return match self.prelude {
                         Some(prelude) if !module.no_implicit_prelude.get() => {
-                            prelude.resolve_name(name, ns, false).success()
-                                   .map(LexicalScopeBinding::Item)
+                            self.resolve_name_in_module(prelude, name, ns, false, false).success()
+                                .map(LexicalScopeBinding::Item)
                         }
                         _ => None,
                     };
@@ -1523,27 +1525,6 @@ fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span)
         return Success(PrefixFound(containing_module, i));
     }
 
-    /// Attempts to resolve the supplied name in the given module for the
-    /// given namespace. If successful, returns the binding corresponding to
-    /// the name.
-    fn resolve_name_in_module(&mut self,
-                              module: Module<'a>,
-                              name: Name,
-                              namespace: Namespace,
-                              use_lexical_scope: bool,
-                              record_used: bool)
-                              -> ResolveResult<&'a NameBinding<'a>> {
-        debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
-
-        self.populate_module_if_necessary(module);
-        module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
-            if record_used {
-                self.record_use(name, namespace, binding);
-            }
-            Success(binding)
-        })
-    }
-
     // AST resolution
     //
     // We maintain a list of value ribs and type ribs.
index 17933abec27b03ff81ba028dffa3b14c053e0a80..0905632d4e6273ace97233dd692ae824534f8793 100644 (file)
@@ -133,19 +133,77 @@ fn binding(&self) -> Option<&'a NameBinding<'a>> {
             _ => None, // The binding could be shadowed by a single import, so it is not known.
         })
     }
+}
+
+impl<'a> ::ModuleS<'a> {
+    fn resolution(&self, name: Name, ns: Namespace) -> &'a RefCell<NameResolution<'a>> {
+        *self.resolutions.borrow_mut().entry((name, ns))
+             .or_insert_with(|| self.arenas.alloc_name_resolution())
+    }
+}
+
+impl<'a> Resolver<'a> {
+    /// Attempts to resolve the supplied name in the given module for the given namespace.
+    /// If successful, returns the binding corresponding to the name.
+    pub fn resolve_name_in_module(&mut self,
+                                  module: Module<'a>,
+                                  name: Name,
+                                  ns: Namespace,
+                                  allow_private_imports: bool,
+                                  record_used: bool)
+                                  -> ResolveResult<&'a NameBinding<'a>> {
+        self.populate_module_if_necessary(module);
+
+        let resolution = module.resolution(name, ns);
+        let resolution = match resolution.borrow_state() {
+            ::std::cell::BorrowState::Unused => resolution.borrow_mut(),
+            _ => return Failed(None), // This happens when there is a cycle of imports
+        };
+
+        if let Some(result) = self.try_result(&resolution, ns, allow_private_imports) {
+            // If the resolution doesn't depend on glob definability, check privacy and return.
+            return result.and_then(|binding| {
+                if !allow_private_imports && binding.is_import() && !binding.is_pseudo_public() {
+                    return Failed(None);
+                }
+                if record_used {
+                    self.record_use(name, ns, binding);
+                }
+                Success(binding)
+            });
+        }
+
+        // Check if the globs are determined
+        for directive in module.globs.borrow().iter() {
+            if !allow_private_imports && directive.vis != ty::Visibility::Public { continue }
+            if let Some(target_module) = directive.target_module.get() {
+                let result = self.resolve_name_in_module(target_module, name, ns, false, false);
+                if let Indeterminate = result {
+                    return Indeterminate;
+                }
+            } else {
+                return Indeterminate;
+            }
+        }
+
+        Failed(None)
+    }
 
     // Returns Some(the resolution of the name), or None if the resolution depends
     // on whether more globs can define the name.
-    fn try_result(&self, ns: Namespace, allow_private_imports: bool)
+    fn try_result(&mut self,
+                  resolution: &NameResolution<'a>,
+                  ns: Namespace,
+                  allow_private_imports: bool)
                   -> Option<ResolveResult<&'a NameBinding<'a>>> {
-        match self.binding {
+        match resolution.binding {
             Some(binding) if !binding.is_glob_import() =>
-                return Some(Success(binding)),
-            _ => {} // Items and single imports are not shadowable
+                return Some(Success(binding)), // Items and single imports are not shadowable.
+            _ => {}
         };
 
         // Check if a single import can still define the name.
-        match self.single_imports {
+        match resolution.single_imports {
             SingleImports::None => {},
             SingleImports::AtLeastOne => return Some(Indeterminate),
             SingleImports::MaybeOne(directive) => {
@@ -153,7 +211,7 @@ fn try_result(&self, ns: Namespace, allow_private_imports: bool)
                 // the name, and (3) no public glob has defined the name, the resolution depends
                 // on whether more globs can define the name.
                 if !allow_private_imports && directive.vis != ty::Visibility::Public &&
-                   !self.binding.map(NameBinding::is_pseudo_public).unwrap_or(false) {
+                   !resolution.binding.map(NameBinding::is_pseudo_public).unwrap_or(false) {
                     return None;
                 }
 
@@ -165,57 +223,16 @@ fn try_result(&self, ns: Namespace, allow_private_imports: bool)
                     SingleImport { source, .. } => source,
                     GlobImport { .. } => unreachable!(),
                 };
-                match target_module.resolve_name(name, ns, false) {
+                match self.resolve_name_in_module(target_module, name, ns, false, false) {
                     Failed(_) => {}
                     _ => return Some(Indeterminate),
                 }
             }
         }
 
-        self.binding.map(Success)
-    }
-}
-
-impl<'a> ::ModuleS<'a> {
-    fn resolution(&self, name: Name, ns: Namespace) -> &'a RefCell<NameResolution<'a>> {
-        *self.resolutions.borrow_mut().entry((name, ns))
-             .or_insert_with(|| self.arenas.alloc_name_resolution())
-    }
-
-    pub fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: bool)
-                        -> ResolveResult<&'a NameBinding<'a>> {
-        let resolution = self.resolution(name, ns);
-        let resolution = match resolution.borrow_state() {
-            ::std::cell::BorrowState::Unused => resolution.borrow_mut(),
-            _ => return Failed(None), // This happens when there is a cycle of imports
-        };
-
-        if let Some(result) = resolution.try_result(ns, allow_private_imports) {
-            // If the resolution doesn't depend on glob definability, check privacy and return.
-            return result.and_then(|binding| {
-                let allowed = allow_private_imports || !binding.is_import() ||
-                                                       binding.is_pseudo_public();
-                if allowed { Success(binding) } else { Failed(None) }
-            });
-        }
-
-        // Check if the globs are determined
-        for directive in self.globs.borrow().iter() {
-            if !allow_private_imports && directive.vis != ty::Visibility::Public { continue }
-            match directive.target_module.get() {
-                None => return Indeterminate,
-                Some(target_module) => match target_module.resolve_name(name, ns, false) {
-                    Indeterminate => return Indeterminate,
-                    _ => {}
-                }
-            }
-        }
-
-        Failed(None)
+        resolution.binding.map(Success)
     }
-}
 
-impl<'a> Resolver<'a> {
     // Add an import directive to the current module.
     pub fn add_import_directive(&mut self,
                                 module_path: Vec<Name>,