diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index e442fc1fbdf..d4f5f1befed 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1243,7 +1243,7 @@ impl ty::TyExpression { let storage_key_ident = Ident::new_with_override("StorageKey".into(), span.clone()); // Search for the struct declaration with the call path above. - let (storage_key_decl, _) = ctx.namespace().root().resolve_symbol( + let (storage_key_decl, _) = ctx.namespace().root().module.resolve_symbol( handler, engines, &storage_key_mod_path, diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 2a96e6efe70..9b7534385ce 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -1,9 +1,14 @@ -use crate::{engine_threading::Engines, language::Visibility, Ident}; +use crate::{ + engine_threading::Engines, + language::Visibility, + semantic_analysis::type_resolve::{resolve_associated_item, resolve_associated_type}, + Ident, TypeId, +}; use super::{ lexical_scope::{Items, LexicalScope}, root::Root, - LexicalScopeId, ModuleName, ModulePath, ModulePathBuf, + LexicalScopeId, ModuleName, ModulePath, ModulePathBuf, ResolvedDeclaration, }; use rustc_hash::FxHasher; @@ -285,6 +290,61 @@ impl Module { let parent_scope_id = self.current_lexical_scope().parent; self.current_lexical_scope_id = parent_scope_id.unwrap_or(0); } + + /// Given a path to a module and the identifier of a symbol within that module, resolve its + /// declaration. + /// + /// If the symbol is within the given module's namespace via import, we recursively traverse + /// imports until we find the original declaration. + pub(crate) fn resolve_symbol( + &self, + handler: &Handler, + engines: &Engines, + mod_path: &ModulePath, + symbol: &Ident, + self_type: Option, + ) -> Result<(ResolvedDeclaration, Vec), ErrorEmitted> { + // This block tries to resolve associated types + let mut module = self; + let mut current_mod_path = vec![]; + let mut decl_opt = None; + for ident in mod_path.iter() { + if let Some(decl) = decl_opt { + decl_opt = Some(resolve_associated_type( + handler, engines, module, ident, decl, None, self_type, + )?); + } else { + match module.submodules.get(ident.as_str()) { + Some(ns) => { + module = ns; + current_mod_path.push(ident.clone()); + } + None => { + decl_opt = Some( + module + .current_lexical_scope() + .items + .resolve_symbol(handler, engines, ident)?, + ); + } + } + } + } + if let Some(decl) = decl_opt { + let decl = + resolve_associated_item(handler, engines, module, symbol, decl, None, self_type)?; + return Ok((decl, current_mod_path)); + } + + self.lookup_submodule(handler, engines, mod_path) + .and_then(|module| { + let decl = module + .current_lexical_scope() + .items + .resolve_symbol(handler, engines, symbol)?; + Ok((decl, mod_path.to_vec())) + }) + } } impl From for Module { diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index 613900ec250..f28037b497b 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -142,6 +142,7 @@ impl Namespace { self_type: Option, ) -> Result { self.root + .module .resolve_symbol(handler, engines, &self.mod_path, symbol, self_type) .map(|r| r.0) } diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 45463b2796d..96fd88a07d3 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -14,7 +14,6 @@ use crate::{ CallPath, Visibility, }, namespace::{ModulePath, ModulePathBuf}, - semantic_analysis::type_resolve::{resolve_associated_item, resolve_associated_type}, TypeId, }; use sway_error::{ @@ -730,63 +729,8 @@ impl Root { .chain(&call_path.prefixes) .cloned() .collect(); - self.resolve_symbol(handler, engines, &symbol_path, &call_path.suffix, self_type) - } - - /// Given a path to a module and the identifier of a symbol within that module, resolve its - /// declaration. - /// - /// If the symbol is within the given module's namespace via import, we recursively traverse - /// imports until we find the original declaration. - pub(crate) fn resolve_symbol( - &self, - handler: &Handler, - engines: &Engines, - mod_path: &ModulePath, - symbol: &Ident, - self_type: Option, - ) -> Result<(ResolvedDeclaration, Vec), ErrorEmitted> { - // This block tries to resolve associated types - let mut module = &self.module; - let mut current_mod_path = vec![]; - let mut decl_opt = None; - for ident in mod_path.iter() { - if let Some(decl) = decl_opt { - decl_opt = Some(resolve_associated_type( - handler, engines, module, ident, decl, None, self_type, - )?); - } else { - match module.submodules.get(ident.as_str()) { - Some(ns) => { - module = ns; - current_mod_path.push(ident.clone()); - } - None => { - decl_opt = Some( - module - .current_lexical_scope() - .items - .resolve_symbol(handler, engines, ident)?, - ); - } - } - } - } - if let Some(decl) = decl_opt { - let decl = - resolve_associated_item(handler, engines, module, symbol, decl, None, self_type)?; - return Ok((decl, current_mod_path)); - } - self.module - .lookup_submodule(handler, engines, mod_path) - .and_then(|module| { - let decl = module - .current_lexical_scope() - .items - .resolve_symbol(handler, engines, symbol)?; - Ok((decl, mod_path.to_vec())) - }) + .resolve_symbol(handler, engines, &symbol_path, &call_path.suffix, self_type) } }