diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index eaf5e4093c2..e673c3b9284 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -11,7 +11,7 @@ use crate::{ type_system::*, }; -use super::{module::ResolvedDeclaration, TraitMap}; +use super::{root::ResolvedDeclaration, TraitMap}; use sway_error::{ error::{CompileError, StructFieldUsageContext}, diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 16cad9931e8..0b84279159f 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -1,20 +1,15 @@ use crate::{ - decl_engine::DeclRef, engine_threading::Engines, - language::{ - parsed::*, - ty::{self, TyTraitItem}, - CallPath, Visibility, - }, + language::{parsed::*, ty, Visibility}, semantic_analysis::*, transform::to_parsed_lang, - Ident, Namespace, TypeId, TypeInfo, + Ident, Namespace, }; use super::{ lexical_scope::{Items, LexicalScope, SymbolMap}, root::Root, - LexicalScopeId, ModuleName, ModulePath, ModulePathBuf, ResolvedTraitImplItem, + LexicalScopeId, ModuleName, ModulePath, ModulePathBuf, }; use sway_ast::ItemConst; @@ -23,20 +18,6 @@ use sway_error::{error::CompileError, handler::ErrorEmitted}; use sway_parse::{lex, Parser}; use sway_types::{span::Span, Spanned}; -pub enum ResolvedDeclaration { - Parsed(Declaration), - Typed(ty::TyDecl), -} - -impl ResolvedDeclaration { - pub fn expect_typed(self) -> ty::TyDecl { - match self { - ResolvedDeclaration::Parsed(_) => panic!(), - ResolvedDeclaration::Typed(ty_decl) => ty_decl, - } - } -} - /// A single `Module` within a Sway project. /// /// A `Module` is most commonly associated with an individual file of Sway code, e.g. a top-level @@ -336,346 +317,6 @@ impl Module { let parent_scope_id = self.current_lexical_scope().parent; self.current_lexical_scope_id = parent_scope_id.unwrap_or(0); } - - /// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`. - /// - /// This is short-hand for concatenating the `mod_path` with the `call_path`'s prefixes and - /// then calling `resolve_symbol` with the resulting path and call_path's suffix. - pub(crate) fn resolve_call_path( - &self, - handler: &Handler, - engines: &Engines, - mod_path: &ModulePath, - call_path: &CallPath, - self_type: Option, - ) -> Result { - let (decl, _) = - self.resolve_call_path_and_mod_path(handler, engines, mod_path, call_path, self_type)?; - Ok(decl) - } - - pub(crate) fn resolve_call_path_and_mod_path( - &self, - handler: &Handler, - engines: &Engines, - mod_path: &ModulePath, - call_path: &CallPath, - self_type: Option, - ) -> Result<(ResolvedDeclaration, Vec), ErrorEmitted> { - let symbol_path: Vec<_> = mod_path - .iter() - .chain(&call_path.prefixes) - .cloned() - .collect(); - self.resolve_symbol_and_mod_path( - handler, - engines, - &symbol_path, - &call_path.suffix, - self_type, - ) - } - - pub(crate) fn resolve_call_path_and_root_type_id( - &self, - handler: &Handler, - engines: &Engines, - root_type_id: TypeId, - mut as_trait: Option, - call_path: &CallPath, - self_type: Option, - ) -> Result { - // This block tries to resolve associated types - let mut decl_opt = None; - let mut type_id_opt = Some(root_type_id); - for ident in call_path.prefixes.iter() { - if let Some(type_id) = type_id_opt { - type_id_opt = None; - decl_opt = Some(self.resolve_associated_type_from_type_id( - handler, - engines, - ident, - type_id, - as_trait.clone(), - self_type, - )?); - as_trait = None; - } else if let Some(decl) = decl_opt { - decl_opt = Some(self.resolve_associated_type( - handler, - engines, - ident, - decl, - as_trait.clone(), - self_type, - )?); - as_trait = None; - } - } - if let Some(type_id) = type_id_opt { - let decl = self.resolve_associated_type_from_type_id( - handler, - engines, - &call_path.suffix, - type_id, - as_trait, - self_type, - )?; - return Ok(decl); - } - if let Some(decl) = decl_opt { - let decl = self.resolve_associated_item( - handler, - engines, - &call_path.suffix, - decl, - as_trait, - self_type, - )?; - Ok(decl) - } else { - Err(handler.emit_err(CompileError::Internal("Unexpected error", call_path.span()))) - } - } - - /// 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 { - let (decl, _) = - self.resolve_symbol_and_mod_path(handler, engines, mod_path, symbol, self_type)?; - Ok(decl) - } - - fn resolve_symbol_and_mod_path( - &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( - self.resolve_associated_type(handler, engines, 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(self.resolve_symbol_helper( - handler, - engines, - ¤t_mod_path, - ident, - module, - self_type, - )?); - } - } - } - } - if let Some(decl) = decl_opt { - let decl = - self.resolve_associated_item(handler, engines, symbol, decl, None, self_type)?; - return Ok((decl, current_mod_path)); - } - - self.lookup_submodule(handler, engines, mod_path) - .and_then(|module| { - let decl = self - .resolve_symbol_helper(handler, engines, mod_path, symbol, module, self_type)?; - Ok((decl, mod_path.to_vec())) - }) - } - - fn resolve_associated_type( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - decl: ResolvedDeclaration, - as_trait: Option, - self_type: Option, - ) -> Result { - let type_info = self.decl_to_type_info(handler, engines, symbol, decl)?; - - self.resolve_associated_type_from_type_id( - handler, - engines, - symbol, - engines - .te() - .insert(engines, type_info, symbol.span().source_id()), - as_trait, - self_type, - ) - } - - fn resolve_associated_item( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - decl: ResolvedDeclaration, - as_trait: Option, - self_type: Option, - ) -> Result { - let type_info = self.decl_to_type_info(handler, engines, symbol, decl)?; - - self.resolve_associated_item_from_type_id( - handler, - engines, - symbol, - engines - .te() - .insert(engines, type_info, symbol.span().source_id()), - as_trait, - self_type, - ) - } - - fn decl_to_type_info( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - decl: ResolvedDeclaration, - ) -> Result { - match decl { - ResolvedDeclaration::Parsed(_decl) => todo!(), - ResolvedDeclaration::Typed(decl) => Ok(match decl.clone() { - ty::TyDecl::StructDecl(struct_decl) => TypeInfo::Struct(DeclRef::new( - struct_decl.name.clone(), - struct_decl.decl_id, - struct_decl.name.span(), - )), - ty::TyDecl::EnumDecl(enum_decl) => TypeInfo::Enum(DeclRef::new( - enum_decl.name.clone(), - enum_decl.decl_id, - enum_decl.name.span(), - )), - ty::TyDecl::TraitTypeDecl(type_decl) => { - let type_decl = engines.de().get_type(&type_decl.decl_id); - (*engines.te().get(type_decl.ty.clone().unwrap().type_id)).clone() - } - _ => { - return Err(handler.emit_err(CompileError::SymbolNotFound { - name: symbol.clone(), - span: symbol.span(), - })) - } - }), - } - } - - fn resolve_associated_type_from_type_id( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - type_id: TypeId, - as_trait: Option, - self_type: Option, - ) -> Result { - let item_decl = self.resolve_associated_item_from_type_id( - handler, engines, symbol, type_id, as_trait, self_type, - )?; - Ok(item_decl) - } - - fn resolve_associated_item_from_type_id( - &self, - handler: &Handler, - engines: &Engines, - symbol: &Ident, - type_id: TypeId, - as_trait: Option, - self_type: Option, - ) -> Result { - let type_id = if engines.te().get(type_id).is_self_type() { - if let Some(self_type) = self_type { - self_type - } else { - return Err(handler.emit_err(CompileError::Internal( - "Self type not provided.", - symbol.span(), - ))); - } - } else { - type_id - }; - let item_ref = self - .current_items() - .implemented_traits - .get_trait_item_for_type(handler, engines, symbol, type_id, as_trait)?; - match item_ref { - ResolvedTraitImplItem::Parsed(_item) => todo!(), - ResolvedTraitImplItem::Typed(item) => match item { - TyTraitItem::Fn(fn_ref) => Ok(ResolvedDeclaration::Typed(fn_ref.into())), - TyTraitItem::Constant(const_ref) => { - Ok(ResolvedDeclaration::Typed(const_ref.into())) - } - TyTraitItem::Type(type_ref) => Ok(ResolvedDeclaration::Typed(type_ref.into())), - }, - } - } - - fn resolve_symbol_helper( - &self, - handler: &Handler, - engines: &Engines, - mod_path: &ModulePath, - symbol: &Ident, - module: &Module, - self_type: Option, - ) -> Result { - let true_symbol = self - .lookup_submodule(handler, engines, mod_path)? - .current_items() - .use_aliases - .get(symbol.as_str()) - .unwrap_or(symbol); - // Check locally declared items. Any name clash with imports will have already been reported as an error. - if let Some(decl) = module.current_items().symbols.get(true_symbol) { - return Ok(ResolvedDeclaration::Typed(decl.clone())); - } - // Check item imports - if let Some((_, decl @ ty::TyDecl::EnumVariantDecl { .. })) = - module.current_items().use_item_synonyms.get(symbol) - { - return Ok(ResolvedDeclaration::Typed(decl.clone())); - } - if let Some((src_path, _)) = module.current_items().use_item_synonyms.get(symbol) { - return self.resolve_symbol(handler, engines, src_path, true_symbol, self_type); - } - // Check glob imports - if let Some((_, decl)) = module.current_items().use_glob_synonyms.get(symbol) { - return Ok(ResolvedDeclaration::Typed(decl.clone())); - } - // Symbol not found - Err(handler.emit_err(CompileError::SymbolNotFound { - name: symbol.clone(), - span: symbol.span(), - })) - } } 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 beab3f65a71..37896c8b3b2 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -4,8 +4,8 @@ use crate::{ }; use super::{ - module::{Module, ResolvedDeclaration}, - root::Root, + module::Module, + root::{ResolvedDeclaration, Root}, submodule_namespace::SubmoduleNamespace, trait_map::ResolvedTraitImplItem, ModulePath, ModulePathBuf, @@ -203,7 +203,6 @@ impl Namespace { self_type: Option, ) -> Result { self.root - .module .resolve_symbol(handler, engines, mod_path, symbol, self_type) } @@ -216,7 +215,6 @@ impl Namespace { self_type: Option, ) -> Result { self.root - .module .resolve_symbol(handler, engines, &self.mod_path, symbol, self_type) } @@ -253,7 +251,6 @@ impl Namespace { self_type: Option, ) -> Result { self.root - .module .resolve_call_path(handler, engines, &self.mod_path, call_path, self_type) } diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index b02835db5d8..7f5744a44df 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -1,9 +1,16 @@ -use super::{module::Module, namespace::Namespace, trait_map::TraitMap, Ident}; +use super::{ + module::Module, namespace::Namespace, trait_map::TraitMap, Ident, ResolvedTraitImplItem, +}; use crate::{ decl_engine::DeclRef, engine_threading::*, - language::ty::{self, TyDecl}, + language::{ + parsed::*, + ty::{self, TyDecl, TyTraitItem}, + CallPath, + }, namespace::ModulePath, + TypeId, TypeInfo, }; use sway_error::{ error::CompileError, @@ -12,6 +19,20 @@ use sway_error::{ use sway_types::Spanned; use sway_utils::iter_prefixes; +pub enum ResolvedDeclaration { + Parsed(Declaration), + Typed(ty::TyDecl), +} + +impl ResolvedDeclaration { + pub fn expect_typed(self) -> ty::TyDecl { + match self { + ResolvedDeclaration::Parsed(_) => panic!(), + ResolvedDeclaration::Typed(ty_decl) => ty_decl, + } + } +} + /// The root module, from which all other modules can be accessed. /// /// This is equivalent to the "crate root" of a Rust crate. @@ -26,6 +47,8 @@ pub struct Root { } impl Root { + ////// IMPORT ////// + /// Given a path to a `src` module, create synonyms to every symbol in that module to the given /// `dst` module. /// @@ -460,6 +483,358 @@ impl Root { } Ok(()) } + + ////// NAME RESOLUTION ////// + + /// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`. + /// + /// This is short-hand for concatenating the `mod_path` with the `call_path`'s prefixes and + /// then calling `resolve_symbol` with the resulting path and call_path's suffix. + pub(crate) fn resolve_call_path( + &self, + handler: &Handler, + engines: &Engines, + mod_path: &ModulePath, + call_path: &CallPath, + self_type: Option, + ) -> Result { + let (decl, _) = + self.resolve_call_path_and_mod_path(handler, engines, mod_path, call_path, self_type)?; + Ok(decl) + } + + pub(crate) fn resolve_call_path_and_mod_path( + &self, + handler: &Handler, + engines: &Engines, + mod_path: &ModulePath, + call_path: &CallPath, + self_type: Option, + ) -> Result<(ResolvedDeclaration, Vec), ErrorEmitted> { + let symbol_path: Vec<_> = mod_path + .iter() + .chain(&call_path.prefixes) + .cloned() + .collect(); + self.resolve_symbol_and_mod_path( + handler, + engines, + &symbol_path, + &call_path.suffix, + self_type, + ) + } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn resolve_call_path_and_root_type_id( + &self, + handler: &Handler, + engines: &Engines, + module: &Module, + root_type_id: TypeId, + mut as_trait: Option, + call_path: &CallPath, + self_type: Option, + ) -> Result { + // This block tries to resolve associated types + let mut decl_opt = None; + let mut type_id_opt = Some(root_type_id); + for ident in call_path.prefixes.iter() { + if let Some(type_id) = type_id_opt { + type_id_opt = None; + decl_opt = Some(self.resolve_associated_type_from_type_id( + handler, + engines, + module, + ident, + type_id, + as_trait.clone(), + self_type, + )?); + as_trait = None; + } else if let Some(decl) = decl_opt { + decl_opt = Some(self.resolve_associated_type( + handler, + engines, + module, + ident, + decl, + as_trait.clone(), + self_type, + )?); + as_trait = None; + } + } + if let Some(type_id) = type_id_opt { + let decl = self.resolve_associated_type_from_type_id( + handler, + engines, + module, + &call_path.suffix, + type_id, + as_trait, + self_type, + )?; + return Ok(decl); + } + if let Some(decl) = decl_opt { + let decl = self.resolve_associated_item( + handler, + engines, + module, + &call_path.suffix, + decl, + as_trait, + self_type, + )?; + Ok(decl) + } else { + Err(handler.emit_err(CompileError::Internal("Unexpected error", call_path.span()))) + } + } + + /// 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 { + let (decl, _) = + self.resolve_symbol_and_mod_path(handler, engines, mod_path, symbol, self_type)?; + Ok(decl) + } + + fn resolve_symbol_and_mod_path( + &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(self.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( + self.resolve_symbol_helper(handler, engines, ident, module, self_type)?, + ); + } + } + } + } + if let Some(decl) = decl_opt { + let decl = self + .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 = + self.resolve_symbol_helper(handler, engines, symbol, module, self_type)?; + Ok((decl, mod_path.to_vec())) + }) + } + + #[allow(clippy::too_many_arguments)] + fn resolve_associated_type( + &self, + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + decl: ResolvedDeclaration, + as_trait: Option, + self_type: Option, + ) -> Result { + let type_info = self.decl_to_type_info(handler, engines, symbol, decl)?; + + self.resolve_associated_type_from_type_id( + handler, + engines, + module, + symbol, + engines + .te() + .insert(engines, type_info, symbol.span().source_id()), + as_trait, + self_type, + ) + } + + #[allow(clippy::too_many_arguments)] + fn resolve_associated_item( + &self, + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + decl: ResolvedDeclaration, + as_trait: Option, + self_type: Option, + ) -> Result { + let type_info = self.decl_to_type_info(handler, engines, symbol, decl)?; + + self.resolve_associated_item_from_type_id( + handler, + engines, + module, + symbol, + engines + .te() + .insert(engines, type_info, symbol.span().source_id()), + as_trait, + self_type, + ) + } + + fn decl_to_type_info( + &self, + handler: &Handler, + engines: &Engines, + symbol: &Ident, + decl: ResolvedDeclaration, + ) -> Result { + match decl { + ResolvedDeclaration::Parsed(_decl) => todo!(), + ResolvedDeclaration::Typed(decl) => Ok(match decl.clone() { + ty::TyDecl::StructDecl(struct_decl) => TypeInfo::Struct(DeclRef::new( + struct_decl.name.clone(), + struct_decl.decl_id, + struct_decl.name.span(), + )), + ty::TyDecl::EnumDecl(enum_decl) => TypeInfo::Enum(DeclRef::new( + enum_decl.name.clone(), + enum_decl.decl_id, + enum_decl.name.span(), + )), + ty::TyDecl::TraitTypeDecl(type_decl) => { + let type_decl = engines.de().get_type(&type_decl.decl_id); + (*engines.te().get(type_decl.ty.clone().unwrap().type_id)).clone() + } + _ => { + return Err(handler.emit_err(CompileError::SymbolNotFound { + name: symbol.clone(), + span: symbol.span(), + })) + } + }), + } + } + + #[allow(clippy::too_many_arguments)] + fn resolve_associated_type_from_type_id( + &self, + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + type_id: TypeId, + as_trait: Option, + self_type: Option, + ) -> Result { + let item_decl = self.resolve_associated_item_from_type_id( + handler, engines, module, symbol, type_id, as_trait, self_type, + )?; + Ok(item_decl) + } + + #[allow(clippy::too_many_arguments)] + fn resolve_associated_item_from_type_id( + &self, + handler: &Handler, + engines: &Engines, + module: &Module, + symbol: &Ident, + type_id: TypeId, + as_trait: Option, + self_type: Option, + ) -> Result { + let type_id = if engines.te().get(type_id).is_self_type() { + if let Some(self_type) = self_type { + self_type + } else { + return Err(handler.emit_err(CompileError::Internal( + "Self type not provided.", + symbol.span(), + ))); + } + } else { + type_id + }; + let item_ref = module + .current_items() + .implemented_traits + .get_trait_item_for_type(handler, engines, symbol, type_id, as_trait)?; + match item_ref { + ResolvedTraitImplItem::Parsed(_item) => todo!(), + ResolvedTraitImplItem::Typed(item) => match item { + TyTraitItem::Fn(fn_ref) => Ok(ResolvedDeclaration::Typed(fn_ref.into())), + TyTraitItem::Constant(const_ref) => { + Ok(ResolvedDeclaration::Typed(const_ref.into())) + } + TyTraitItem::Type(type_ref) => Ok(ResolvedDeclaration::Typed(type_ref.into())), + }, + } + } + + fn resolve_symbol_helper( + &self, + handler: &Handler, + engines: &Engines, + symbol: &Ident, + module: &Module, + self_type: Option, + ) -> Result { + let true_symbol = module + .current_items() + .use_aliases + .get(symbol.as_str()) + .unwrap_or(symbol); + // Check locally declared items. Any name clash with imports will have already been reported as an error. + if let Some(decl) = module.current_items().symbols.get(true_symbol) { + return Ok(ResolvedDeclaration::Typed(decl.clone())); + } + // Check item imports + if let Some((_, decl @ ty::TyDecl::EnumVariantDecl { .. })) = + module.current_items().use_item_synonyms.get(symbol) + { + return Ok(ResolvedDeclaration::Typed(decl.clone())); + } + if let Some((src_path, _)) = module.current_items().use_item_synonyms.get(symbol) { + return self.resolve_symbol(handler, engines, src_path, true_symbol, self_type); + } + // Check glob imports + if let Some((_, decl)) = module.current_items().use_glob_synonyms.get(symbol) { + return Ok(ResolvedDeclaration::Typed(decl.clone())); + } + // Symbol not found + Err(handler.emit_err(CompileError::SymbolNotFound { + name: symbol.clone(), + span: symbol.span(), + })) + } } impl From for Root { diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 6214302541e..b7d71376e01 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -572,10 +572,11 @@ impl<'a> TypeCheckContext<'a> { } => { let type_decl_opt = if let Some(root_type_id) = root_type_id { self.namespace() - .module(engines) + .root .resolve_call_path_and_root_type_id( handler, self.engines, + self.namespace().module(engines), root_type_id, None, &qualified_call_path.clone().to_call_path(handler)?, @@ -779,17 +780,13 @@ impl<'a> TypeCheckContext<'a> { call_path: &CallPath, ) -> Result { let engines = self.engines; - let (decl, mod_path) = self - .namespace() - .root - .module - .resolve_call_path_and_mod_path( - handler, - self.engines, - mod_path, - call_path, - self.self_type, - )?; + let (decl, mod_path) = self.namespace().root.resolve_call_path_and_mod_path( + handler, + self.engines, + mod_path, + call_path, + self.self_type, + )?; let decl = decl.expect_typed(); // In case there is no mod path we don't need to check visibility @@ -887,10 +884,10 @@ impl<'a> TypeCheckContext<'a> { self.namespace() .root - .module .resolve_call_path_and_root_type_id( handler, self.engines, + &self.namespace().root.module, root_type_id, as_trait_opt, &qualified_call_path.call_path,