From 5a30643ee58333664cfc2e6f492e68cdac0ad3f3 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Wed, 22 May 2024 05:45:23 +0200 Subject: [PATCH 01/11] Activate failing test, add first fix --- sway-core/src/semantic_analysis/namespace/namespace.rs | 3 ++- .../language/shadowing/shadowed_glob_imports/test.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index fdb6b910ad7..cc66caa94a6 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -268,6 +268,7 @@ impl Namespace { module_span: Span, ) -> SubmoduleNamespace { let init = self.init.clone(); + let is_external = self.module(engines).is_external; self.module_mut(engines) .submodules .entry(mod_name.to_string()) @@ -284,7 +285,7 @@ impl Namespace { new_module.name = Some(mod_name); new_module.span = Some(module_span); new_module.visibility = visibility; - new_module.is_external = false; + new_module.is_external = is_external; new_module.mod_path = submod_path; SubmoduleNamespace { namespace: self, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/shadowing/shadowed_glob_imports/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/shadowing/shadowed_glob_imports/test.toml index edf3a3eae21..75b5f2ef5a2 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/shadowing/shadowed_glob_imports/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/shadowing/shadowed_glob_imports/test.toml @@ -1,2 +1,2 @@ -category = "disabled" +category = "compile" expected_warnings = 27 From 670d7b95506278dbced0cbdab0cd7653d12cdc74 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Fri, 31 May 2024 22:37:08 +0200 Subject: [PATCH 02/11] Fix issue 5500 --- .../ast_node/declaration/struct.rs | 10 +++++-- .../callpath_local_shadowing/Forc.toml | 9 +++++++ .../json_abi_oracle.json | 26 +++++++++++++++++++ .../json_abi_oracle_new_encoding.json | 26 +++++++++++++++++++ .../callpath_local_shadowing/src/lib.sw | 5 ++++ .../callpath_local_shadowing/src/main.sw | 17 ++++++++++++ 6 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle_new_encoding.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/lib.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/main.sw diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index 361ac944ea9..ed40a478644 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -37,8 +37,14 @@ impl ty::TyStructDecl { new_fields.push(ty::TyStructField::type_check(handler, ctx.by_ref(), field)?); } - let mut path: CallPath = name.into(); - path = path.to_fullpath(ctx.engines(), ctx.namespace()); + let mut path: CallPath = name.clone().into(); + if let Some(ref pkg_name) = ctx.namespace().root_module().name { + path.prefixes.push(pkg_name.clone()); + }; + for mod_path in ctx.namespace().mod_path() { + path.prefixes.push(mod_path.clone()) + }; + path.is_absolute = true; // create the struct decl let decl = ty::TyStructDecl { diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.toml new file mode 100644 index 00000000000..22da11cfbac --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "callpath_local_shadowing" +entry = "main.sw" +implicit-std = false + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle.json new file mode 100644 index 00000000000..e60dda965d4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle.json @@ -0,0 +1,26 @@ +{ + "configurables": [], + "encoding": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": { + "name": "", + "type": 0, + "typeArguments": null + } + } + ], + "loggedTypes": [], + "messagesTypes": [], + "types": [ + { + "components": [], + "type": "()", + "typeId": 0, + "typeParameters": null + } + ] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle_new_encoding.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle_new_encoding.json new file mode 100644 index 00000000000..e60dda965d4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/json_abi_oracle_new_encoding.json @@ -0,0 +1,26 @@ +{ + "configurables": [], + "encoding": "1", + "functions": [ + { + "attributes": null, + "inputs": [], + "name": "main", + "output": { + "name": "", + "type": 0, + "typeArguments": null + } + } + ], + "loggedTypes": [], + "messagesTypes": [], + "types": [ + { + "components": [], + "type": "()", + "typeId": 0, + "typeParameters": null + } + ] +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/lib.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/lib.sw new file mode 100644 index 00000000000..28a98821301 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/lib.sw @@ -0,0 +1,5 @@ +library; + +pub struct TestStruct { + pub a: u64, +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/main.sw new file mode 100644 index 00000000000..f74a1a7a446 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/src/main.sw @@ -0,0 +1,17 @@ +script; + +mod lib; + +use lib::*; + +struct TestStruct { + pub x: u64, + pub y: u64, +} + +fn main() { + let ts = TestStruct { x: 0, y: 0 }; + poke(ts.x); +} + +fn poke(_x: T) { } From 396d3385b9346ab8cebfe31470145bed894397e1 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Mon, 3 Jun 2024 14:02:37 +0200 Subject: [PATCH 03/11] Merge conflict --- .../namespace/lexical_scope.rs | 141 +++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index 4e471633fd0..915b0b94751 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -35,7 +35,146 @@ impl ResolvedFunctionDecl { } } -pub(super) type SymbolMap = im::OrdMap; +/// Scoped trait maps. +/// +/// These are used to distinguish between trait maps imported using star imports (`use a::*`), trait +/// maps imported using item imports (`use a::X`), and locally declared trait maps, since the latter +/// two may shadow the first. +#[derive(Clone, Debug, Default)] +pub(crate) struct ScopedTraitMaps { + pub(crate) local_decls: TraitMap, + pub(crate) item_imports: TraitMap, + pub(crate) glob_imports: TraitMap, +} + +impl ScopedTraitMaps { + pub fn get_items_for_type(&self, engines: &Engines, type_id: TypeId) -> Vec { + let item_imports = self.item_imports.get_items_for_type(engines, type_id); + let decls_and_item_imports = self.local_decls.get_items_for_type(engines, type_id) + .extend_from_slice(item_imports.as_slice()); + if !decls_and_item_imports.is_empty() { + decls_and_item_imports + } + else { + self.glob_imports.get_items_for_type(engines, type_id) + } + } + + pub fn get_impl_spans_for_type(&self, engines: &Engines, type_id: &TypeId) -> Vec { + let item_imports = self.item_imports.get_impl_spans_for_type(engines, type_id); + let decls_and_item_imports = self.local_decls.get_impl_spans_for_type(engines, type_id) + .extend_from_slice(item_imports.as_slice()); + if !decls_and_item_imports.is_empty() { + decls_and_item_imports + } + else { + self.glob_imports.get_impl_spans_for_type(engines, type_id) + } + } + + pub fn get_impl_spans_for_trait_name(&self, engines: &Engines, trait_name: &CallPath) -> Vec { + let item_imports = self.item_imports.get_impl_spans_for_trait_name(engines, trait_name); + let decls_and_item_imports = self.local_decls.get_impl_spans_for_trait_name(engines, trait_name) + .extend_from_slice(item_imports.as_slice()); + if !decls_and_item_imports.is_empty() { + decls_and_item_imports + } + else { + self.glob_imports.get_impl_spans_for_trait_name(engines, trait_name) + } + } + + pub fn get_trait_item_for_type(&self, handler: &Handler, engines: &Engines, symbol: &Ident, type_id: TypeId, as_trait: Option) -> Result { + let local_decl_candidates = self.local_decls.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); + let item_import_candidates = self.item_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); + let total_local_and_item_import_candidates = local_decl_candidates.len() + item_import_candidates.len(); + if total_local_and_item_import_candidates > 1 { + Err(handler.emit_err( + CompileError::MultipleApplicableItemsInScope { + item_name: symbol.as_str().to_string(), + item_kind: "item".to_string(), + type_name: engines.help_out(type_id).to_string(), + as_traits: local_decl_candidates + .keys() + .map(|k| { + k.clone() + .split("::") + .collect::>() + .last() + .unwrap() + .to_string() + }) + .collect::>() + .extend( + item_import_candidates + .keys() + .map(|k| { + k.clone() + .split("::") + .collect::>() + .last() + .unwrap() + .to_string() + })), + span: symbol.span(), + }, + )) + } + else if total_local_and_item_import_candidates == 1 { + if local_decl_candidates == 1 { + Ok(local_decl_candidates.values().next().unwrap().clone()) + } else { + Ok(item_import_candidates.values().next().unwrap().clone()) + } + } + else { + // No local or item imported candidates. Check the star imported candidates + let glob_import_candidates = self.glob_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); + if glob_import_candidates.len() > 1 { + Err(handler.emit_err( + CompileError::MultipleApplicableItemsInScope { + item_name: symbol.as_str().to_string(), + item_kind: "item".to_string(), + type_name: engines.help_out(type_id).to_string(), + as_traits: glob_import_candidates + .keys() + .map(|k| { + k.clone() + .split("::") + .collect::>() + .last() + .unwrap() + .to_string() + }) + .collect::>(), + span: symbol.span(), + }, + )) + } + else if glob_import_candidates.len() == 1 { + Ok(glob_import_candidates.values().next().unwrap().clone()) + } + else { + // No candidates found + Err(handler.emit_err(CompileError::SymbolNotFound { + name: symbol.clone(), + span: symbol.span(), + })) + } + } + } + + pub fn check_if_trait_constraints_are_satisfied_for_type(handler: &Handler, implementing_for: TypeId, trait_supertraits: &[TraitConstraint], access_span: &Span, engines: &Engines, try_inserting_trait_impl_on_failure: TryInsertingTraitImplOnFailure) -> Result<(), ErrorEmitted> { + + + } + + + // TODO: Error handling wrt. insertion should also happen here. +} + +pub(super) type ParsedSymbolMap = im::OrdMap; +pub(super) type SymbolMap = im::OrdMap; type SourceIdent = Ident; pub(super) type GlobSynonyms = im::HashMap>; pub(super) type ItemSynonyms = im::HashMap, ModulePathBuf, ty::TyDecl)>; From f764499aa09fe799674f440c0d32e3927d23977c Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Mon, 3 Jun 2024 14:28:33 +0200 Subject: [PATCH 04/11] revert merge fix --- .../namespace/lexical_scope.rs | 141 +----------------- 1 file changed, 1 insertion(+), 140 deletions(-) diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index 915b0b94751..4e471633fd0 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -35,146 +35,7 @@ impl ResolvedFunctionDecl { } } -/// Scoped trait maps. -/// -/// These are used to distinguish between trait maps imported using star imports (`use a::*`), trait -/// maps imported using item imports (`use a::X`), and locally declared trait maps, since the latter -/// two may shadow the first. -#[derive(Clone, Debug, Default)] -pub(crate) struct ScopedTraitMaps { - pub(crate) local_decls: TraitMap, - pub(crate) item_imports: TraitMap, - pub(crate) glob_imports: TraitMap, -} - -impl ScopedTraitMaps { - pub fn get_items_for_type(&self, engines: &Engines, type_id: TypeId) -> Vec { - let item_imports = self.item_imports.get_items_for_type(engines, type_id); - let decls_and_item_imports = self.local_decls.get_items_for_type(engines, type_id) - .extend_from_slice(item_imports.as_slice()); - if !decls_and_item_imports.is_empty() { - decls_and_item_imports - } - else { - self.glob_imports.get_items_for_type(engines, type_id) - } - } - - pub fn get_impl_spans_for_type(&self, engines: &Engines, type_id: &TypeId) -> Vec { - let item_imports = self.item_imports.get_impl_spans_for_type(engines, type_id); - let decls_and_item_imports = self.local_decls.get_impl_spans_for_type(engines, type_id) - .extend_from_slice(item_imports.as_slice()); - if !decls_and_item_imports.is_empty() { - decls_and_item_imports - } - else { - self.glob_imports.get_impl_spans_for_type(engines, type_id) - } - } - - pub fn get_impl_spans_for_trait_name(&self, engines: &Engines, trait_name: &CallPath) -> Vec { - let item_imports = self.item_imports.get_impl_spans_for_trait_name(engines, trait_name); - let decls_and_item_imports = self.local_decls.get_impl_spans_for_trait_name(engines, trait_name) - .extend_from_slice(item_imports.as_slice()); - if !decls_and_item_imports.is_empty() { - decls_and_item_imports - } - else { - self.glob_imports.get_impl_spans_for_trait_name(engines, trait_name) - } - } - - pub fn get_trait_item_for_type(&self, handler: &Handler, engines: &Engines, symbol: &Ident, type_id: TypeId, as_trait: Option) -> Result { - let local_decl_candidates = self.local_decls.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); - let item_import_candidates = self.item_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); - let total_local_and_item_import_candidates = local_decl_candidates.len() + item_import_candidates.len(); - if total_local_and_item_import_candidates > 1 { - Err(handler.emit_err( - CompileError::MultipleApplicableItemsInScope { - item_name: symbol.as_str().to_string(), - item_kind: "item".to_string(), - type_name: engines.help_out(type_id).to_string(), - as_traits: local_decl_candidates - .keys() - .map(|k| { - k.clone() - .split("::") - .collect::>() - .last() - .unwrap() - .to_string() - }) - .collect::>() - .extend( - item_import_candidates - .keys() - .map(|k| { - k.clone() - .split("::") - .collect::>() - .last() - .unwrap() - .to_string() - })), - span: symbol.span(), - }, - )) - } - else if total_local_and_item_import_candidates == 1 { - if local_decl_candidates == 1 { - Ok(local_decl_candidates.values().next().unwrap().clone()) - } else { - Ok(item_import_candidates.values().next().unwrap().clone()) - } - } - else { - // No local or item imported candidates. Check the star imported candidates - let glob_import_candidates = self.glob_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); - if glob_import_candidates.len() > 1 { - Err(handler.emit_err( - CompileError::MultipleApplicableItemsInScope { - item_name: symbol.as_str().to_string(), - item_kind: "item".to_string(), - type_name: engines.help_out(type_id).to_string(), - as_traits: glob_import_candidates - .keys() - .map(|k| { - k.clone() - .split("::") - .collect::>() - .last() - .unwrap() - .to_string() - }) - .collect::>(), - span: symbol.span(), - }, - )) - } - else if glob_import_candidates.len() == 1 { - Ok(glob_import_candidates.values().next().unwrap().clone()) - } - else { - // No candidates found - Err(handler.emit_err(CompileError::SymbolNotFound { - name: symbol.clone(), - span: symbol.span(), - })) - } - } - } - - pub fn check_if_trait_constraints_are_satisfied_for_type(handler: &Handler, implementing_for: TypeId, trait_supertraits: &[TraitConstraint], access_span: &Span, engines: &Engines, try_inserting_trait_impl_on_failure: TryInsertingTraitImplOnFailure) -> Result<(), ErrorEmitted> { - - - } - - - // TODO: Error handling wrt. insertion should also happen here. -} - -pub(super) type ParsedSymbolMap = im::OrdMap; -pub(super) type SymbolMap = im::OrdMap; +pub(super) type SymbolMap = im::OrdMap; type SourceIdent = Ident; pub(super) type GlobSynonyms = im::HashMap>; pub(super) type ItemSynonyms = im::HashMap, ModulePathBuf, ty::TyDecl)>; From 5070835c10e21e91651c89b8f1ec496a97a2b9d0 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Thu, 6 Jun 2024 00:14:21 +0200 Subject: [PATCH 05/11] Fixed callpaths and is_external flag on modules --- forc-pkg/src/pkg.rs | 14 +- sway-core/src/language/call_path.rs | 38 ++++- .../ast_node/declaration/abi.rs | 2 +- .../ast_node/declaration/auto_impl.rs | 8 +- .../ast_node/declaration/impl_trait.rs | 7 +- .../ast_node/declaration/struct.rs | 32 +++- .../ast_node/declaration/trait.rs | 12 +- .../typed_expression/struct_field_access.rs | 9 ++ sway-core/src/semantic_analysis/module.rs | 1 + .../namespace/contract_helpers.rs | 1 - .../namespace/lexical_scope.rs | 138 ++++++++++++++++++ .../semantic_analysis/namespace/namespace.rs | 65 ++++++++- .../src/semantic_analysis/namespace/root.rs | 7 +- .../semantic_analysis/namespace/trait_map.rs | 4 + .../semantic_analysis/type_check_context.rs | 8 + 15 files changed, 307 insertions(+), 39 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 2c24049acb5..ac9dedabe6b 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1595,7 +1595,7 @@ pub fn dependency_namespace( }; root_module.write(engines, |root_module| { - root_module.is_external = true; +// root_module.is_external = true; root_module.name.clone_from(&name); root_module.visibility = Visibility::Public; }); @@ -1606,7 +1606,7 @@ pub fn dependency_namespace( let dep_node = edge.target(); let dep_name = kebab_to_snake_case(&edge.weight().name); let dep_edge = edge.weight(); - let dep_namespace = match dep_edge.kind { + let mut dep_namespace = match dep_edge.kind { DepKind::Library => lib_namespace_map .get(&dep_node) .cloned() @@ -1628,12 +1628,12 @@ pub fn dependency_namespace( contract_id_value, experimental, )?; - module.is_external = true; module.name = name; module.visibility = Visibility::Public; module } }; + dep_namespace.is_external = true; root_module.insert_submodule(dep_name, dep_namespace); let dep = &graph[dep_node]; if dep.name == CORE { @@ -1648,7 +1648,7 @@ pub fn dependency_namespace( root_module.insert_submodule(CORE.to_string(), core_namespace.clone()); } } - + let mut root = namespace::Root::from(root_module); let _ = root.star_import_with_reexports( @@ -2350,6 +2350,8 @@ pub fn build( Err(errs) => return fail(&[], &errs), }; +// dep_namespace.set_external(false); + let compiled_without_tests = compile( &descriptor, &profile, @@ -2423,6 +2425,8 @@ pub fn build( } }; +// dep_namespace.set_external(false); + let mut compiled = compile( &descriptor, &profile, @@ -2647,6 +2651,8 @@ pub fn check( ) .expect("failed to create dependency namespace"); +// dep_namespace.set_external(false); + let profile = BuildProfile { terse: terse_mode, ..BuildProfile::debug() diff --git a/sway-core/src/language/call_path.rs b/sway-core/src/language/call_path.rs index 52a8e41a04b..be44c62a707 100644 --- a/sway-core/src/language/call_path.rs +++ b/sway-core/src/language/call_path.rs @@ -329,6 +329,18 @@ impl CallPath { .collect::>() } + pub fn ident_to_fullpath(suffix: Ident, namespace: &Namespace) -> CallPath { + let mut res : Self = suffix.clone().into(); + if let Some(ref pkg_name) = namespace.root_module().name { + res.prefixes.push(pkg_name.clone()) + }; + for mod_path in namespace.mod_path() { + res.prefixes.push(mod_path.clone()) + }; + res.is_absolute = true; + res + } + /// Convert a given [CallPath] to a symbol to a full [CallPath] from the root of the project /// in which the symbol is declared. For example, given a path `pkga::SOME_CONST` where `pkga` /// is an _internal_ library of a package named `my_project`, the corresponding call path is @@ -341,7 +353,12 @@ impl CallPath { return self.clone(); } - if self.prefixes.is_empty() { +// let problem = self.suffix.as_str() == "AbiEncode"; +// if problem { +// println!("namespace mod_path: \"{}\"", namespace.mod_path.iter().map(|x| x.as_str()).collect::>().join("::")); +// } + + if self.prefixes.is_empty() { // Given a path to a symbol that has no prefixes, discover the path to the symbol as a // combination of the package name in which the symbol is defined and the path to the // current submodule. @@ -350,12 +367,17 @@ impl CallPath { let mut is_absolute = false; if let Some(mod_path) = namespace.program_id(engines).read(engines, |m| { - if let Some((_, path, _)) = m + if m.current_items().symbols().contains_key(&self.suffix) { +// if problem { println!("No prefix, local binding"); }; + None + } + else if let Some((_, path, _)) = m .current_items() .use_item_synonyms .get(&self.suffix) .cloned() { +// if problem { println!("No prefix, item import, path: {}", path.iter().map(|x| x.as_str()).collect::>().join("::")); }; Some(path) } else if let Some(paths_and_decls) = m .current_items() @@ -364,11 +386,14 @@ impl CallPath { .cloned() { if paths_and_decls.len() == 1 { +// if problem { println!("No prefix, glob import, path: {}", paths_and_decls[0].0.iter().map(|x| x.as_str()).collect::>().join("::")); }; Some(paths_and_decls[0].0.clone()) } else { +// if problem { println!("No prefix, non-one glob imports"); }; None } } else { +// if problem { println!("No prefix, no binding"); }; None } }) { @@ -379,7 +404,12 @@ impl CallPath { .submodule(engines, &[mod_path[0].clone()]); if let Some(submodule) = submodule { is_external = submodule.read(engines, |m| m.is_external); +// println!("Found submodule. is_external = {}", is_external); } +// else { +// println!("No submodule found."); +// } +// if problem { println!("is_external: {}", is_external); }; } let mut prefixes: Vec = vec![]; @@ -398,6 +428,10 @@ impl CallPath { prefixes.extend(synonym_prefixes); +// if problem { +// println!("final prefix: {}", prefixes.iter().map(|x| x.as_str()).collect::>().join("::")); +// }; + CallPath { prefixes, suffix: self.suffix.clone(), diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs index eee87c346ad..f6c1cc1e0d1 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs @@ -375,7 +375,7 @@ impl ty::TyAbiDecl { // from the same ABI later, during method application typechecking. let _ = ctx.insert_trait_implementation( &Handler::default(), - CallPath::from(self.name.clone()), + CallPath::ident_to_fullpath(self.name.clone(), ctx.namespace()), vec![], type_id, &all_items, 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 d15c7fd182f..588ccba3333 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 @@ -377,11 +377,13 @@ where assert!(!handler.has_errors(), "{:?}", handler); let ctx = self.ctx.by_ref(); - let (decl, namespace) = ctx + let tmp = ctx .scoped_and_namespace(|ctx| { TyDecl::type_check(&handler, ctx, Declaration::ImplTrait(decl)) - }) - .unwrap(); + }); + + println!("{:#?}", handler); + let (decl, namespace) = tmp.unwrap(); // Uncomment this to understand why auto impl failed for a type. // println!("{:#?}", handler); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 23072debd37..f64b3d5e5fd 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -305,17 +305,14 @@ impl TyImplTrait { let self_type_id = self_type_param.type_id; // create the trait name - let trait_name = CallPath { - prefixes: vec![], - suffix: match &&*type_engine.get(implementing_for.type_id) { + let suffix = match &&*type_engine.get(implementing_for.type_id) { TypeInfo::Custom { qualified_call_path: call_path, .. } => call_path.call_path.suffix.clone(), _ => Ident::new_with_override("r#Self".into(), implementing_for.span()), - }, - is_absolute: false, }; + let trait_name = CallPath::ident_to_fullpath(suffix, ctx.namespace()); // Type check the type parameters. let new_impl_type_parameters = TypeParameter::type_check_type_params( diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index ed40a478644..45689777a75 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -37,15 +37,31 @@ impl ty::TyStructDecl { new_fields.push(ty::TyStructField::type_check(handler, ctx.by_ref(), field)?); } - let mut path: CallPath = name.clone().into(); - if let Some(ref pkg_name) = ctx.namespace().root_module().name { - path.prefixes.push(pkg_name.clone()); - }; - for mod_path in ctx.namespace().mod_path() { - path.prefixes.push(mod_path.clone()) - }; - path.is_absolute = true; + + +// let mut path: CallPath = name.clone().into(); +// //path = path.to_fullpath(ctx.engines, ctx.namespace()); +// // if !ctx.namespace().module(ctx.engines).is_external { +// if let Some(ref pkg_name) = ctx.namespace().root_module().name { +// path.prefixes.push(pkg_name.clone()); +// }; +// // }; +// for mod_path in ctx.namespace().mod_path() { +// path.prefixes.push(mod_path.clone()) +// }; +// path.is_absolute = true; +// +// // if name.as_str() == "BufferReader" +// // || name.as_str() == "TestStruct" +// // { +// // dbg!(&name); +// // dbg!(&path.prefixes); +// // dbg!(&span); +// // }; + + let path = CallPath::ident_to_fullpath(name, ctx.namespace()); + // create the struct decl let decl = ty::TyStructDecl { call_path: path, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index d5b3606f532..9c73f333695 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -112,11 +112,7 @@ impl TyTraitDecl { // to allow methods to use those functions ctx.insert_trait_implementation( handler, - CallPath { - prefixes: vec![], - suffix: name.clone(), - is_absolute: false, - }, + CallPath::ident_to_fullpath(name.clone(), ctx.namespace), new_type_parameters.iter().map(|x| x.into()).collect(), self_type, &dummy_interface_surface, @@ -180,11 +176,7 @@ impl TyTraitDecl { // to allow methods to use those functions ctx.insert_trait_implementation( handler, - CallPath { - prefixes: vec![], - suffix: name.clone(), - is_absolute: false, - }, + CallPath::ident_to_fullpath(name.clone(), ctx.namespace()), new_type_parameters.iter().map(|x| x.into()).collect(), self_type, &dummy_interface_surface, diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs index a75441d535c..37ffcb21609 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs @@ -69,6 +69,15 @@ pub(crate) fn instantiate_struct_field_access( let field = match decl.find_field(&field_to_access) { Some(field) => { +// if decl.call_path.suffix.as_str() == "TestStruct" { +// dbg!(&field.name); +// dbg!(&decl.call_path.prefixes); +// for field in decl.fields.iter() { +// dbg!(&field.name); +// } +// dbg!(&decl.span.as_str()); +// }; +// if is_public_struct_access && field.is_private() { return Err(handler.emit_err(CompileError::StructFieldIsPrivate { field_name: (&field_to_access).into(), diff --git a/sway-core/src/semantic_analysis/module.rs b/sway-core/src/semantic_analysis/module.rs index f377c9acd95..624ef02e8c7 100644 --- a/sway-core/src/semantic_analysis/module.rs +++ b/sway-core/src/semantic_analysis/module.rs @@ -281,6 +281,7 @@ impl ty::TyModule { .iter() .find(|(submod_name, _submodule)| eval_mod_name == submod_name) .unwrap(); +// println!("Typechecking submodule {}", name.as_str()); Ok(( name.clone(), ty::TySubmodule::type_check( diff --git a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs index 0e11482783a..0b1a5851e0c 100644 --- a/sway-core/src/semantic_analysis/namespace/contract_helpers.rs +++ b/sway-core/src/semantic_analysis/namespace/contract_helpers.rs @@ -99,7 +99,6 @@ fn default_with_contract_id_inner( 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; ns.root.module.visibility = Visibility::Public; let type_check_ctx = TypeCheckContext::from_namespace(&mut ns, engines, experimental); let typed_node = TyAstNode::type_check(handler, type_check_ctx, &ast_node).unwrap(); diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index 4e471633fd0..5acb92b2f2c 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -35,6 +35,144 @@ impl ResolvedFunctionDecl { } } +///// Scoped trait maps. +///// +///// These are used to distinguish between trait maps imported using star imports (`use a::*`), trait +///// maps imported using item imports (`use a::X`), and locally declared trait maps, since the latter +///// two may shadow the first. +//#[derive(Clone, Debug, Default)] +//pub(crate) struct ScopedTraitMaps { +// pub(crate) local_decls: TraitMap, +// pub(crate) item_imports: TraitMap, +// pub(crate) glob_imports: TraitMap, +//} +// +//impl ScopedTraitMaps { +// pub fn get_items_for_type(&self, engines: &Engines, type_id: TypeId) -> Vec { +// let item_imports = self.item_imports.get_items_for_type(engines, type_id); +// let decls_and_item_imports = self.local_decls.get_items_for_type(engines, type_id) +// .extend_from_slice(item_imports.as_slice()); +// if !decls_and_item_imports.is_empty() { +// decls_and_item_imports +// } +// else { +// self.glob_imports.get_items_for_type(engines, type_id) +// } +// } +// +// pub fn get_impl_spans_for_type(&self, engines: &Engines, type_id: &TypeId) -> Vec { +// let item_imports = self.item_imports.get_impl_spans_for_type(engines, type_id); +// let decls_and_item_imports = self.local_decls.get_impl_spans_for_type(engines, type_id) +// .extend_from_slice(item_imports.as_slice()); +// if !decls_and_item_imports.is_empty() { +// decls_and_item_imports +// } +// else { +// self.glob_imports.get_impl_spans_for_type(engines, type_id) +// } +// } +// +// pub fn get_impl_spans_for_trait_name(&self, engines: &Engines, trait_name: &CallPath) -> Vec { +// let item_imports = self.item_imports.get_impl_spans_for_trait_name(engines, trait_name); +// let decls_and_item_imports = self.local_decls.get_impl_spans_for_trait_name(engines, trait_name) +// .extend_from_slice(item_imports.as_slice()); +// if !decls_and_item_imports.is_empty() { +// decls_and_item_imports +// } +// else { +// self.glob_imports.get_impl_spans_for_trait_name(engines, trait_name) +// } +// } +// +// pub fn get_trait_item_for_type(&self, handler: &Handler, engines: &Engines, symbol: &Ident, type_id: TypeId, as_trait: Option) -> Result { +// let local_decl_candidates = self.local_decls.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); +// let item_import_candidates = self.item_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); +// let total_local_and_item_import_candidates = local_decl_candidates.len() + item_import_candidates.len(); +// if total_local_and_item_import_candidates > 1 { +// Err(handler.emit_err( +// CompileError::MultipleApplicableItemsInScope { +// item_name: symbol.as_str().to_string(), +// item_kind: "item".to_string(), +// type_name: engines.help_out(type_id).to_string(), +// as_traits: local_decl_candidates +// .keys() +// .map(|k| { +// k.clone() +// .split("::") +// .collect::>() +// .last() +// .unwrap() +// .to_string() +// }) +// .collect::>() +// .extend( +// item_import_candidates +// .keys() +// .map(|k| { +// k.clone() +// .split("::") +// .collect::>() +// .last() +// .unwrap() +// .to_string() +// })), +// span: symbol.span(), +// }, +// )) +// } +// else if total_local_and_item_import_candidates == 1 { +// if local_decl_candidates == 1 { +// Ok(local_decl_candidates.values().next().unwrap().clone()) +// } else { +// Ok(item_import_candidates.values().next().unwrap().clone()) +// } +// } +// else { +// // No local or item imported candidates. Check the star imported candidates +// let glob_import_candidates = self.glob_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); +// if glob_import_candidates.len() > 1 { +// Err(handler.emit_err( +// CompileError::MultipleApplicableItemsInScope { +// item_name: symbol.as_str().to_string(), +// item_kind: "item".to_string(), +// type_name: engines.help_out(type_id).to_string(), +// as_traits: glob_import_candidates +// .keys() +// .map(|k| { +// k.clone() +// .split("::") +// .collect::>() +// .last() +// .unwrap() +// .to_string() +// }) +// .collect::>(), +// span: symbol.span(), +// }, +// )) +// } +// else if glob_import_candidates.len() == 1 { +// Ok(glob_import_candidates.values().next().unwrap().clone()) +// } +// else { +// // No candidates found +// Err(handler.emit_err(CompileError::SymbolNotFound { +// name: symbol.clone(), +// span: symbol.span(), +// })) +// } +// } +// } +// +// pub fn check_if_trait_constraints_are_satisfied_for_type(handler: &Handler, implementing_for: TypeId, trait_supertraits: &[TraitConstraint], access_span: &Span, engines: &Engines, try_inserting_trait_impl_on_failure: TryInsertingTraitImplOnFailure) -> Result<(), ErrorEmitted> { +// +// +// } +// +// +// // TODO: Error handling wrt. insertion should also happen here. +//} + pub(super) type SymbolMap = im::OrdMap; type SourceIdent = Ident; pub(super) type GlobSynonyms = im::HashMap>; diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index bceff86690a..3baa3c599d3 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -8,11 +8,13 @@ use super::{ root::{ResolvedDeclaration, Root}, submodule_namespace::SubmoduleNamespace, trait_map::ResolvedTraitImplItem, - ModulePath, ModulePathBuf, + ModuleName, ModulePath, ModulePathBuf, }; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::span::Span; +use rustc_hash::FxHasher; +use std::hash::BuildHasherDefault; /// Enum used to pass a value asking for insertion of type into trait map when an implementation /// of the trait cannot be found. @@ -55,11 +57,46 @@ 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 { + assert!(!root.module.is_external, "The root module must not be external during compilation"); let mod_path = vec![]; + + // A copy of the root module is used to initialize every new submodule in the program. + // + // 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); + }; +// println!("Setting submodule {} with path {} to external", if let Some(ref name) = module.name { name.as_str() } else { "" } , module.mod_path.iter().map(|x| x.as_str()).collect::>().join("::")); + Module { + submodules: new_submods, + lexical_scopes: module.lexical_scopes.clone(), + current_lexical_scope_id: module.current_lexical_scope_id.clone(), + name: module.name.clone(), + visibility: module.visibility.clone(), + span: module.span.clone(), + is_external: true, + mod_path: module.mod_path.clone(), + } + } + + let mut init = clone_with_submodules_external(&root.module); + // The init module itself is not external + init.is_external = false; +// println!("init module name: {}", if let Some(ref name) = init.name { name.as_str() } else { "" }); +// println!("init submodules:"); +// for (submod_name, submod) in init.submodules.iter() { +// println!("- {}: is_external = {}", submod_name.as_str(), submod.is_external); +// } + Self { - init: root.module.clone(), - root, + init: init.clone(), + root: Root { module: init }, mod_path, } } @@ -267,6 +304,21 @@ impl Namespace { visibility: Visibility, module_span: Span, ) -> SubmoduleNamespace { +// let module = self.module(engines); +// println!("Module name {}", if let Some(ref mod_name) = module.name { mod_name.as_str() } else { "" } ); +// println!("Submodule name {}", mod_name.as_str()); +// println!("Current submodules:"); +// for (submod_name, submod) in module.submodules.iter() { +// println!("- {}: is_external = {}", submod_name.as_str(), submod.is_external); +// if let Some(ref mod_name) = module.name { +// if mod_name.as_str() == "use_absolute_path" && submod_name.as_str() == "core" && !submod.is_external { +// panic!("core is not external for user-defined module"); +// } +// } +// } +// println!("Entering submodule {}", mod_name.as_str()); +// println!("is_external: {}", module.is_external); +// println!(); let init = self.init.clone(); let is_external = self.module(engines).is_external; self.module_mut(engines) @@ -287,6 +339,13 @@ impl Namespace { new_module.visibility = visibility; new_module.is_external = is_external; new_module.mod_path = submod_path; +// println!("New module name {}", if let Some(ref mod_name) = new_module.name { mod_name.as_str() } else { "" } ); +// println!("New module current submodules:"); +// for (submod_name, submod) in new_module.submodules.iter() { +// println!("- {}: is_external = {}", submod_name.as_str(), submod.is_external); +// } +// println!("new_module is_external: {}", new_module.is_external); +// println!(); SubmoduleNamespace { namespace: self, parent_mod_path, diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 3d30f541687..8b64ebfa8a4 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -80,6 +80,10 @@ pub struct Root { } impl Root { +// pub fn set_external(&mut self, is_external: bool) { +// self.module.is_external = is_external +// } + ////// IMPORT ////// /// Given a path to a `src` module, create synonyms to every symbol in that module to the given @@ -98,7 +102,6 @@ impl Root { self.check_module_privacy(handler, engines, src)?; let src_mod = self.module.lookup_submodule(handler, engines, 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() { @@ -117,7 +120,7 @@ impl Root { dst_mod.current_items_mut().insert_glob_use_symbol( engines, symbol.clone(), - src.to_vec(), + src.to_vec(), decl.expect_typed_ref(), ) }); diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index e778acfdf54..52f1b1d28aa 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -310,6 +310,10 @@ impl TraitMap { ) } ); +// if trait_name.suffix.as_str() == "Trait" { +// dbg!(&trait_name); +// dbg!(&trait_name_str); +// }; handler.emit_err(CompileError::ConflictingImplsForTraitAndType { trait_name: trait_name_str, type_implementing_for: engines.help_out(type_id).to_string(), diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index a0692e15b97..27f9b7ace47 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1452,6 +1452,14 @@ impl<'a> TypeCheckContext<'a> { // Use trait name with full path, improves consistency between // this inserting and getting in `get_methods_for_type_and_trait_name`. let full_trait_name = trait_name.to_fullpath(self.engines(), self.namespace()); +// if full_trait_name.suffix.as_str() == "AbiEncode" { +// let name = full_trait_name.suffix.as_str(); +// let dummy = "\n"; +// dbg!(&name); +// dbg!(&trait_name); +// dbg!(&full_trait_name); +// dbg!(&dummy); +// }; let engines = self.engines; let items = items .iter() From 9536b18e408aa193861f0808a97893724cfc096a Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Thu, 6 Jun 2024 00:15:21 +0200 Subject: [PATCH 06/11] Comment out dbg call --- .../semantic_analysis/ast_node/declaration/auto_impl.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 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 588ccba3333..d15c7fd182f 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 @@ -377,13 +377,11 @@ where assert!(!handler.has_errors(), "{:?}", handler); let ctx = self.ctx.by_ref(); - let tmp = ctx + let (decl, namespace) = ctx .scoped_and_namespace(|ctx| { TyDecl::type_check(&handler, ctx, Declaration::ImplTrait(decl)) - }); - - println!("{:#?}", handler); - let (decl, namespace) = tmp.unwrap(); + }) + .unwrap(); // Uncomment this to understand why auto impl failed for a type. // println!("{:#?}", handler); From d507b84c5d718d4229365b0ba7dff4c804e1758a Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Thu, 6 Jun 2024 00:17:56 +0200 Subject: [PATCH 07/11] Fix path issue for enums --- sway-core/src/semantic_analysis/ast_node/declaration/enum.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index 574f14bcaf8..b6e090b39e7 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -42,8 +42,9 @@ impl ty::TyEnumDecl { ); } - let mut call_path: CallPath = name.into(); - call_path = call_path.to_fullpath(ctx.engines(), ctx.namespace()); + let call_path = CallPath::ident_to_fullpath(name, ctx.namespace()); +// let mut call_path: CallPath = name.into(); +// call_path = call_path.to_fullpath(ctx.engines(), ctx.namespace()); // create the enum decl let decl = ty::TyEnumDecl { From a4801609c34f50839e7843da81afc4439c2e6865 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Thu, 6 Jun 2024 13:05:13 +0200 Subject: [PATCH 08/11] Code cleanup --- forc-pkg/src/pkg.rs | 7 - sway-core/src/language/call_path.rs | 24 +-- .../ast_node/declaration/enum.rs | 2 - .../ast_node/declaration/struct.rs | 23 --- .../typed_expression/struct_field_access.rs | 9 -- sway-core/src/semantic_analysis/module.rs | 1 - .../namespace/lexical_scope.rs | 138 ------------------ .../semantic_analysis/namespace/namespace.rs | 28 ---- .../src/semantic_analysis/namespace/root.rs | 4 - .../semantic_analysis/namespace/trait_map.rs | 4 - .../semantic_analysis/type_check_context.rs | 8 - .../callpath_local_shadowing/Forc.lock | 13 ++ .../callpath_local_shadowing/test.toml | 3 + 13 files changed, 21 insertions(+), 243 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/test.toml diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index ac9dedabe6b..ddd82548c0d 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1595,7 +1595,6 @@ pub fn dependency_namespace( }; root_module.write(engines, |root_module| { -// root_module.is_external = true; root_module.name.clone_from(&name); root_module.visibility = Visibility::Public; }); @@ -2350,8 +2349,6 @@ pub fn build( Err(errs) => return fail(&[], &errs), }; -// dep_namespace.set_external(false); - let compiled_without_tests = compile( &descriptor, &profile, @@ -2425,8 +2422,6 @@ pub fn build( } }; -// dep_namespace.set_external(false); - let mut compiled = compile( &descriptor, &profile, @@ -2651,8 +2646,6 @@ pub fn check( ) .expect("failed to create dependency namespace"); -// dep_namespace.set_external(false); - let profile = BuildProfile { terse: terse_mode, ..BuildProfile::debug() diff --git a/sway-core/src/language/call_path.rs b/sway-core/src/language/call_path.rs index be44c62a707..f9816e95ec3 100644 --- a/sway-core/src/language/call_path.rs +++ b/sway-core/src/language/call_path.rs @@ -329,6 +329,11 @@ impl CallPath { .collect::>() } + /// Create a full [CallPath] from aiven an [Ident] and the [Namespace] in which the [Ident] is + /// declared. + /// + /// This function is intended to be used while typechecking the identifier declaration, i.e., + /// before the identifier is added to the environment. pub fn ident_to_fullpath(suffix: Ident, namespace: &Namespace) -> CallPath { let mut res : Self = suffix.clone().into(); if let Some(ref pkg_name) = namespace.root_module().name { @@ -353,11 +358,6 @@ impl CallPath { return self.clone(); } -// let problem = self.suffix.as_str() == "AbiEncode"; -// if problem { -// println!("namespace mod_path: \"{}\"", namespace.mod_path.iter().map(|x| x.as_str()).collect::>().join("::")); -// } - if self.prefixes.is_empty() { // Given a path to a symbol that has no prefixes, discover the path to the symbol as a // combination of the package name in which the symbol is defined and the path to the @@ -368,7 +368,6 @@ impl CallPath { if let Some(mod_path) = namespace.program_id(engines).read(engines, |m| { if m.current_items().symbols().contains_key(&self.suffix) { -// if problem { println!("No prefix, local binding"); }; None } else if let Some((_, path, _)) = m @@ -377,7 +376,6 @@ impl CallPath { .get(&self.suffix) .cloned() { -// if problem { println!("No prefix, item import, path: {}", path.iter().map(|x| x.as_str()).collect::>().join("::")); }; Some(path) } else if let Some(paths_and_decls) = m .current_items() @@ -386,14 +384,11 @@ impl CallPath { .cloned() { if paths_and_decls.len() == 1 { -// if problem { println!("No prefix, glob import, path: {}", paths_and_decls[0].0.iter().map(|x| x.as_str()).collect::>().join("::")); }; Some(paths_and_decls[0].0.clone()) } else { -// if problem { println!("No prefix, non-one glob imports"); }; None } } else { -// if problem { println!("No prefix, no binding"); }; None } }) { @@ -404,12 +399,7 @@ impl CallPath { .submodule(engines, &[mod_path[0].clone()]); if let Some(submodule) = submodule { is_external = submodule.read(engines, |m| m.is_external); -// println!("Found submodule. is_external = {}", is_external); } -// else { -// println!("No submodule found."); -// } -// if problem { println!("is_external: {}", is_external); }; } let mut prefixes: Vec = vec![]; @@ -428,10 +418,6 @@ impl CallPath { prefixes.extend(synonym_prefixes); -// if problem { -// println!("final prefix: {}", prefixes.iter().map(|x| x.as_str()).collect::>().join("::")); -// }; - CallPath { prefixes, suffix: self.suffix.clone(), diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index b6e090b39e7..d4d05280581 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -43,8 +43,6 @@ impl ty::TyEnumDecl { } let call_path = CallPath::ident_to_fullpath(name, ctx.namespace()); -// let mut call_path: CallPath = name.into(); -// call_path = call_path.to_fullpath(ctx.engines(), ctx.namespace()); // create the enum decl let decl = ty::TyEnumDecl { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index 45689777a75..cb53e4eef3d 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -37,29 +37,6 @@ impl ty::TyStructDecl { new_fields.push(ty::TyStructField::type_check(handler, ctx.by_ref(), field)?); } - - - -// let mut path: CallPath = name.clone().into(); -// //path = path.to_fullpath(ctx.engines, ctx.namespace()); -// // if !ctx.namespace().module(ctx.engines).is_external { -// if let Some(ref pkg_name) = ctx.namespace().root_module().name { -// path.prefixes.push(pkg_name.clone()); -// }; -// // }; -// for mod_path in ctx.namespace().mod_path() { -// path.prefixes.push(mod_path.clone()) -// }; -// path.is_absolute = true; -// -// // if name.as_str() == "BufferReader" -// // || name.as_str() == "TestStruct" -// // { -// // dbg!(&name); -// // dbg!(&path.prefixes); -// // dbg!(&span); -// // }; - let path = CallPath::ident_to_fullpath(name, ctx.namespace()); // create the struct decl diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs index 37ffcb21609..a75441d535c 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/struct_field_access.rs @@ -69,15 +69,6 @@ pub(crate) fn instantiate_struct_field_access( let field = match decl.find_field(&field_to_access) { Some(field) => { -// if decl.call_path.suffix.as_str() == "TestStruct" { -// dbg!(&field.name); -// dbg!(&decl.call_path.prefixes); -// for field in decl.fields.iter() { -// dbg!(&field.name); -// } -// dbg!(&decl.span.as_str()); -// }; -// if is_public_struct_access && field.is_private() { return Err(handler.emit_err(CompileError::StructFieldIsPrivate { field_name: (&field_to_access).into(), diff --git a/sway-core/src/semantic_analysis/module.rs b/sway-core/src/semantic_analysis/module.rs index 624ef02e8c7..f377c9acd95 100644 --- a/sway-core/src/semantic_analysis/module.rs +++ b/sway-core/src/semantic_analysis/module.rs @@ -281,7 +281,6 @@ impl ty::TyModule { .iter() .find(|(submod_name, _submodule)| eval_mod_name == submod_name) .unwrap(); -// println!("Typechecking submodule {}", name.as_str()); Ok(( name.clone(), ty::TySubmodule::type_check( diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index 5acb92b2f2c..4e471633fd0 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -35,144 +35,6 @@ impl ResolvedFunctionDecl { } } -///// Scoped trait maps. -///// -///// These are used to distinguish between trait maps imported using star imports (`use a::*`), trait -///// maps imported using item imports (`use a::X`), and locally declared trait maps, since the latter -///// two may shadow the first. -//#[derive(Clone, Debug, Default)] -//pub(crate) struct ScopedTraitMaps { -// pub(crate) local_decls: TraitMap, -// pub(crate) item_imports: TraitMap, -// pub(crate) glob_imports: TraitMap, -//} -// -//impl ScopedTraitMaps { -// pub fn get_items_for_type(&self, engines: &Engines, type_id: TypeId) -> Vec { -// let item_imports = self.item_imports.get_items_for_type(engines, type_id); -// let decls_and_item_imports = self.local_decls.get_items_for_type(engines, type_id) -// .extend_from_slice(item_imports.as_slice()); -// if !decls_and_item_imports.is_empty() { -// decls_and_item_imports -// } -// else { -// self.glob_imports.get_items_for_type(engines, type_id) -// } -// } -// -// pub fn get_impl_spans_for_type(&self, engines: &Engines, type_id: &TypeId) -> Vec { -// let item_imports = self.item_imports.get_impl_spans_for_type(engines, type_id); -// let decls_and_item_imports = self.local_decls.get_impl_spans_for_type(engines, type_id) -// .extend_from_slice(item_imports.as_slice()); -// if !decls_and_item_imports.is_empty() { -// decls_and_item_imports -// } -// else { -// self.glob_imports.get_impl_spans_for_type(engines, type_id) -// } -// } -// -// pub fn get_impl_spans_for_trait_name(&self, engines: &Engines, trait_name: &CallPath) -> Vec { -// let item_imports = self.item_imports.get_impl_spans_for_trait_name(engines, trait_name); -// let decls_and_item_imports = self.local_decls.get_impl_spans_for_trait_name(engines, trait_name) -// .extend_from_slice(item_imports.as_slice()); -// if !decls_and_item_imports.is_empty() { -// decls_and_item_imports -// } -// else { -// self.glob_imports.get_impl_spans_for_trait_name(engines, trait_name) -// } -// } -// -// pub fn get_trait_item_for_type(&self, handler: &Handler, engines: &Engines, symbol: &Ident, type_id: TypeId, as_trait: Option) -> Result { -// let local_decl_candidates = self.local_decls.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); -// let item_import_candidates = self.item_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); -// let total_local_and_item_import_candidates = local_decl_candidates.len() + item_import_candidates.len(); -// if total_local_and_item_import_candidates > 1 { -// Err(handler.emit_err( -// CompileError::MultipleApplicableItemsInScope { -// item_name: symbol.as_str().to_string(), -// item_kind: "item".to_string(), -// type_name: engines.help_out(type_id).to_string(), -// as_traits: local_decl_candidates -// .keys() -// .map(|k| { -// k.clone() -// .split("::") -// .collect::>() -// .last() -// .unwrap() -// .to_string() -// }) -// .collect::>() -// .extend( -// item_import_candidates -// .keys() -// .map(|k| { -// k.clone() -// .split("::") -// .collect::>() -// .last() -// .unwrap() -// .to_string() -// })), -// span: symbol.span(), -// }, -// )) -// } -// else if total_local_and_item_import_candidates == 1 { -// if local_decl_candidates == 1 { -// Ok(local_decl_candidates.values().next().unwrap().clone()) -// } else { -// Ok(item_import_candidates.values().next().unwrap().clone()) -// } -// } -// else { -// // No local or item imported candidates. Check the star imported candidates -// let glob_import_candidates = self.glob_imports.get_trait_item_for_type(handler, engines, symbol, type_id, as_trait); -// if glob_import_candidates.len() > 1 { -// Err(handler.emit_err( -// CompileError::MultipleApplicableItemsInScope { -// item_name: symbol.as_str().to_string(), -// item_kind: "item".to_string(), -// type_name: engines.help_out(type_id).to_string(), -// as_traits: glob_import_candidates -// .keys() -// .map(|k| { -// k.clone() -// .split("::") -// .collect::>() -// .last() -// .unwrap() -// .to_string() -// }) -// .collect::>(), -// span: symbol.span(), -// }, -// )) -// } -// else if glob_import_candidates.len() == 1 { -// Ok(glob_import_candidates.values().next().unwrap().clone()) -// } -// else { -// // No candidates found -// Err(handler.emit_err(CompileError::SymbolNotFound { -// name: symbol.clone(), -// span: symbol.span(), -// })) -// } -// } -// } -// -// pub fn check_if_trait_constraints_are_satisfied_for_type(handler: &Handler, implementing_for: TypeId, trait_supertraits: &[TraitConstraint], access_span: &Span, engines: &Engines, try_inserting_trait_impl_on_failure: TryInsertingTraitImplOnFailure) -> Result<(), ErrorEmitted> { -// -// -// } -// -// -// // TODO: Error handling wrt. insertion should also happen here. -//} - pub(super) type SymbolMap = im::OrdMap; type SourceIdent = Ident; pub(super) type GlobSynonyms = im::HashMap>; diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index 3baa3c599d3..ba588732ad0 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -72,7 +72,6 @@ impl Namespace { let new_submod = clone_with_submodules_external(submod); new_submods.insert(name.clone(), new_submod); }; -// println!("Setting submodule {} with path {} to external", if let Some(ref name) = module.name { name.as_str() } else { "" } , module.mod_path.iter().map(|x| x.as_str()).collect::>().join("::")); Module { submodules: new_submods, lexical_scopes: module.lexical_scopes.clone(), @@ -88,11 +87,6 @@ impl Namespace { let mut init = clone_with_submodules_external(&root.module); // The init module itself is not external init.is_external = false; -// println!("init module name: {}", if let Some(ref name) = init.name { name.as_str() } else { "" }); -// println!("init submodules:"); -// for (submod_name, submod) in init.submodules.iter() { -// println!("- {}: is_external = {}", submod_name.as_str(), submod.is_external); -// } Self { init: init.clone(), @@ -304,21 +298,6 @@ impl Namespace { visibility: Visibility, module_span: Span, ) -> SubmoduleNamespace { -// let module = self.module(engines); -// println!("Module name {}", if let Some(ref mod_name) = module.name { mod_name.as_str() } else { "" } ); -// println!("Submodule name {}", mod_name.as_str()); -// println!("Current submodules:"); -// for (submod_name, submod) in module.submodules.iter() { -// println!("- {}: is_external = {}", submod_name.as_str(), submod.is_external); -// if let Some(ref mod_name) = module.name { -// if mod_name.as_str() == "use_absolute_path" && submod_name.as_str() == "core" && !submod.is_external { -// panic!("core is not external for user-defined module"); -// } -// } -// } -// println!("Entering submodule {}", mod_name.as_str()); -// println!("is_external: {}", module.is_external); -// println!(); let init = self.init.clone(); let is_external = self.module(engines).is_external; self.module_mut(engines) @@ -339,13 +318,6 @@ impl Namespace { new_module.visibility = visibility; new_module.is_external = is_external; new_module.mod_path = submod_path; -// println!("New module name {}", if let Some(ref mod_name) = new_module.name { mod_name.as_str() } else { "" } ); -// println!("New module current submodules:"); -// for (submod_name, submod) in new_module.submodules.iter() { -// println!("- {}: is_external = {}", submod_name.as_str(), submod.is_external); -// } -// println!("new_module is_external: {}", new_module.is_external); -// println!(); SubmoduleNamespace { namespace: self, parent_mod_path, diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 8b64ebfa8a4..a969c1acae2 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -80,10 +80,6 @@ pub struct Root { } impl Root { -// pub fn set_external(&mut self, is_external: bool) { -// self.module.is_external = is_external -// } - ////// IMPORT ////// /// Given a path to a `src` module, create synonyms to every symbol in that module to the given diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 52f1b1d28aa..e778acfdf54 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -310,10 +310,6 @@ impl TraitMap { ) } ); -// if trait_name.suffix.as_str() == "Trait" { -// dbg!(&trait_name); -// dbg!(&trait_name_str); -// }; handler.emit_err(CompileError::ConflictingImplsForTraitAndType { trait_name: trait_name_str, type_implementing_for: engines.help_out(type_id).to_string(), diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 27f9b7ace47..a0692e15b97 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -1452,14 +1452,6 @@ impl<'a> TypeCheckContext<'a> { // Use trait name with full path, improves consistency between // this inserting and getting in `get_methods_for_type_and_trait_name`. let full_trait_name = trait_name.to_fullpath(self.engines(), self.namespace()); -// if full_trait_name.suffix.as_str() == "AbiEncode" { -// let name = full_trait_name.suffix.as_str(); -// let dummy = "\n"; -// dbg!(&name); -// dbg!(&trait_name); -// dbg!(&full_trait_name); -// dbg!(&dummy); -// }; let engines = self.engines; let items = items .iter() diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.lock new file mode 100644 index 00000000000..30883f47562 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "callpath_local_shadowing" +source = "member" +dependencies = ["std"] + +[[package]] +name = "core" +source = "path+from-root-779BB769D43AD4B7" + +[[package]] +name = "std" +source = "path+from-root-779BB769D43AD4B7" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/test.toml new file mode 100644 index 00000000000..23f85066264 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/callpath_local_shadowing/test.toml @@ -0,0 +1,3 @@ +category = "compile" +validate_abi = true +expected_warnings = 2 From 270f04bf7d5daeeef3924801f19d50c9c239c44a Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Thu, 6 Jun 2024 13:08:22 +0200 Subject: [PATCH 09/11] clippy, fmt --- forc-pkg/src/pkg.rs | 4 +- sway-core/src/language/call_path.rs | 29 +++++---- .../ast_node/declaration/enum.rs | 2 +- .../ast_node/declaration/impl_trait.rs | 12 ++-- .../ast_node/declaration/struct.rs | 4 +- .../ast_node/declaration/trait.rs | 2 +- .../semantic_analysis/namespace/namespace.rs | 62 ++++++++++--------- .../src/semantic_analysis/namespace/root.rs | 2 +- 8 files changed, 60 insertions(+), 57 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index ddd82548c0d..d8c2bab4c87 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1632,7 +1632,7 @@ pub fn dependency_namespace( module } }; - dep_namespace.is_external = true; + dep_namespace.is_external = true; root_module.insert_submodule(dep_name, dep_namespace); let dep = &graph[dep_node]; if dep.name == CORE { @@ -1647,7 +1647,7 @@ pub fn dependency_namespace( root_module.insert_submodule(CORE.to_string(), core_namespace.clone()); } } - + let mut root = namespace::Root::from(root_module); let _ = root.star_import_with_reexports( diff --git a/sway-core/src/language/call_path.rs b/sway-core/src/language/call_path.rs index f9816e95ec3..95671ac5722 100644 --- a/sway-core/src/language/call_path.rs +++ b/sway-core/src/language/call_path.rs @@ -335,17 +335,17 @@ impl CallPath { /// This function is intended to be used while typechecking the identifier declaration, i.e., /// before the identifier is added to the environment. pub fn ident_to_fullpath(suffix: Ident, namespace: &Namespace) -> CallPath { - let mut res : Self = suffix.clone().into(); - if let Some(ref pkg_name) = namespace.root_module().name { - res.prefixes.push(pkg_name.clone()) - }; - for mod_path in namespace.mod_path() { - res.prefixes.push(mod_path.clone()) - }; - res.is_absolute = true; - res + let mut res: Self = suffix.clone().into(); + if let Some(ref pkg_name) = namespace.root_module().name { + res.prefixes.push(pkg_name.clone()) + }; + for mod_path in namespace.mod_path() { + res.prefixes.push(mod_path.clone()) + } + res.is_absolute = true; + res } - + /// Convert a given [CallPath] to a symbol to a full [CallPath] from the root of the project /// in which the symbol is declared. For example, given a path `pkga::SOME_CONST` where `pkga` /// is an _internal_ library of a package named `my_project`, the corresponding call path is @@ -358,7 +358,7 @@ impl CallPath { return self.clone(); } - if self.prefixes.is_empty() { + if self.prefixes.is_empty() { // Given a path to a symbol that has no prefixes, discover the path to the symbol as a // combination of the package name in which the symbol is defined and the path to the // current submodule. @@ -367,10 +367,9 @@ impl CallPath { let mut is_absolute = false; if let Some(mod_path) = namespace.program_id(engines).read(engines, |m| { - if m.current_items().symbols().contains_key(&self.suffix) { - None - } - else if let Some((_, path, _)) = m + if m.current_items().symbols().contains_key(&self.suffix) { + None + } else if let Some((_, path, _)) = m .current_items() .use_item_synonyms .get(&self.suffix) diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index d4d05280581..f07975ee2d7 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -42,7 +42,7 @@ impl ty::TyEnumDecl { ); } - let call_path = CallPath::ident_to_fullpath(name, ctx.namespace()); + let call_path = CallPath::ident_to_fullpath(name, ctx.namespace()); // create the enum decl let decl = ty::TyEnumDecl { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index f64b3d5e5fd..1f022a1b15b 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -305,12 +305,12 @@ impl TyImplTrait { let self_type_id = self_type_param.type_id; // create the trait name - let suffix = match &&*type_engine.get(implementing_for.type_id) { - TypeInfo::Custom { - qualified_call_path: call_path, - .. - } => call_path.call_path.suffix.clone(), - _ => Ident::new_with_override("r#Self".into(), implementing_for.span()), + let suffix = match &&*type_engine.get(implementing_for.type_id) { + TypeInfo::Custom { + qualified_call_path: call_path, + .. + } => call_path.call_path.suffix.clone(), + _ => Ident::new_with_override("r#Self".into(), implementing_for.span()), }; let trait_name = CallPath::ident_to_fullpath(suffix, ctx.namespace()); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index cb53e4eef3d..a04efa0f274 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -37,8 +37,8 @@ impl ty::TyStructDecl { new_fields.push(ty::TyStructField::type_check(handler, ctx.by_ref(), field)?); } - let path = CallPath::ident_to_fullpath(name, ctx.namespace()); - + let path = CallPath::ident_to_fullpath(name, ctx.namespace()); + // create the struct decl let decl = ty::TyStructDecl { call_path: path, diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index 9c73f333695..253b67ad5a4 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -112,7 +112,7 @@ impl TyTraitDecl { // to allow methods to use those functions ctx.insert_trait_implementation( handler, - CallPath::ident_to_fullpath(name.clone(), ctx.namespace), + CallPath::ident_to_fullpath(name.clone(), ctx.namespace), new_type_parameters.iter().map(|x| x.into()).collect(), self_type, &dummy_interface_surface, diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index ba588732ad0..0af36824224 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -11,10 +11,10 @@ use super::{ ModuleName, ModulePath, ModulePathBuf, }; -use sway_error::handler::{ErrorEmitted, Handler}; -use sway_types::span::Span; use rustc_hash::FxHasher; use std::hash::BuildHasherDefault; +use sway_error::handler::{ErrorEmitted, Handler}; +use sway_types::span::Span; /// Enum used to pass a value asking for insertion of type into trait map when an implementation /// of the trait cannot be found. @@ -59,34 +59,38 @@ 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 { - assert!(!root.module.is_external, "The root module must not be external during compilation"); + assert!( + !root.module.is_external, + "The root module must not be external during compilation" + ); let mod_path = vec![]; - // A copy of the root module is used to initialize every new submodule in the program. - // - // 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.clone(), - name: module.name.clone(), - visibility: module.visibility.clone(), - span: module.span.clone(), - is_external: true, - mod_path: module.mod_path.clone(), - } - } - - let mut init = clone_with_submodules_external(&root.module); - // The init module itself is not external - init.is_external = false; + // A copy of the root module is used to initialize every new submodule in the program. + // + // 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.clone(), + name: module.name.clone(), + visibility: module.visibility.clone(), + span: module.span.clone(), + is_external: true, + mod_path: module.mod_path.clone(), + } + } + + let mut init = clone_with_submodules_external(&root.module); + // The init module itself is not external + init.is_external = false; Self { init: init.clone(), @@ -299,7 +303,7 @@ impl Namespace { module_span: Span, ) -> SubmoduleNamespace { let init = self.init.clone(); - let is_external = self.module(engines).is_external; + let is_external = self.module(engines).is_external; self.module_mut(engines) .submodules .entry(mod_name.to_string()) diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index a969c1acae2..6008c7144c7 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -116,7 +116,7 @@ impl Root { dst_mod.current_items_mut().insert_glob_use_symbol( engines, symbol.clone(), - src.to_vec(), + src.to_vec(), decl.expect_typed_ref(), ) }); From 322db90442e6846b52a501bce776ad6e8c6b2b03 Mon Sep 17 00:00:00 2001 From: Jacob Johannsen Date: Thu, 6 Jun 2024 14:58:45 +0200 Subject: [PATCH 10/11] clippy --- sway-core/src/semantic_analysis/namespace/namespace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index 0af36824224..cfe52d93d28 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -79,9 +79,9 @@ impl Namespace { Module { submodules: new_submods, lexical_scopes: module.lexical_scopes.clone(), - current_lexical_scope_id: module.current_lexical_scope_id.clone(), + current_lexical_scope_id: module.current_lexical_scope_id, name: module.name.clone(), - visibility: module.visibility.clone(), + visibility: module.visibility, span: module.span.clone(), is_external: true, mod_path: module.mod_path.clone(), From 90a4dfbb9e21258d5e1a672f1077667f8eac3d21 Mon Sep 17 00:00:00 2001 From: jjcnn <38888011+jjcnn@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:23:07 +0200 Subject: [PATCH 11/11] Update sway-core/src/language/call_path.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Matos --- sway-core/src/language/call_path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway-core/src/language/call_path.rs b/sway-core/src/language/call_path.rs index 95671ac5722..d0f993438b8 100644 --- a/sway-core/src/language/call_path.rs +++ b/sway-core/src/language/call_path.rs @@ -329,7 +329,7 @@ impl CallPath { .collect::>() } - /// Create a full [CallPath] from aiven an [Ident] and the [Namespace] in which the [Ident] is + /// Create a full [CallPath] from a given [Ident] and the [Namespace] in which the [Ident] is /// declared. /// /// This function is intended to be used while typechecking the identifier declaration, i.e.,