From 2c8dc647d96d3e989e120d81d67fa3c739fd7066 Mon Sep 17 00:00:00 2001 From: Joao Matos Date: Sun, 4 Aug 2024 23:15:20 +0100 Subject: [PATCH] Resolve alias declarations when resolving struct symbols. --- sway-core/src/language/parsed/declaration.rs | 17 +++++++++++++++++ .../src/language/ty/declaration/declaration.rs | 2 +- .../ast_node/declaration/auto_impl.rs | 2 +- .../match_expression/typed/typed_scrutinee.rs | 2 +- .../ast_node/expression/typed_expression.rs | 2 +- .../src/semantic_analysis/namespace/root.rs | 17 ++++++++++++++++- .../src/type_system/ast_elements/binding.rs | 9 +++++---- .../language/type_alias_basic/Forc.lock | 8 ++++++++ .../language/type_alias_basic/Forc.toml | 6 ++++++ .../language/type_alias_basic/src/main.sw | 4 ++++ .../type_alias_from_dependency/Forc.lock | 8 ++++++++ .../type_alias_from_dependency/Forc.toml | 9 +++++++++ .../type_alias_from_dependency/src/main.sw | 7 +++++++ .../type_alias_from_dependency/test.toml | 3 +++ 14 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/test.toml diff --git a/sway-core/src/language/parsed/declaration.rs b/sway-core/src/language/parsed/declaration.rs index 628fd3078ac..a47c4895c1b 100644 --- a/sway-core/src/language/parsed/declaration.rs +++ b/sway-core/src/language/parsed/declaration.rs @@ -33,6 +33,7 @@ use crate::{ decl_engine::{ parsed_engine::{ParsedDeclEngine, ParsedDeclEngineGet}, parsed_id::ParsedDeclId, + DeclEngineGetParsedDeclId, }, engine_threading::{ DebugWithEngines, DisplayWithEngines, EqWithEngines, PartialEqWithEngines, @@ -142,6 +143,22 @@ impl Declaration { ) -> Result, ErrorEmitted> { match self { Declaration::StructDeclaration(decl_id) => Ok(*decl_id), + Declaration::TypeAliasDeclaration(decl_id) => { + let alias = engines.pe().get_type_alias(decl_id); + let struct_decl_id = engines.te().get(alias.ty.type_id).expect_struct( + handler, + engines, + &self.span(engines), + )?; + + let parsed_decl_id = engines.de().get_parsed_decl_id(&struct_decl_id); + parsed_decl_id.ok_or_else(|| { + handler.emit_err(CompileError::InternalOwned( + "Cannot get parsed decl id from decl id".to_string(), + self.span(engines), + )) + }) + } decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct { actually: decl.friendly_type_name().to_string(), span: decl.span(engines), diff --git a/sway-core/src/language/ty/declaration/declaration.rs b/sway-core/src/language/ty/declaration/declaration.rs index 7cb16bebd5b..61363124c11 100644 --- a/sway-core/src/language/ty/declaration/declaration.rs +++ b/sway-core/src/language/ty/declaration/declaration.rs @@ -555,7 +555,7 @@ impl TyDecl { /// Retrieves the declaration as a `DeclRef>`. /// /// Returns an error if `self` is not the [TyDecl][StructDecl] variant. - pub(crate) fn to_struct_id( + pub(crate) fn to_struct_decl( &self, handler: &Handler, engines: &Engines, 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 2731811f6a7..d495c142fe1 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 @@ -405,7 +405,7 @@ where return Some((None, None)); } - let implementing_for_decl_id = decl.to_struct_id(&Handler::default(), engines).unwrap(); + let implementing_for_decl_id = decl.to_struct_decl(&Handler::default(), engines).unwrap(); let struct_decl = self.ctx.engines().de().get(&implementing_for_decl_id); let program_id = struct_decl.span().source_id().map(|sid| sid.program_id()); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs index 4f726c3b711..12ac36c44a6 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/typed_scrutinee.rs @@ -233,7 +233,7 @@ fn type_check_struct( let unknown_decl = ctx.namespace() .resolve_symbol_typed(handler, engines, &struct_name, ctx.self_type())?; - let struct_id = unknown_decl.to_struct_id(handler, ctx.engines())?; + let struct_id = unknown_decl.to_struct_decl(handler, ctx.engines())?; let mut struct_decl = (*decl_engine.get_struct(&struct_id)).clone(); // monomorphize the struct definition 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 92d768136cc..c0d50699189 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 @@ -1108,7 +1108,7 @@ impl ty::TyExpression { None, )? .expect_typed(); - let storage_key_struct_decl_ref = storage_key_decl_opt.to_struct_id(handler, engines)?; + let storage_key_struct_decl_ref = storage_key_decl_opt.to_struct_decl(handler, engines)?; let mut storage_key_struct_decl = (*decl_engine.get_struct(&storage_key_struct_decl_ref)).clone(); diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 7c238054506..19c50487499 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -8,7 +8,7 @@ use crate::{ engine_threading::*, language::{ parsed::*, - ty::{self, TyDecl, TyTraitItem}, + ty::{self, StructDecl, TyDecl, TyTraitItem}, CallPath, Visibility, }, namespace::{ModulePath, ModulePathBuf}, @@ -99,6 +99,21 @@ impl ResolvedDeclaration { } } + pub(crate) fn to_struct_decl( + &self, + handler: &Handler, + engines: &Engines, + ) -> Result { + match self { + ResolvedDeclaration::Parsed(decl) => decl + .to_struct_decl(handler, engines) + .map(|id| ResolvedDeclaration::Parsed(Declaration::StructDeclaration(id))), + ResolvedDeclaration::Typed(decl) => decl.to_struct_decl(handler, engines).map(|id| { + ResolvedDeclaration::Typed(TyDecl::StructDecl(StructDecl { decl_id: id })) + }), + } + } + pub(crate) fn visibility(&self, engines: &Engines) -> Visibility { match self { ResolvedDeclaration::Parsed(decl) => decl.visibility(engines.pe()), diff --git a/sway-core/src/type_system/ast_elements/binding.rs b/sway-core/src/type_system/ast_elements/binding.rs index a391a9e1c67..d6022709fa6 100644 --- a/sway-core/src/type_system/ast_elements/binding.rs +++ b/sway-core/src/type_system/ast_elements/binding.rs @@ -363,11 +363,12 @@ impl SymbolResolveTypeBinding for TypeBinding { let engines = ctx.engines(); // Grab the declaration. let unknown_decl = ctx.resolve_call_path_with_visibility_check(handler, &self.inner)?; + // Check to see if this is a struct declaration. - let struct_decl_id = unknown_decl + let struct_decl = unknown_decl.to_struct_decl(handler, engines)?; + struct_decl .resolve_parsed(engines.de()) - .to_struct_decl(handler, engines)?; - Ok(struct_decl_id) + .to_struct_decl(handler, engines) } } @@ -390,7 +391,7 @@ impl TypeCheckTypeBinding for TypeBinding { // Grab the declaration. let unknown_decl = ctx.resolve_call_path_with_visibility_check(handler, &self.inner)?; // Check to see if this is a struct declaration. - let struct_id = unknown_decl.to_struct_id(handler, engines)?; + let struct_id = unknown_decl.to_struct_decl(handler, engines)?; // Get a new copy from the declaration engine. let mut new_copy = (*decl_engine.get_struct(&struct_id)).clone(); // Monomorphize the copy, in place. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.lock new file mode 100644 index 00000000000..e5570689316 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "alias" +source = "path+from-root-DE984AFD05391BAA" + +[[package]] +name = "use-alias" +source = "member" +dependencies = ["alias"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.toml new file mode 100644 index 00000000000..a0d6afeeff2 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "type_alias_basic" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/src/main.sw new file mode 100644 index 00000000000..fa400cbfbc4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_basic/src/main.sw @@ -0,0 +1,4 @@ +library; + +struct S {} +pub type Alias = S; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.lock new file mode 100644 index 00000000000..69e0c1abf7b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "type_alias_basic" +source = "path+from-root-05B061D32AED907C" + +[[package]] +name = "type_alias_from_dependency" +source = "member" +dependencies = ["type_alias_basic"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.toml new file mode 100644 index 00000000000..82ceffc153f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "type_alias_from_dependency" +implicit-std = false + +[dependencies] +type_alias_basic = { path = "../type_alias_basic" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/src/main.sw new file mode 100644 index 00000000000..92e8e146129 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/src/main.sw @@ -0,0 +1,7 @@ +library; + +use type_alias_basic::*; + +fn foo() { + let z = type_alias_basic::Alias { }; +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/test.toml new file mode 100644 index 00000000000..848f61f7cd7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/type_alias_from_dependency/test.toml @@ -0,0 +1,3 @@ +category = "compile" +validate_abi = false +expected_warnings = 2