diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index c887cc68720..7092d3e63ef 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1759,7 +1759,7 @@ pub fn compile( pkg: &PackageDescriptor, profile: &BuildProfile, engines: &Engines, - namespace: namespace::Root, + namespace: &mut namespace::Root, source_map: &mut SourceMap, ) -> Result { let mut metrics = PerformanceData::default(); @@ -2373,7 +2373,7 @@ pub fn build( // `ContractIdConst` is a None here since we do not yet have a // contract ID value at this point. - let dep_namespace = match dependency_namespace( + let mut dep_namespace = match dependency_namespace( &lib_namespace_map, &compiled_contract_deps, plan.graph(), @@ -2390,7 +2390,7 @@ pub fn build( &descriptor, &profile, &engines, - dep_namespace, + &mut dep_namespace, &mut source_map, )?; @@ -2437,7 +2437,7 @@ pub fn build( }; // Note that the contract ID value here is only Some if tests are enabled. - let dep_namespace = match dependency_namespace( + let mut dep_namespace = match dependency_namespace( &lib_namespace_map, &compiled_contract_deps, plan.graph(), @@ -2463,7 +2463,7 @@ pub fn build( &descriptor, &profile, &engines, - dep_namespace, + &mut dep_namespace, &mut source_map, )?; @@ -2672,7 +2672,7 @@ pub fn check( let contract_id_value = (idx == plan.compilation_order.len() - 1).then(|| DUMMY_CONTRACT_ID.to_string()); - let dep_namespace = dependency_namespace( + let mut dep_namespace = dependency_namespace( &lib_namespace_map, &compiled_contract_deps, &plan.graph, @@ -2703,7 +2703,7 @@ pub fn check( &handler, engines, input, - dep_namespace, + &mut dep_namespace, Some(&build_config), &pkg.name, retrigger_compilation.clone(), diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index 5509a812f24..f16e36e5b97 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -1316,7 +1316,7 @@ mod tests { }, ); let mut md_mgr = MetadataManager::default(); - let core_lib = namespace::Root::from(namespace::Module { + let mut core_lib = namespace::Root::from(namespace::Module { name: Some(sway_types::Ident::new_no_span( "assert_is_constant_test".to_string(), )), @@ -1327,7 +1327,7 @@ mod tests { &handler, &engines, std::sync::Arc::from(format!("library; {prefix} fn f() -> u64 {{ {expr}; 0 }}")), - core_lib, + &mut core_lib, None, "test", None, diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index 153358ca0cf..bdc7e683ceb 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -520,7 +520,7 @@ pub fn parsed_to_ast( handler: &Handler, engines: &Engines, parse_program: &mut parsed::ParseProgram, - initial_namespace: namespace::Root, + initial_namespace: &mut namespace::Root, build_config: Option<&BuildConfig>, package_name: &str, retrigger_compilation: Option>, @@ -691,7 +691,7 @@ pub fn compile_to_ast( handler: &Handler, engines: &Engines, input: Arc, - initial_namespace: namespace::Root, + initial_namespace: &mut namespace::Root, build_config: Option<&BuildConfig>, package_name: &str, retrigger_compilation: Option>, @@ -783,7 +783,7 @@ pub fn compile_to_asm( handler: &Handler, engines: &Engines, input: Arc, - initial_namespace: namespace::Root, + initial_namespace: &mut namespace::Root, build_config: &BuildConfig, package_name: &str, ) -> Result { @@ -944,7 +944,7 @@ pub fn compile_to_bytecode( handler: &Handler, engines: &Engines, input: Arc, - initial_namespace: namespace::Root, + initial_namespace: &mut namespace::Root, build_config: &BuildConfig, source_map: &mut SourceMap, package_name: &str, 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 9ce246074f3..742b24f4fef 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 @@ -2663,8 +2663,8 @@ mod tests { type_annotation: TypeId, experimental: ExperimentalFlags, ) -> Result { - let root_module = namespace::Root::from(namespace::Module::default()); - let mut namespace = Namespace::init_root(root_module); + let mut root_module = namespace::Root::from(namespace::Module::default()); + let mut namespace = Namespace::init_root(&mut root_module); let ctx = TypeCheckContext::from_namespace(&mut namespace, engines, experimental) .with_type_annotation(type_annotation); ty::TyExpression::type_check(handler, ctx, expr) diff --git a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs index 0b1a5851e0c..eaa91f37820 100644 --- a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs +++ b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs @@ -95,8 +95,8 @@ fn default_with_contract_id_inner( content: AstNodeContent::Declaration(Declaration::ConstantDeclaration(const_decl_id)), span: const_item_span.clone(), }; - let root = Root::from(Module::default()); - let mut ns = Namespace::init_root(root); + let mut root = Root::from(Module::default()); + let mut ns = Namespace::init_root(&mut root); // This is pretty hacky but that's okay because of this code is being removed pretty soon ns.root.module.name = ns_name; ns.root.module.visibility = Visibility::Public; diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 327abb91410..b61daaa2c01 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -92,6 +92,13 @@ impl Module { &self.submodules } + /// Mutable access to this module's submodules. + pub fn submodules_mut( + &mut self, + ) -> &mut im::HashMap> { + &mut self.submodules + } + /// Insert a submodule into this `Module`. pub fn insert_submodule(&mut self, name: String, submodule: Module) { self.submodules.insert(name, submodule); diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index cfe52d93d28..9b2470bb3d3 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -8,11 +8,9 @@ use super::{ root::{ResolvedDeclaration, Root}, submodule_namespace::SubmoduleNamespace, trait_map::ResolvedTraitImplItem, - ModuleName, ModulePath, ModulePathBuf, + ModulePath, ModulePathBuf, }; -use rustc_hash::FxHasher; -use std::hash::BuildHasherDefault; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::span::Span; @@ -58,7 +56,7 @@ impl Namespace { /// Initialise the namespace at its root from the given initial namespace. /// If the root module contains submodules these are now considered external. - pub fn init_root(root: Root) -> Self { + pub fn init_root(root: &mut Root) -> Self { assert!( !root.module.is_external, "The root module must not be external during compilation" @@ -69,32 +67,22 @@ impl Namespace { // // Every submodule that has been added before calling init_root is now considered // external, which we have to enforce at this point. - fn clone_with_submodules_external(module: &Module) -> Module { - let mut new_submods = - im::HashMap::>::default(); - for (name, submod) in module.submodules.iter() { - let new_submod = clone_with_submodules_external(submod); - new_submods.insert(name.clone(), new_submod); - } - Module { - submodules: new_submods, - lexical_scopes: module.lexical_scopes.clone(), - current_lexical_scope_id: module.current_lexical_scope_id, - name: module.name.clone(), - visibility: module.visibility, - span: module.span.clone(), - is_external: true, - mod_path: module.mod_path.clone(), + fn set_submodules_external(module: &mut Module) { + for (_, submod) in module.submodules_mut().iter_mut() { + if !submod.is_external { + submod.is_external = true; + set_submodules_external(submod); + } } } - let mut init = clone_with_submodules_external(&root.module); + set_submodules_external(&mut root.module); // The init module itself is not external - init.is_external = false; + root.module.is_external = false; Self { - init: init.clone(), - root: Root { module: init }, + init: root.module.clone(), + root: root.clone(), mod_path, } } diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index 2c21d60c91e..e79226326d5 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -238,12 +238,12 @@ pub(super) async fn run( let sway_str = String::from_utf8_lossy(&sway_str); let handler = Handler::default(); - let initial_namespace = namespace::Root::from(core_lib.clone()); + let mut initial_namespace = namespace::Root::from(core_lib.clone()); let compile_res = compile_to_ast( &handler, &engines, Arc::from(sway_str), - initial_namespace, + &mut initial_namespace, Some(&bld_cfg), PACKAGE_NAME, None,