From bf056b8b1ef6931ec355cb19985133109a1ec55a Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Mon, 26 Feb 2024 16:36:34 +0100 Subject: [PATCH 01/11] Test case added --- .../imports_implicitly_public/Forc.lock | 25 +++++++++++++++++++ .../imports_implicitly_public/Forc.toml | 2 ++ .../external_mod/Forc.toml | 9 +++++++ .../external_mod/src/external_submod.sw | 5 ++++ .../external_mod/src/main.sw | 7 ++++++ .../json_abi_oracle.json | 1 + .../script/Forc.toml | 10 ++++++++ .../script/src/internal_mod.sw | 7 ++++++ .../src/internal_mod/internal_submod.sw | 7 ++++++ .../script/src/main.sw | 22 ++++++++++++++++ .../imports_implicitly_public/test.toml | 3 +++ 11 files changed, 98 insertions(+) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock new file mode 100644 index 00000000000..122dda190ba --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock @@ -0,0 +1,25 @@ +[[package]] +name = "core" +source = "path+from-root-4569ADD4F9A2E45D" + +[[package]] +name = "external_mod" +source = "member" +dependencies = [ + "core", + "std", +] + +[[package]] +name = "script" +source = "member" +dependencies = [ + "core", + "external_mod", + "std", +] + +[[package]] +name = "std" +source = "path+from-root-4569ADD4F9A2E45D" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml new file mode 100644 index 00000000000..5cc6cbd57a0 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["script", "external_mod"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml new file mode 100644 index 00000000000..ed75dd55645 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "external_mod" + +[dependencies] +core = { path = "../../../../../../../sway-lib-core" } +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw new file mode 100644 index 00000000000..1a442f4bd31 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw @@ -0,0 +1,5 @@ +library; + +pub fn external_submod_foo() -> u32 { + 2 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw new file mode 100644 index 00000000000..43e5719e375 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw @@ -0,0 +1,7 @@ +library; + +pub mod external_submod; + +pub fn external_mod_foo() -> u32 { + 1 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json @@ -0,0 +1 @@ +[] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml new file mode 100644 index 00000000000..bbd562aaba6 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml @@ -0,0 +1,10 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "script" + +[dependencies] +core = { path = "../../../../../../../sway-lib-core" } +std = { path = "../../../../../../../sway-lib-std" } +external_mod = { path = "../external_mod/" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw new file mode 100644 index 00000000000..539970f57cb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw @@ -0,0 +1,7 @@ +library; + +pub mod internal_submod; + +pub fn internal_mod_foo() -> u32 { + 42 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw new file mode 100644 index 00000000000..d7572139f68 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw @@ -0,0 +1,7 @@ +library; + +use external_mod::{*, external_submod::*}; + +pub fn internal_submod_foo() -> u32 { + 3 +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw new file mode 100644 index 00000000000..2238ac2b64f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw @@ -0,0 +1,22 @@ +script; + +mod internal_mod; + +use internal_mod::{*, internal_submod::*}; +use external_mod::{*, external_submod::*}; + +// It should not be possible to import core contents via the standard library. +// It should not be possible to import standard library contents via submodules or external dependencies. + +use std::core::ops::Eq; +use std::hash::core::ops::Add; +use internal_mod::internal_submod::std::hash::core::ops::Subtract; +use external_mod::external_submod::std::core::ops::Multiply; +use internal_mod::internal_submod::external_mod::external_submod::std::core::ops::Divide; + +fn main() { + assert(internal_mod_foo() + + internal_submod_foo() + + external_mod_foo() + + external_submod_foo() == 48); +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml new file mode 100644 index 00000000000..e1a83974450 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml @@ -0,0 +1,3 @@ +category = "fail" + +# not: $()error From 3d290314529637cc98671581a7f882ada42e3429 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Sat, 2 Mar 2024 17:32:36 +0100 Subject: [PATCH 02/11] Move typecheck import logic to Root, use only absolute paths --- .../ast_node/declaration/auto_impl.rs | 2 - .../src/semantic_analysis/ast_node/mod.rs | 7 +- .../src/semantic_analysis/namespace/module.rs | 348 +--------------- .../src/semantic_analysis/namespace/root.rs | 387 +++++++++++++++++- .../semantic_analysis/type_check_context.rs | 20 +- 5 files changed, 394 insertions(+), 370 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs index f60e85e9931..48e654d473a 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs @@ -71,7 +71,6 @@ impl<'a, 'b> AutoImplAbiEncodeContext<'a, 'b> { Ident::new_no_span("core".into()), Ident::new_no_span("codec".into()), ], - true, ); !handler.has_errors() @@ -585,7 +584,6 @@ impl<'a, 'b> AutoImplAbiEncodeContext<'a, 'b> { Ident::new_no_span("core".into()), Ident::new_no_span("codec".into()), ], - true, ); if import_handler.has_errors() { diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index 73e3650962e..e0ac6bd12b9 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -50,7 +50,7 @@ impl ty::TyAstNode { // try a standard starimport first let star_import_handler = Handler::default(); let import = - ctx.star_import(&star_import_handler, &path, a.is_absolute); + ctx.star_import(&star_import_handler, &path); if import.is_ok() { handler.append(star_import_handler); import @@ -62,7 +62,6 @@ impl ty::TyAstNode { &variant_import_handler, path, enum_name, - a.is_absolute, ); if variant_import.is_ok() { handler.append(variant_import_handler); @@ -78,7 +77,7 @@ impl ty::TyAstNode { } } ImportType::SelfImport(_) => { - ctx.self_import(handler, &path, a.alias.clone(), a.is_absolute) + ctx.self_import(handler, &path, a.alias.clone()) } ImportType::Item(ref s) => { // try a standard item import first @@ -88,7 +87,6 @@ impl ty::TyAstNode { &path, s, a.alias.clone(), - a.is_absolute, ); if import.is_ok() { @@ -104,7 +102,6 @@ impl ty::TyAstNode { enum_name, s, a.alias.clone(), - a.is_absolute, ); if variant_import.is_ok() { handler.append(variant_import_handler); diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 8cfbdfe10d3..19857d89218 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -3,7 +3,7 @@ use crate::{ engine_threading::Engines, language::{ parsed::*, - ty::{self, TyDecl, TyTraitItem}, + ty::{self, TyTraitItem}, CallPath, Visibility, }, semantic_analysis::*, @@ -14,7 +14,6 @@ use crate::{ use super::{ lexical_scope::{GlobImport, Items, LexicalScope, SymbolMap}, root::Root, - trait_map::TraitMap, LexicalScopeId, ModuleName, Path, PathBuf, }; @@ -281,54 +280,6 @@ impl Module { self.current_lexical_scope_id = parent_scope_id.unwrap_or(0); } - /// Given a path to a `src` module, create synonyms to every symbol in that module to the given - /// `dst` module. - /// - /// This is used when an import path contains an asterisk. - /// - /// Paths are assumed to be relative to `self`. - pub(crate) fn star_import( - &mut self, - handler: &Handler, - engines: &Engines, - src: &Path, - dst: &Path, - is_src_absolute: bool, - ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, src)?; - - let decl_engine = engines.de(); - - let src_mod = self.check_submodule(handler, src)?; - - let implemented_traits = src_mod.current_items().implemented_traits.clone(); - let mut symbols_and_decls = vec![]; - for (symbol, decl) in src_mod.current_items().symbols.iter() { - if is_ancestor(src, dst) || decl.visibility(decl_engine).is_public() { - symbols_and_decls.push((symbol.clone(), decl.clone())); - } - } - - let dst_mod = &mut self[dst]; - dst_mod - .current_items_mut() - .implemented_traits - .extend(implemented_traits, engines); - for symbol_and_decl in symbols_and_decls { - dst_mod.current_items_mut().use_synonyms.insert( - symbol_and_decl.0, - ( - src.to_vec(), - GlobImport::Yes, - symbol_and_decl.1, - is_src_absolute, - ), - ); - } - - Ok(()) - } - /// Given a path to a `src` module, create synonyms to every symbol in that module to the given /// `dst` module. /// @@ -405,303 +356,6 @@ impl Module { Ok(()) } - /// Pull a single item from a `src` module and import it into the `dst` module. - /// - /// The item we want to import is basically the last item in path because this is a `self` - /// import. - pub(crate) fn self_import( - &mut self, - handler: &Handler, - engines: &Engines, - src: &Path, - dst: &Path, - alias: Option, - is_src_absolute: bool, - ) -> Result<(), ErrorEmitted> { - let (last_item, src) = src.split_last().expect("guaranteed by grammar"); - self.item_import( - handler, - engines, - src, - last_item, - dst, - alias, - is_src_absolute, - ) - } - - /// Pull a single `item` from the given `src` module and import it into the `dst` module. - /// - /// Paths are assumed to be relative to `self`. - #[allow(clippy::too_many_arguments)] - pub(crate) fn item_import( - &mut self, - handler: &Handler, - engines: &Engines, - src: &Path, - item: &Ident, - dst: &Path, - alias: Option, - is_src_absolute: bool, - ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, src)?; - - let decl_engine = engines.de(); - - let src_mod = self.check_submodule(handler, src)?; - let mut impls_to_insert = TraitMap::default(); - match src_mod.current_items().symbols.get(item).cloned() { - Some(decl) => { - if !decl.visibility(decl_engine).is_public() && !is_ancestor(src, dst) { - handler.emit_err(CompileError::ImportPrivateSymbol { - name: item.clone(), - span: item.span(), - }); - } - - // if this is an enum or struct or function, import its implementations - if let Ok(type_id) = decl.return_type(&Handler::default(), engines) { - impls_to_insert.extend( - src_mod - .current_items() - .implemented_traits - .filter_by_type_item_import(type_id, engines), - engines, - ); - } - // if this is a trait, import its implementations - let decl_span = decl.span(); - if let TyDecl::TraitDecl(_) = &decl { - // TODO: we only import local impls from the source namespace - // this is okay for now but we'll need to device some mechanism to collect all available trait impls - impls_to_insert.extend( - src_mod - .current_items() - .implemented_traits - .filter_by_trait_decl_span(decl_span), - engines, - ); - } - // no matter what, import it this way though. - let dst_mod = &mut self[dst]; - let add_synonym = |name| { - if let Some((_, GlobImport::No, _, _)) = - dst_mod.current_items().use_synonyms.get(name) - { - handler.emit_err(CompileError::ShadowsOtherSymbol { name: name.into() }); - } - dst_mod.current_items_mut().use_synonyms.insert( - name.clone(), - (src.to_vec(), GlobImport::No, decl, is_src_absolute), - ); - }; - match alias { - Some(alias) => { - add_synonym(&alias); - dst_mod - .current_items_mut() - .use_aliases - .insert(alias.as_str().to_string(), item.clone()); - } - None => add_synonym(item), - }; - } - None => { - return Err(handler.emit_err(CompileError::SymbolNotFound { - name: item.clone(), - span: item.span(), - })); - } - }; - - let dst_mod = &mut self[dst]; - dst_mod - .current_items_mut() - .implemented_traits - .extend(impls_to_insert, engines); - - Ok(()) - } - - /// Pull a single variant `variant` from the enum `enum_name` from the given `src` module and import it into the `dst` module. - /// - /// Paths are assumed to be relative to `self`. - #[allow(clippy::too_many_arguments)] // TODO: remove lint bypass once private modules are no longer experimental - pub(crate) fn variant_import( - &mut self, - handler: &Handler, - engines: &Engines, - src: &Path, - enum_name: &Ident, - variant_name: &Ident, - dst: &Path, - alias: Option, - is_src_absolute: bool, - ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, src)?; - - let decl_engine = engines.de(); - - let src_mod = self.check_submodule(handler, src)?; - match src_mod.current_items().symbols.get(enum_name).cloned() { - Some(decl) => { - if !decl.visibility(decl_engine).is_public() && !is_ancestor(src, dst) { - handler.emit_err(CompileError::ImportPrivateSymbol { - name: enum_name.clone(), - span: enum_name.span(), - }); - } - - if let TyDecl::EnumDecl(ty::EnumDecl { - decl_id, - subst_list: _, - .. - }) = decl - { - let enum_decl = decl_engine.get_enum(&decl_id); - let enum_ref = DeclRef::new( - enum_decl.call_path.suffix.clone(), - decl_id, - enum_decl.span(), - ); - - if let Some(variant_decl) = - enum_decl.variants.iter().find(|v| v.name == *variant_name) - { - // import it this way. - let dst_mod = &mut self[dst]; - let mut add_synonym = |name| { - if let Some((_, GlobImport::No, _, _)) = - dst_mod.current_items().use_synonyms.get(name) - { - handler.emit_err(CompileError::ShadowsOtherSymbol { - name: name.into(), - }); - } - dst_mod.current_items_mut().use_synonyms.insert( - name.clone(), - ( - src.to_vec(), - GlobImport::No, - TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref: enum_ref.clone(), - variant_name: variant_name.clone(), - variant_decl_span: variant_decl.span.clone(), - }), - is_src_absolute, - ), - ); - }; - match alias { - Some(alias) => { - add_synonym(&alias); - dst_mod - .current_items_mut() - .use_aliases - .insert(alias.as_str().to_string(), variant_name.clone()); - } - None => add_synonym(variant_name), - }; - } else { - return Err(handler.emit_err(CompileError::SymbolNotFound { - name: variant_name.clone(), - span: variant_name.span(), - })); - } - } else { - return Err(handler.emit_err(CompileError::Internal( - "Attempting to import variants of something that isn't an enum", - enum_name.span(), - ))); - } - } - None => { - return Err(handler.emit_err(CompileError::SymbolNotFound { - name: enum_name.clone(), - span: enum_name.span(), - })); - } - }; - - Ok(()) - } - - /// Pull all variants from the enum `enum_name` from the given `src` module and import them all into the `dst` module. - /// - /// Paths are assumed to be relative to `self`. - pub(crate) fn variant_star_import( - &mut self, - handler: &Handler, - engines: &Engines, - src: &Path, - dst: &Path, - enum_name: &Ident, - is_src_absolute: bool, - ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, src)?; - - let decl_engine = engines.de(); - - let src_mod = self.check_submodule(handler, src)?; - match src_mod.current_items().symbols.get(enum_name).cloned() { - Some(decl) => { - if !decl.visibility(decl_engine).is_public() && !is_ancestor(src, dst) { - handler.emit_err(CompileError::ImportPrivateSymbol { - name: enum_name.clone(), - span: enum_name.span(), - }); - } - - if let TyDecl::EnumDecl(ty::EnumDecl { - decl_id, - subst_list: _, - .. - }) = decl - { - let enum_decl = decl_engine.get_enum(&decl_id); - let enum_ref = DeclRef::new( - enum_decl.call_path.suffix.clone(), - decl_id, - enum_decl.span(), - ); - - for variant_decl in enum_decl.variants.iter() { - let variant_name = &variant_decl.name; - - // import it this way. - let dst_mod = &mut self[dst]; - dst_mod.current_items_mut().use_synonyms.insert( - variant_name.clone(), - ( - src.to_vec(), - GlobImport::Yes, - TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref: enum_ref.clone(), - variant_name: variant_name.clone(), - variant_decl_span: variant_decl.span.clone(), - }), - is_src_absolute, - ), - ); - } - } else { - return Err(handler.emit_err(CompileError::Internal( - "Attempting to import variants of something that isn't an enum", - enum_name.span(), - ))); - } - } - None => { - return Err(handler.emit_err(CompileError::SymbolNotFound { - name: enum_name.clone(), - span: enum_name.span(), - })); - } - }; - - Ok(()) - } - fn check_module_privacy(&self, handler: &Handler, src: &Path) -> Result<(), ErrorEmitted> { let dst = &self.mod_path; // you are always allowed to access your ancestor's symbols diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index c0840c05744..c4e52fbc3a7 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -1,4 +1,24 @@ -use super::{module::Module, namespace::Namespace}; +use crate::{ + decl_engine::DeclRef, + engine_threading::*, + language::{ + ty::{self, TyDecl}, + }, + namespace::Path, +}; +use super::{ + lexical_scope::GlobImport, + module::Module, + namespace::Namespace, + trait_map::TraitMap, + Ident, +}; +use sway_error::{ + error::CompileError, + handler::{ErrorEmitted, Handler} +}; +use sway_types::Spanned; +use sway_utils::iter_prefixes; /// The root module, from which all other modules can be accessed. /// @@ -13,6 +33,367 @@ pub struct Root { pub(crate) module: Module, } +impl Root { + + /// Given a path to a `src` module, create synonyms to every symbol in that module to the given + /// `dst` module. + /// + /// This is used when an import path contains an asterisk. + /// + /// Paths are assumed to be absolute. + pub(crate) fn star_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &Path, + dst: &Path, + ) -> Result<(), ErrorEmitted> { + self.check_module_privacy(handler, src)?; + + let decl_engine = engines.de(); + + let src_mod = self.module.check_submodule(handler, src)?; + + let implemented_traits = src_mod.current_items().implemented_traits.clone(); + let mut symbols_and_decls = vec![]; + for (symbol, decl) in src_mod.current_items().symbols.iter() { + if is_ancestor(src, dst) || decl.visibility(decl_engine).is_public() { + symbols_and_decls.push((symbol.clone(), decl.clone())); + } + } + + let dst_mod = &mut self.module[dst]; + dst_mod + .current_items_mut() + .implemented_traits + .extend(implemented_traits, engines); // TODO: No difference made between imported and declared items + for symbol_and_decl in symbols_and_decls { + dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + symbol_and_decl.0, + ( + src.to_vec(), + GlobImport::Yes, + symbol_and_decl.1, + true, + ), + ); + } + + Ok(()) + } + + /// Pull a single item from a `src` module and import it into the `dst` module. + /// + /// The item we want to import is basically the last item in path because this is a `self` + /// import. + pub(crate) fn self_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &Path, + dst: &Path, + alias: Option, + ) -> Result<(), ErrorEmitted> { + let (last_item, src) = src.split_last().expect("guaranteed by grammar"); + self.item_import( + handler, + engines, + src, + last_item, + dst, + alias, + ) + } + + /// Pull a single `item` from the given `src` module and import it into the `dst` module. + /// + /// Paths are assumed to be absolute. + #[allow(clippy::too_many_arguments)] + pub(crate) fn item_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &Path, + item: &Ident, + dst: &Path, + alias: Option, + ) -> Result<(), ErrorEmitted> { + self.check_module_privacy(handler, src)?; + + let decl_engine = engines.de(); + + let src_mod = self.module.check_submodule(handler, src)?; + let mut impls_to_insert = TraitMap::default(); + match src_mod.current_items().symbols.get(item).cloned() { + Some(decl) => { + if !decl.visibility(decl_engine).is_public() && !is_ancestor(src, dst) { + handler.emit_err(CompileError::ImportPrivateSymbol { + name: item.clone(), + span: item.span(), + }); + } + + // if this is an enum or struct or function, import its implementations + if let Ok(type_id) = decl.return_type(&Handler::default(), engines) { + impls_to_insert.extend( + src_mod + .current_items() + .implemented_traits + .filter_by_type_item_import(type_id, engines), + engines, + ); + } + // if this is a trait, import its implementations + let decl_span = decl.span(); + if let TyDecl::TraitDecl(_) = &decl { + // TODO: we only import local impls from the source namespace + // this is okay for now but we'll need to device some mechanism to collect all available trait impls + impls_to_insert.extend( + src_mod + .current_items() + .implemented_traits + .filter_by_trait_decl_span(decl_span), + engines, + ); + } + // no matter what, import it this way though. + let dst_mod = &mut self.module[dst]; + let add_synonym = |name| { + if let Some((_, GlobImport::No, _, _)) = + dst_mod.current_items().use_synonyms.get(name) + { + handler.emit_err(CompileError::ShadowsOtherSymbol { name: name.into() }); + } + dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + name.clone(), + (src.to_vec(), GlobImport::No, decl, true), + ); + }; + match alias { + Some(alias) => { + add_synonym(&alias); + dst_mod + .current_items_mut() + .use_aliases + .insert(alias.as_str().to_string(), item.clone()); // TODO: No difference made between imported and declared items + } + None => add_synonym(item), + }; + } + None => { + return Err(handler.emit_err(CompileError::SymbolNotFound { + name: item.clone(), + span: item.span(), + })); + } + }; + + let dst_mod = &mut self.module[dst]; + dst_mod + .current_items_mut() + .implemented_traits + .extend(impls_to_insert, engines); // TODO: No difference made between imported and declared items + + Ok(()) + } + + /// Pull a single variant `variant` from the enum `enum_name` from the given `src` module and import it into the `dst` module. + /// + /// Paths are assumed to be absolute. + #[allow(clippy::too_many_arguments)] // TODO: remove lint bypass once private modules are no longer experimental + pub(crate) fn variant_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &Path, + enum_name: &Ident, + variant_name: &Ident, + dst: &Path, + alias: Option, + ) -> Result<(), ErrorEmitted> { + self.check_module_privacy(handler, src)?; + + let decl_engine = engines.de(); + + let src_mod = self.module.check_submodule(handler, src)?; + match src_mod.current_items().symbols.get(enum_name).cloned() { + Some(decl) => { + if !decl.visibility(decl_engine).is_public() && !is_ancestor(src, dst) { + handler.emit_err(CompileError::ImportPrivateSymbol { + name: enum_name.clone(), + span: enum_name.span(), + }); + } + + if let TyDecl::EnumDecl(ty::EnumDecl { + decl_id, + subst_list: _, + .. + }) = decl + { + let enum_decl = decl_engine.get_enum(&decl_id); + let enum_ref = DeclRef::new( + enum_decl.call_path.suffix.clone(), + decl_id, + enum_decl.span(), + ); + + if let Some(variant_decl) = + enum_decl.variants.iter().find(|v| v.name == *variant_name) + { + // import it this way. + let dst_mod = &mut self.module[dst]; + let mut add_synonym = |name| { + if let Some((_, GlobImport::No, _, _)) = + dst_mod.current_items().use_synonyms.get(name) + { + handler.emit_err(CompileError::ShadowsOtherSymbol { + name: name.into(), + }); + } + dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + name.clone(), + ( + src.to_vec(), + GlobImport::No, + TyDecl::EnumVariantDecl(ty::EnumVariantDecl { + enum_ref: enum_ref.clone(), + variant_name: variant_name.clone(), + variant_decl_span: variant_decl.span.clone(), + }), + true, + ), + ); + }; + match alias { + Some(alias) => { + add_synonym(&alias); + dst_mod + .current_items_mut() + .use_aliases + .insert(alias.as_str().to_string(), variant_name.clone()); // TODO: No difference made between imported and declared items + } + None => add_synonym(variant_name), + }; + } else { + return Err(handler.emit_err(CompileError::SymbolNotFound { + name: variant_name.clone(), + span: variant_name.span(), + })); + } + } else { + return Err(handler.emit_err(CompileError::Internal( + "Attempting to import variants of something that isn't an enum", + enum_name.span(), + ))); + } + } + None => { + return Err(handler.emit_err(CompileError::SymbolNotFound { + name: enum_name.clone(), + span: enum_name.span(), + })); + } + }; + + Ok(()) + } + + /// Pull all variants from the enum `enum_name` from the given `src` module and import them all into the `dst` module. + /// + /// Paths are assumed to be absolute. + pub(crate) fn variant_star_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &Path, + dst: &Path, + enum_name: &Ident, + ) -> Result<(), ErrorEmitted> { + self.check_module_privacy(handler, src)?; + + let decl_engine = engines.de(); + + let src_mod = self.module.check_submodule(handler, src)?; + match src_mod.current_items().symbols.get(enum_name).cloned() { + Some(decl) => { + if !decl.visibility(decl_engine).is_public() && !is_ancestor(src, dst) { + handler.emit_err(CompileError::ImportPrivateSymbol { + name: enum_name.clone(), + span: enum_name.span(), + }); + } + + if let TyDecl::EnumDecl(ty::EnumDecl { + decl_id, + subst_list: _, + .. + }) = decl + { + let enum_decl = decl_engine.get_enum(&decl_id); + let enum_ref = DeclRef::new( + enum_decl.call_path.suffix.clone(), + decl_id, + enum_decl.span(), + ); + + for variant_decl in enum_decl.variants.iter() { + let variant_name = &variant_decl.name; + + // import it this way. + let dst_mod = &mut self.module[dst]; + dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + variant_name.clone(), + ( + src.to_vec(), + GlobImport::Yes, + TyDecl::EnumVariantDecl(ty::EnumVariantDecl { + enum_ref: enum_ref.clone(), + variant_name: variant_name.clone(), + variant_decl_span: variant_decl.span.clone(), + }), + true + ), + ); + } + } else { + return Err(handler.emit_err(CompileError::Internal( + "Attempting to import variants of something that isn't an enum", + enum_name.span(), + ))); + } + } + None => { + return Err(handler.emit_err(CompileError::SymbolNotFound { + name: enum_name.clone(), + span: enum_name.span(), + })); + } + }; + + Ok(()) + } + + fn check_module_privacy(&self, handler: &Handler, src: &Path) -> Result<(), ErrorEmitted> { + let dst = &self.module.mod_path; + // you are always allowed to access your ancestor's symbols + if !is_ancestor(src, dst) { + // we don't check the first prefix because direct children are always accessible + for prefix in iter_prefixes(src).skip(1) { + let module = self.module.check_submodule(handler, prefix)?; + if module.visibility.is_private() { + let prefix_last = prefix[prefix.len() - 1].clone(); + handler.emit_err(CompileError::ImportPrivateModule { + span: prefix_last.span(), + name: prefix_last, + }); + } + } + } + Ok(()) + } +} + impl From for Root { fn from(module: Module) -> Self { Root { module } @@ -24,3 +405,7 @@ impl From for Root { namespace.root } } + +fn is_ancestor(src: &Path, dst: &Path) -> bool { + dst.len() >= src.len() && src.iter().zip(dst).all(|(src, dst)| src == dst) +} diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 8ec36b02494..32430b5a3c8 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1269,14 +1269,12 @@ impl<'a> TypeCheckContext<'a> { &mut self, handler: &Handler, src: &Path, - is_absolute: bool, ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); self.namespace_mut() .root - .module - .star_import(handler, engines, src, &mod_path, is_absolute) + .star_import(handler, engines, src, &mod_path) } /// Short-hand for performing a [Module::variant_star_import] with `mod_path` as the destination. @@ -1285,17 +1283,15 @@ impl<'a> TypeCheckContext<'a> { handler: &Handler, src: &Path, enum_name: &Ident, - is_absolute: bool, ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.module.variant_star_import( + self.namespace_mut().root.variant_star_import( handler, engines, src, &mod_path, enum_name, - is_absolute, ) } @@ -1305,17 +1301,15 @@ impl<'a> TypeCheckContext<'a> { handler: &Handler, src: &Path, alias: Option, - is_absolute: bool, ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.module.self_import( + self.namespace_mut().root.self_import( handler, engines, src, &mod_path, alias, - is_absolute, ) } @@ -1326,18 +1320,16 @@ impl<'a> TypeCheckContext<'a> { src: &Path, item: &Ident, alias: Option, - is_absolute: bool, ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.module.item_import( + self.namespace_mut().root.item_import( handler, engines, src, item, &mod_path, alias, - is_absolute, ) } @@ -1350,11 +1342,10 @@ impl<'a> TypeCheckContext<'a> { enum_name: &Ident, variant_name: &Ident, alias: Option, - is_absolute: bool, ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.module.variant_import( + self.namespace_mut().root.variant_import( handler, engines, src, @@ -1362,7 +1353,6 @@ impl<'a> TypeCheckContext<'a> { variant_name, &mod_path, alias, - is_absolute, ) } From 945fec10034c2c66d5e13cd9485a1bf5c44d4e5e Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Sat, 2 Mar 2024 19:26:32 +0100 Subject: [PATCH 03/11] Move prelude imports to Root --- forc-pkg/src/pkg.rs | 24 ++-- sway-core/src/lib.rs | 8 +- .../src/semantic_analysis/namespace/module.rs | 105 +----------------- .../semantic_analysis/namespace/namespace.rs | 5 +- .../src/semantic_analysis/namespace/root.rs | 76 +++++++++++++ sway-core/src/semantic_analysis/program.rs | 2 +- test/src/ir_generation/mod.rs | 5 +- 7 files changed, 102 insertions(+), 123 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 4c323351209..f0cf3933185 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1594,19 +1594,19 @@ pub fn dependency_namespace( node: NodeIx, engines: &Engines, contract_id_value: Option, -) -> Result> { +) -> Result> { // TODO: Clean this up when config-time constants v1 are removed. let node_idx = &graph[node]; let name = Some(Ident::new_no_span(node_idx.name.clone())); - let mut namespace = if let Some(contract_id_value) = contract_id_value { + let mut root_module = if let Some(contract_id_value) = contract_id_value { namespace::Module::default_with_contract_id(engines, name.clone(), contract_id_value)? } else { namespace::Module::default() }; - namespace.is_external = true; - namespace.name = name; - namespace.visibility = Visibility::Public; + root_module.is_external = true; + root_module.name = name; + root_module.visibility = Visibility::Public; // Add direct dependencies. let mut core_added = false; @@ -1640,7 +1640,7 @@ pub fn dependency_namespace( ns } }; - namespace.insert_submodule(dep_name, dep_namespace); + root_module.insert_submodule(dep_name, dep_namespace); let dep = &graph[dep_node]; if dep.name == CORE { core_added = true; @@ -1651,11 +1651,13 @@ pub fn dependency_namespace( if !core_added { if let Some(core_node) = find_core_dep(graph, node) { let core_namespace = &lib_namespace_map[&core_node]; - namespace.insert_submodule(CORE.to_string(), core_namespace.clone()); + root_module.insert_submodule(CORE.to_string(), core_namespace.clone()); } } - let _ = namespace.star_import_with_reexports( + let mut root = namespace::Root::from(root_module); + + let _ = root.star_import_with_reexports( &Handler::default(), engines, &[CORE, PRELUDE].map(|s| Ident::new_no_span(s.into())), @@ -1664,7 +1666,7 @@ pub fn dependency_namespace( ); if has_std_dep(graph, node) { - let _ = namespace.star_import_with_reexports( + let _ = root.star_import_with_reexports( &Handler::default(), engines, &[STD, PRELUDE].map(|s| Ident::new_no_span(s.into())), @@ -1673,7 +1675,7 @@ pub fn dependency_namespace( ); } - Ok(namespace) + Ok(root) } /// Find the `std` dependency, if it is a direct one, of the given node. @@ -1750,7 +1752,7 @@ pub fn compile( pkg: &PackageDescriptor, profile: &BuildProfile, engines: &Engines, - namespace: namespace::Module, + namespace: namespace::Root, source_map: &mut SourceMap, ) -> Result { let mut metrics = PerformanceData::default(); diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index 8c238d3dbaf..c772e382682 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -474,7 +474,7 @@ pub fn parsed_to_ast( handler: &Handler, engines: &Engines, parse_program: &parsed::ParseProgram, - initial_namespace: namespace::Module, + initial_namespace: namespace::Root, build_config: Option<&BuildConfig>, package_name: &str, retrigger_compilation: Option>, @@ -638,7 +638,7 @@ pub fn compile_to_ast( handler: &Handler, engines: &Engines, input: Arc, - initial_namespace: namespace::Module, + initial_namespace: namespace::Root, build_config: Option<&BuildConfig>, package_name: &str, retrigger_compilation: Option>, @@ -735,7 +735,7 @@ pub fn compile_to_asm( handler: &Handler, engines: &Engines, input: Arc, - initial_namespace: namespace::Module, + initial_namespace: namespace::Root, build_config: BuildConfig, package_name: &str, ) -> Result { @@ -892,7 +892,7 @@ pub fn compile_to_bytecode( handler: &Handler, engines: &Engines, input: Arc, - initial_namespace: namespace::Module, + initial_namespace: namespace::Root, build_config: BuildConfig, source_map: &mut SourceMap, package_name: &str, diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 19857d89218..d05102c168a 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -12,7 +12,7 @@ use crate::{ }; use super::{ - lexical_scope::{GlobImport, Items, LexicalScope, SymbolMap}, + lexical_scope::{Items, LexicalScope, SymbolMap}, root::Root, LexicalScopeId, ModuleName, Path, PathBuf, }; @@ -22,7 +22,6 @@ use sway_error::handler::Handler; use sway_error::{error::CompileError, handler::ErrorEmitted}; use sway_parse::{lex, Parser}; use sway_types::{span::Span, Spanned}; -use sway_utils::iter_prefixes; /// A single `Module` within a Sway project. /// @@ -154,7 +153,8 @@ impl Module { content: AstNodeContent::Declaration(Declaration::ConstantDeclaration(const_decl_id)), span: const_item_span.clone(), }; - let mut ns = Namespace::init_root(Default::default()); + let root = Root::from(Module::default()); + let mut ns = Namespace::init_root(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.is_external = true; @@ -280,101 +280,6 @@ impl Module { self.current_lexical_scope_id = parent_scope_id.unwrap_or(0); } - /// Given a path to a `src` module, create synonyms to every symbol in that module to the given - /// `dst` module. - /// - /// This is used when an import path contains an asterisk. - /// - /// Paths are assumed to be relative to `self`. - pub fn star_import_with_reexports( - &mut self, - handler: &Handler, - engines: &Engines, - src: &Path, - dst: &Path, - is_src_absolute: bool, - ) -> Result<(), ErrorEmitted> { - self.check_module_privacy(handler, src)?; - - let decl_engine = engines.de(); - - let src_mod = self.check_submodule(handler, src)?; - - let implemented_traits = src_mod.current_items().implemented_traits.clone(); - let use_synonyms = src_mod.current_items().use_synonyms.clone(); - let mut symbols_and_decls = src_mod - .current_items() - .use_synonyms - .iter() - .map(|(symbol, (_, _, decl, _))| (symbol.clone(), decl.clone())) - .collect::>(); - for (symbol, decl) in src_mod.current_items().symbols.iter() { - if is_ancestor(src, dst) || decl.visibility(decl_engine).is_public() { - symbols_and_decls.push((symbol.clone(), decl.clone())); - } - } - - let mut symbols_paths_and_decls = vec![]; - for (symbol, (mod_path, _, decl, _)) in use_synonyms { - let mut is_external = false; - let submodule = src_mod.submodule(&[mod_path[0].clone()]); - if let Some(submodule) = submodule { - is_external = submodule.is_external - }; - - let mut path = src[..1].to_vec(); - if is_external { - path = mod_path; - } else { - path.extend(mod_path); - } - - symbols_paths_and_decls.push((symbol, path, decl)); - } - - let dst_mod = &mut self[dst]; - dst_mod - .current_items_mut() - .implemented_traits - .extend(implemented_traits, engines); - - let mut try_add = |symbol, path, decl: ty::TyDecl| { - dst_mod - .current_items_mut() - .use_synonyms - .insert(symbol, (path, GlobImport::Yes, decl, is_src_absolute)); - }; - - for (symbol, decl) in symbols_and_decls { - try_add(symbol, src.to_vec(), decl); - } - - for (symbol, path, decl) in symbols_paths_and_decls { - try_add(symbol, path, decl); - } - - Ok(()) - } - - fn check_module_privacy(&self, handler: &Handler, src: &Path) -> Result<(), ErrorEmitted> { - let dst = &self.mod_path; - // you are always allowed to access your ancestor's symbols - if !is_ancestor(src, dst) { - // we don't check the first prefix because direct children are always accessible - for prefix in iter_prefixes(src).skip(1) { - let module = self.check_submodule(handler, prefix)?; - if module.visibility.is_private() { - let prefix_last = prefix[prefix.len() - 1].clone(); - handler.emit_err(CompileError::ImportPrivateModule { - span: prefix_last.span(), - name: prefix_last, - }); - } - } - } - Ok(()) - } - /// 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 @@ -750,7 +655,3 @@ fn module_not_found(path: &[Ident]) -> CompileError { .join("::"), } } - -fn is_ancestor(src: &Path, dst: &Path) -> bool { - dst.len() >= src.len() && src.iter().zip(dst).all(|(src, dst)| src == dst) -} diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index 89d3b9bfae6..e548a65024c 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -42,11 +42,10 @@ pub struct Namespace { impl Namespace { /// Initialise the namespace at its root from the given initial namespace. - pub fn init_root(init: Module) -> Self { - let root = Root::from(init.clone()); + pub fn init_root(root: Root) -> Self { let mod_path = vec![]; Self { - init, + init: root.module.clone(), root, mod_path, } diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index c4e52fbc3a7..8bc4a5e4d1e 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -374,6 +374,82 @@ impl Root { Ok(()) } + /// Given a path to a `src` module, create synonyms to every symbol in that module to the given + /// `dst` module. + /// + /// This is used when an import path contains an asterisk. + /// + /// Paths are assumed to be absolute. + pub fn star_import_with_reexports( + &mut self, + handler: &Handler, + engines: &Engines, + src: &Path, + dst: &Path, + is_src_absolute: bool, + ) -> Result<(), ErrorEmitted> { + self.check_module_privacy(handler, src)?; + + let decl_engine = engines.de(); + + let src_mod = self.module.check_submodule(handler, src)?; + + let implemented_traits = src_mod.current_items().implemented_traits.clone(); + let use_synonyms = src_mod.current_items().use_synonyms.clone(); + let mut symbols_and_decls = src_mod + .current_items() + .use_synonyms + .iter() + .map(|(symbol, (_, _, decl, _))| (symbol.clone(), decl.clone())) + .collect::>(); + for (symbol, decl) in src_mod.current_items().symbols.iter() { + if is_ancestor(src, dst) || decl.visibility(decl_engine).is_public() { + symbols_and_decls.push((symbol.clone(), decl.clone())); + } + } + + let mut symbols_paths_and_decls = vec![]; + for (symbol, (mod_path, _, decl, _)) in use_synonyms { + let mut is_external = false; + let submodule = src_mod.submodule(&[mod_path[0].clone()]); + if let Some(submodule) = submodule { + is_external = submodule.is_external + }; + + let mut path = src[..1].to_vec(); + if is_external { + path = mod_path; + } else { + path.extend(mod_path); + } + + symbols_paths_and_decls.push((symbol, path, decl)); + } + + let dst_mod = &mut self.module[dst]; + dst_mod + .current_items_mut() + .implemented_traits + .extend(implemented_traits, engines); // TODO: No difference made between imported and declared items + + let mut try_add = |symbol, path, decl: ty::TyDecl| { + dst_mod + .current_items_mut() + .use_synonyms + .insert(symbol, (path, GlobImport::Yes, decl, is_src_absolute)); // TODO: No difference made between imported and declared items + }; + + for (symbol, decl) in symbols_and_decls { + try_add(symbol, src.to_vec(), decl); + } + + for (symbol, path, decl) in symbols_paths_and_decls { + try_add(symbol, path, decl); + } + + Ok(()) + } + fn check_module_privacy(&self, handler: &Handler, src: &Path) -> Result<(), ErrorEmitted> { let dst = &self.module.mod_path; // you are always allowed to access your ancestor's symbols diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index 4c77de9fa12..838bed022dc 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -27,7 +27,7 @@ impl TyProgram { handler: &Handler, engines: &Engines, parsed: &ParseProgram, - initial_namespace: namespace::Module, + initial_namespace: namespace::Root, package_name: &str, build_config: Option<&BuildConfig>, ) -> Result { diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index 815ef8a7aa2..7d0b441ad87 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -230,8 +230,9 @@ pub(super) async fn run( // standard libraries. The namespace, thus its root module, must have the // name set. const PACKAGE_NAME: &str = "test_lib"; - let mut initial_namespace = core_lib.clone(); - initial_namespace.name = Some(sway_types::Ident::new_no_span(PACKAGE_NAME.to_string())); + let mut clone_core_lib = core_lib.clone(); + clone_core_lib.name = Some(sway_types::Ident::new_no_span(PACKAGE_NAME.to_string())); + let initial_namespace = namespace::Root::from(core_lib.clone()); let compile_res = compile_to_ast( &handler, &engines, From 5aac2c4bbdc16b385cd8d734dad1f58b63814aca Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Sat, 2 Mar 2024 19:34:57 +0100 Subject: [PATCH 04/11] Update test --- .../external_mod/src/external_submod.sw | 10 ++++++++++ .../imports_implicitly_public/script/src/main.sw | 1 + 2 files changed, 11 insertions(+) diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw index 1a442f4bd31..4d118c02bb8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw @@ -1,5 +1,15 @@ library; +pub enum ExtSubmodEnum { + A: (), + B: (), +} + pub fn external_submod_foo() -> u32 { + let _ = external_submod_private(); 2 } + +fn external_submod_private() -> ExtSubmodEnum { + ExtSubmodEnum::A +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw index 2238ac2b64f..2a720b6ba58 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw @@ -13,6 +13,7 @@ use std::hash::core::ops::Add; use internal_mod::internal_submod::std::hash::core::ops::Subtract; use external_mod::external_submod::std::core::ops::Multiply; use internal_mod::internal_submod::external_mod::external_submod::std::core::ops::Divide; +use internal_mod::internal_submod::external_mod::external_submod::ExtSubmodEnum; fn main() { assert(internal_mod_foo() + From 22c077aeda47a71d5362af6fbc49de8a4684f089 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Sun, 3 Mar 2024 00:05:19 +0100 Subject: [PATCH 05/11] Remove is_src_absolute flag since it's always true --- forc-pkg/src/pkg.rs | 2 -- sway-core/src/language/call_path.rs | 2 +- .../semantic_analysis/namespace/lexical_scope.rs | 6 +++--- .../src/semantic_analysis/namespace/module.rs | 4 ++-- .../src/semantic_analysis/namespace/root.rs | 16 ++++++---------- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index f0cf3933185..ee1c1f87cef 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1662,7 +1662,6 @@ pub fn dependency_namespace( engines, &[CORE, PRELUDE].map(|s| Ident::new_no_span(s.into())), &[], - true, ); if has_std_dep(graph, node) { @@ -1671,7 +1670,6 @@ pub fn dependency_namespace( engines, &[STD, PRELUDE].map(|s| Ident::new_no_span(s.into())), &[], - true, ); } diff --git a/sway-core/src/language/call_path.rs b/sway-core/src/language/call_path.rs index d19c5c404ed..1fd6bf49445 100644 --- a/sway-core/src/language/call_path.rs +++ b/sway-core/src/language/call_path.rs @@ -320,7 +320,7 @@ impl CallPath { .get(&self.suffix) { synonym_prefixes = use_synonym.0.clone(); - is_absolute = use_synonym.3; + is_absolute = true; let submodule = namespace.module().submodule(&[use_synonym.0[0].clone()]); if let Some(submodule) = submodule { is_external = submodule.is_external; diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index f0665e1a670..f1b9375a740 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -28,8 +28,8 @@ pub(crate) enum GlobImport { } pub(super) type SymbolMap = im::OrdMap; -// The final `bool` field of `UseSynonyms` is true if the `Vec` path is absolute. -pub(super) type UseSynonyms = im::HashMap, GlobImport, ty::TyDecl, bool)>; +// The `Vec` path is absolute. +pub(super) type UseSynonyms = im::HashMap, GlobImport, ty::TyDecl)>; pub(super) type UseAliases = im::HashMap; /// Represents a lexical scope integer-based identifier, which can be used to reference @@ -261,7 +261,7 @@ impl Items { append_shadowing_error(ident, decl, false, false, &item, const_shadowing_mode); } - if let Some((ident, (_, GlobImport::No, decl, _))) = self.use_synonyms.get_key_value(&name) + if let Some((ident, (_, GlobImport::No, decl))) = self.use_synonyms.get_key_value(&name) { append_shadowing_error( ident, diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index d05102c168a..495ccfbb212 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -593,8 +593,8 @@ impl Module { .get(symbol.as_str()) .unwrap_or(symbol); match module.current_items().use_synonyms.get(symbol) { - Some((_, _, decl @ ty::TyDecl::EnumVariantDecl { .. }, _)) => Ok(decl.clone()), - Some((src_path, _, _, _)) if mod_path != src_path => { + Some((_, _, decl @ ty::TyDecl::EnumVariantDecl { .. })) => Ok(decl.clone()), + Some((src_path, _, _)) if mod_path != src_path => { // If the symbol is imported, before resolving to it, // we need to check if there is a local symbol withing the module with // the same name, and if yes resolve to the local symbol, because it diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 8bc4a5e4d1e..a12de4774b8 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -74,7 +74,6 @@ impl Root { src.to_vec(), GlobImport::Yes, symbol_and_decl.1, - true, ), ); } @@ -159,14 +158,14 @@ impl Root { // no matter what, import it this way though. let dst_mod = &mut self.module[dst]; let add_synonym = |name| { - if let Some((_, GlobImport::No, _, _)) = + if let Some((_, GlobImport::No, _)) = dst_mod.current_items().use_synonyms.get(name) { handler.emit_err(CompileError::ShadowsOtherSymbol { name: name.into() }); } dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items name.clone(), - (src.to_vec(), GlobImport::No, decl, true), + (src.to_vec(), GlobImport::No, decl), ); }; match alias { @@ -244,7 +243,7 @@ impl Root { // import it this way. let dst_mod = &mut self.module[dst]; let mut add_synonym = |name| { - if let Some((_, GlobImport::No, _, _)) = + if let Some((_, GlobImport::No, _)) = dst_mod.current_items().use_synonyms.get(name) { handler.emit_err(CompileError::ShadowsOtherSymbol { @@ -261,7 +260,6 @@ impl Root { variant_name: variant_name.clone(), variant_decl_span: variant_decl.span.clone(), }), - true, ), ); }; @@ -352,7 +350,6 @@ impl Root { variant_name: variant_name.clone(), variant_decl_span: variant_decl.span.clone(), }), - true ), ); } @@ -386,7 +383,6 @@ impl Root { engines: &Engines, src: &Path, dst: &Path, - is_src_absolute: bool, ) -> Result<(), ErrorEmitted> { self.check_module_privacy(handler, src)?; @@ -400,7 +396,7 @@ impl Root { .current_items() .use_synonyms .iter() - .map(|(symbol, (_, _, decl, _))| (symbol.clone(), decl.clone())) + .map(|(symbol, (_, _, decl))| (symbol.clone(), decl.clone())) .collect::>(); for (symbol, decl) in src_mod.current_items().symbols.iter() { if is_ancestor(src, dst) || decl.visibility(decl_engine).is_public() { @@ -409,7 +405,7 @@ impl Root { } let mut symbols_paths_and_decls = vec![]; - for (symbol, (mod_path, _, decl, _)) in use_synonyms { + for (symbol, (mod_path, _, decl)) in use_synonyms { let mut is_external = false; let submodule = src_mod.submodule(&[mod_path[0].clone()]); if let Some(submodule) = submodule { @@ -436,7 +432,7 @@ impl Root { dst_mod .current_items_mut() .use_synonyms - .insert(symbol, (path, GlobImport::Yes, decl, is_src_absolute)); // TODO: No difference made between imported and declared items + .insert(symbol, (path, GlobImport::Yes, decl)); // TODO: No difference made between imported and declared items }; for (symbol, decl) in symbols_and_decls { From e79d6b7505f2d8887685b4e9c662e77bc410eebe Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Tue, 5 Mar 2024 14:05:39 +0100 Subject: [PATCH 06/11] fmt, clippy --- forc-pkg/src/pkg.rs | 2 +- .../src/semantic_analysis/ast_node/mod.rs | 11 +--- .../namespace/lexical_scope.rs | 3 +- .../src/semantic_analysis/namespace/module.rs | 2 +- .../src/semantic_analysis/namespace/root.rs | 57 +++++++------------ .../semantic_analysis/type_check_context.rs | 31 +++------- 6 files changed, 37 insertions(+), 69 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index ee1c1f87cef..e109c8c186f 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1656,7 +1656,7 @@ pub fn dependency_namespace( } let mut root = namespace::Root::from(root_module); - + let _ = root.star_import_with_reexports( &Handler::default(), engines, diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index e0ac6bd12b9..84ae5481756 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -49,8 +49,7 @@ impl ty::TyAstNode { ImportType::Star => { // try a standard starimport first let star_import_handler = Handler::default(); - let import = - ctx.star_import(&star_import_handler, &path); + let import = ctx.star_import(&star_import_handler, &path); if import.is_ok() { handler.append(star_import_handler); import @@ -82,12 +81,8 @@ impl ty::TyAstNode { ImportType::Item(ref s) => { // try a standard item import first let item_import_handler = Handler::default(); - let import = ctx.item_import( - &item_import_handler, - &path, - s, - a.alias.clone(), - ); + let import = + ctx.item_import(&item_import_handler, &path, s, a.alias.clone()); if import.is_ok() { handler.append(item_import_handler); diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index f1b9375a740..932c3128707 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -261,8 +261,7 @@ impl Items { append_shadowing_error(ident, decl, false, false, &item, const_shadowing_mode); } - if let Some((ident, (_, GlobImport::No, decl))) = self.use_synonyms.get_key_value(&name) - { + if let Some((ident, (_, GlobImport::No, decl))) = self.use_synonyms.get_key_value(&name) { append_shadowing_error( ident, decl, diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 495ccfbb212..a146a49843a 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -153,7 +153,7 @@ impl Module { content: AstNodeContent::Declaration(Declaration::ConstantDeclaration(const_decl_id)), span: const_item_span.clone(), }; - let root = Root::from(Module::default()); + let root = Root::from(Module::default()); let mut ns = Namespace::init_root(root); // This is pretty hacky but that's okay because of this code is being removed pretty soon ns.root.module.name = ns_name; diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index a12de4774b8..da552e68183 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -1,21 +1,15 @@ +use super::{ + lexical_scope::GlobImport, module::Module, namespace::Namespace, trait_map::TraitMap, Ident, +}; use crate::{ decl_engine::DeclRef, engine_threading::*, - language::{ - ty::{self, TyDecl}, - }, + language::ty::{self, TyDecl}, namespace::Path, }; -use super::{ - lexical_scope::GlobImport, - module::Module, - namespace::Namespace, - trait_map::TraitMap, - Ident, -}; use sway_error::{ error::CompileError, - handler::{ErrorEmitted, Handler} + handler::{ErrorEmitted, Handler}, }; use sway_types::Spanned; use sway_utils::iter_prefixes; @@ -34,7 +28,6 @@ pub struct Root { } impl Root { - /// Given a path to a `src` module, create synonyms to every symbol in that module to the given /// `dst` module. /// @@ -66,15 +59,12 @@ impl Root { dst_mod .current_items_mut() .implemented_traits - .extend(implemented_traits, engines); // TODO: No difference made between imported and declared items + .extend(implemented_traits, engines); // TODO: No difference made between imported and declared items for symbol_and_decl in symbols_and_decls { - dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + dst_mod.current_items_mut().use_synonyms.insert( + // TODO: No difference made between imported and declared items symbol_and_decl.0, - ( - src.to_vec(), - GlobImport::Yes, - symbol_and_decl.1, - ), + (src.to_vec(), GlobImport::Yes, symbol_and_decl.1), ); } @@ -94,14 +84,7 @@ impl Root { alias: Option, ) -> Result<(), ErrorEmitted> { let (last_item, src) = src.split_last().expect("guaranteed by grammar"); - self.item_import( - handler, - engines, - src, - last_item, - dst, - alias, - ) + self.item_import(handler, engines, src, last_item, dst, alias) } /// Pull a single `item` from the given `src` module and import it into the `dst` module. @@ -163,7 +146,8 @@ impl Root { { handler.emit_err(CompileError::ShadowsOtherSymbol { name: name.into() }); } - dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + dst_mod.current_items_mut().use_synonyms.insert( + // TODO: No difference made between imported and declared items name.clone(), (src.to_vec(), GlobImport::No, decl), ); @@ -174,7 +158,7 @@ impl Root { dst_mod .current_items_mut() .use_aliases - .insert(alias.as_str().to_string(), item.clone()); // TODO: No difference made between imported and declared items + .insert(alias.as_str().to_string(), item.clone()); // TODO: No difference made between imported and declared items } None => add_synonym(item), }; @@ -191,7 +175,7 @@ impl Root { dst_mod .current_items_mut() .implemented_traits - .extend(impls_to_insert, engines); // TODO: No difference made between imported and declared items + .extend(impls_to_insert, engines); // TODO: No difference made between imported and declared items Ok(()) } @@ -250,7 +234,8 @@ impl Root { name: name.into(), }); } - dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + dst_mod.current_items_mut().use_synonyms.insert( + // TODO: No difference made between imported and declared items name.clone(), ( src.to_vec(), @@ -269,7 +254,8 @@ impl Root { dst_mod .current_items_mut() .use_aliases - .insert(alias.as_str().to_string(), variant_name.clone()); // TODO: No difference made between imported and declared items + .insert(alias.as_str().to_string(), variant_name.clone()); + // TODO: No difference made between imported and declared items } None => add_synonym(variant_name), }; @@ -340,7 +326,8 @@ impl Root { // import it this way. let dst_mod = &mut self.module[dst]; - dst_mod.current_items_mut().use_synonyms.insert( // TODO: No difference made between imported and declared items + dst_mod.current_items_mut().use_synonyms.insert( + // TODO: No difference made between imported and declared items variant_name.clone(), ( src.to_vec(), @@ -426,13 +413,13 @@ impl Root { dst_mod .current_items_mut() .implemented_traits - .extend(implemented_traits, engines); // TODO: No difference made between imported and declared items + .extend(implemented_traits, engines); // TODO: No difference made between imported and declared items let mut try_add = |symbol, path, decl: ty::TyDecl| { dst_mod .current_items_mut() .use_synonyms - .insert(symbol, (path, GlobImport::Yes, decl)); // TODO: No difference made between imported and declared items + .insert(symbol, (path, GlobImport::Yes, decl)); // TODO: No difference made between imported and declared items }; for (symbol, decl) in symbols_and_decls { diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 32430b5a3c8..cfd45b0b3f4 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1286,13 +1286,9 @@ impl<'a> TypeCheckContext<'a> { ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.variant_star_import( - handler, - engines, - src, - &mod_path, - enum_name, - ) + self.namespace_mut() + .root + .variant_star_import(handler, engines, src, &mod_path, enum_name) } /// Short-hand for performing a [Module::self_import] with `mod_path` as the destination. @@ -1304,13 +1300,9 @@ impl<'a> TypeCheckContext<'a> { ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.self_import( - handler, - engines, - src, - &mod_path, - alias, - ) + self.namespace_mut() + .root + .self_import(handler, engines, src, &mod_path, alias) } /// Short-hand for performing a [Module::item_import] with `mod_path` as the destination. @@ -1323,14 +1315,9 @@ impl<'a> TypeCheckContext<'a> { ) -> Result<(), ErrorEmitted> { let engines = self.engines; let mod_path = self.namespace().mod_path.clone(); - self.namespace_mut().root.item_import( - handler, - engines, - src, - item, - &mod_path, - alias, - ) + self.namespace_mut() + .root + .item_import(handler, engines, src, item, &mod_path, alias) } /// Short-hand for performing a [Module::variant_import] with `mod_path` as the destination. From 741f23819ec6f26445783d42e32df4d4aa89f6d7 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Tue, 5 Mar 2024 14:19:26 +0100 Subject: [PATCH 07/11] Removed unready test --- .../imports_implicitly_public/Forc.lock | 25 ------------------- .../imports_implicitly_public/Forc.toml | 2 -- .../external_mod/Forc.toml | 9 ------- .../external_mod/src/external_submod.sw | 15 ----------- .../external_mod/src/main.sw | 7 ------ .../json_abi_oracle.json | 1 - .../script/Forc.toml | 10 -------- .../script/src/internal_mod.sw | 7 ------ .../src/internal_mod/internal_submod.sw | 7 ------ .../script/src/main.sw | 23 ----------------- .../imports_implicitly_public/test.toml | 3 --- 11 files changed, 109 deletions(-) delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw delete mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock deleted file mode 100644 index 122dda190ba..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.lock +++ /dev/null @@ -1,25 +0,0 @@ -[[package]] -name = "core" -source = "path+from-root-4569ADD4F9A2E45D" - -[[package]] -name = "external_mod" -source = "member" -dependencies = [ - "core", - "std", -] - -[[package]] -name = "script" -source = "member" -dependencies = [ - "core", - "external_mod", - "std", -] - -[[package]] -name = "std" -source = "path+from-root-4569ADD4F9A2E45D" -dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml deleted file mode 100644 index 5cc6cbd57a0..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/Forc.toml +++ /dev/null @@ -1,2 +0,0 @@ -[workspace] -members = ["script", "external_mod"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml deleted file mode 100644 index ed75dd55645..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/Forc.toml +++ /dev/null @@ -1,9 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "external_mod" - -[dependencies] -core = { path = "../../../../../../../sway-lib-core" } -std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw deleted file mode 100644 index 4d118c02bb8..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/external_submod.sw +++ /dev/null @@ -1,15 +0,0 @@ -library; - -pub enum ExtSubmodEnum { - A: (), - B: (), -} - -pub fn external_submod_foo() -> u32 { - let _ = external_submod_private(); - 2 -} - -fn external_submod_private() -> ExtSubmodEnum { - ExtSubmodEnum::A -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw deleted file mode 100644 index 43e5719e375..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/external_mod/src/main.sw +++ /dev/null @@ -1,7 +0,0 @@ -library; - -pub mod external_submod; - -pub fn external_mod_foo() -> u32 { - 1 -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json deleted file mode 100644 index fe51488c706..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/json_abi_oracle.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml deleted file mode 100644 index bbd562aaba6..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/Forc.toml +++ /dev/null @@ -1,10 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "script" - -[dependencies] -core = { path = "../../../../../../../sway-lib-core" } -std = { path = "../../../../../../../sway-lib-std" } -external_mod = { path = "../external_mod/" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw deleted file mode 100644 index 539970f57cb..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod.sw +++ /dev/null @@ -1,7 +0,0 @@ -library; - -pub mod internal_submod; - -pub fn internal_mod_foo() -> u32 { - 42 -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw deleted file mode 100644 index d7572139f68..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/internal_mod/internal_submod.sw +++ /dev/null @@ -1,7 +0,0 @@ -library; - -use external_mod::{*, external_submod::*}; - -pub fn internal_submod_foo() -> u32 { - 3 -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw deleted file mode 100644 index 2a720b6ba58..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/script/src/main.sw +++ /dev/null @@ -1,23 +0,0 @@ -script; - -mod internal_mod; - -use internal_mod::{*, internal_submod::*}; -use external_mod::{*, external_submod::*}; - -// It should not be possible to import core contents via the standard library. -// It should not be possible to import standard library contents via submodules or external dependencies. - -use std::core::ops::Eq; -use std::hash::core::ops::Add; -use internal_mod::internal_submod::std::hash::core::ops::Subtract; -use external_mod::external_submod::std::core::ops::Multiply; -use internal_mod::internal_submod::external_mod::external_submod::std::core::ops::Divide; -use internal_mod::internal_submod::external_mod::external_submod::ExtSubmodEnum; - -fn main() { - assert(internal_mod_foo() + - internal_submod_foo() + - external_mod_foo() + - external_submod_foo() == 48); -} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml deleted file mode 100644 index e1a83974450..00000000000 --- a/test/src/e2e_vm_tests/test_programs/should_fail/imports_implicitly_public/test.toml +++ /dev/null @@ -1,3 +0,0 @@ -category = "fail" - -# not: $()error From 3eaa7aa0334faa2c3343b93e7bd2d243d13220ed Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Tue, 5 Mar 2024 15:05:34 +0100 Subject: [PATCH 08/11] Add root module name to test --- .../semantic_analysis/ast_node/expression/typed_expression.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 9b941d8787e..b17ea8cb909 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 @@ -2430,7 +2430,9 @@ mod tests { expr: Expression, type_annotation: TypeId, ) -> Result { - let mut namespace = Namespace::init_root(namespace::Module::default()); + let mut root_module = namespace::Module::default(); + root_module.name = Some(Ident::new_no_span("test_lib".to_string())); + let mut namespace = Namespace::init_root(root_module); let ctx = TypeCheckContext::from_namespace(&mut namespace, engines) .with_type_annotation(type_annotation); ty::TyExpression::type_check(handler, ctx, expr) From 9698e8a5048a07de928305b818a39f550f27650e Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Tue, 5 Mar 2024 16:47:42 +0100 Subject: [PATCH 09/11] Fix naming of root module in tests --- .../ast_node/expression/typed_expression.rs | 1 - test/src/ir_generation/mod.rs | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) 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 b17ea8cb909..a3d56a57e31 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 @@ -2431,7 +2431,6 @@ mod tests { type_annotation: TypeId, ) -> Result { let mut root_module = namespace::Module::default(); - root_module.name = Some(Ident::new_no_span("test_lib".to_string())); let mut namespace = Namespace::init_root(root_module); let ctx = TypeCheckContext::from_namespace(&mut namespace, engines) .with_type_annotation(type_annotation); diff --git a/test/src/ir_generation/mod.rs b/test/src/ir_generation/mod.rs index abdd18eb92c..fdfbccf041a 100644 --- a/test/src/ir_generation/mod.rs +++ b/test/src/ir_generation/mod.rs @@ -171,7 +171,12 @@ pub(super) async fn run( // Compile core library and reuse it when compiling tests. let engines = Engines::default(); let build_target = BuildTarget::default(); - let core_lib = compile_core(build_target, &engines); + let mut core_lib = compile_core(build_target, &engines); + // Create new initial namespace for every test by reusing the precompiled + // standard libraries. The namespace, thus its root module, must have the + // name set. + const PACKAGE_NAME: &str = "test_lib"; + core_lib.name = Some(sway_types::Ident::new_no_span(PACKAGE_NAME.to_string())); // Find all the tests. let all_tests = discover_test_files(); @@ -226,12 +231,6 @@ pub(super) async fn run( let sway_str = String::from_utf8_lossy(&sway_str); let handler = Handler::default(); - // Create new initial namespace for every test by reusing the precompiled - // standard libraries. The namespace, thus its root module, must have the - // name set. - const PACKAGE_NAME: &str = "test_lib"; - let mut clone_core_lib = core_lib.clone(); - clone_core_lib.name = Some(sway_types::Ident::new_no_span(PACKAGE_NAME.to_string())); let initial_namespace = namespace::Root::from(core_lib.clone()); let compile_res = compile_to_ast( &handler, From e0d6e1908430d2f21819690071c1d4db8e68ec9a Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Tue, 5 Mar 2024 17:32:58 +0100 Subject: [PATCH 10/11] Fix tests --- sway-core/src/ir_generation/const_eval.rs | 4 ++-- .../semantic_analysis/ast_node/expression/typed_expression.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index d0f08a8e8d0..3de44cf2d39 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -1180,12 +1180,12 @@ mod tests { let handler = Handler::default(); let mut context = Context::new(engines.se(), sway_ir::ExperimentalFlags::default()); let mut md_mgr = MetadataManager::default(); - let core_lib = namespace::Module { + let core_lib = namespace::Root::from(namespace::Module { name: Some(sway_types::Ident::new_no_span( "assert_is_constant_test".to_string(), )), ..Default::default() - }; + }); let r = crate::compile_to_ast( &handler, 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 a3d56a57e31..9fd0bb025a2 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 @@ -2430,7 +2430,7 @@ mod tests { expr: Expression, type_annotation: TypeId, ) -> Result { - let mut root_module = namespace::Module::default(); + let mut root_module = namespace::Root::from(namespace::Module::default()); let mut namespace = Namespace::init_root(root_module); let ctx = TypeCheckContext::from_namespace(&mut namespace, engines) .with_type_annotation(type_annotation); From 95707164211b9b28c08e03bbdb186bf8a88a03cf Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Tue, 5 Mar 2024 17:45:41 +0100 Subject: [PATCH 11/11] Remove unnecessary mut --- .../semantic_analysis/ast_node/expression/typed_expression.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9fd0bb025a2..d3901867fb6 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 @@ -2430,7 +2430,7 @@ mod tests { expr: Expression, type_annotation: TypeId, ) -> Result { - let mut root_module = namespace::Root::from(namespace::Module::default()); + let root_module = namespace::Root::from(namespace::Module::default()); let mut namespace = Namespace::init_root(root_module); let ctx = TypeCheckContext::from_namespace(&mut namespace, engines) .with_type_annotation(type_annotation);