From a81c42eb18827c644f46a6119054d4dacb500f92 Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Wed, 4 Sep 2024 12:16:47 +0100 Subject: [PATCH] Adds function return type unification. (#6490) ## Description The function return type unification was missing, leading to generic functions not being resolved based on the return type. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty Co-authored-by: IGI-111 --- .../typed_expression/function_application.rs | 11 +++++++ .../bad_generic_annotation/test.toml | 6 ++++ .../shadowing_in_reexporting_module/test.toml | 2 +- .../recursive_type_unification/test.toml | 7 +++++ .../.gitignore | 2 ++ .../Forc.lock | 13 +++++++++ .../Forc.toml | 8 +++++ .../src/main.sw | 29 +++++++++++++++++++ .../test.toml | 4 +++ 9 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs index a3f299027b9..e400e3b1470 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/function_application.rs @@ -61,6 +61,17 @@ pub(crate) fn instantiate_function_application( &function_decl.parameters, )?; + // unify function return type with current ctx.type_annotation(). + engines.te().unify_with_generic( + handler, + engines, + function_decl.return_type.type_id, + ctx.type_annotation(), + &call_path_binding.span(), + "Function return type does not match up with local type annotation.", + None, + ); + let mut function_return_type_id = function_decl.return_type.type_id; let function_ident: IdentUnique = function_decl.name.clone().into(); diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml index 2023da0cc3a..e65971dfc6d 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/bad_generic_annotation/test.toml @@ -1,5 +1,11 @@ category = "fail" +# check: let _g: u32 = three_generics(true, "foo", 10); +# nextln: $()Mismatched types. +# nextln: $()expected: u32 +# nextln: $()found: str. +# nextln: $()help: Function return type does not match up with local type annotation. + # check: let _g: u32 = three_generics(true, "foo", 10); # nextln: $()Mismatched types. # nextln: $()expected: u32 diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml index 9ba4d7f4a66..700594e5116 100755 --- a/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/language/reexport/shadowing_in_reexporting_module/test.toml @@ -188,4 +188,4 @@ category = "fail" #check: $()error #check: $()This path must return a value of type "u64" from function "items_2_trait_function", but it does not. -#check: $()Aborting due to 40 errors. +#check: $()Aborting due to 42 errors. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml index 48b8108e7a9..a660e53c0ad 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml +++ b/test/src/e2e_vm_tests/test_programs/should_fail/recursive_type_unification/test.toml @@ -1,5 +1,12 @@ category = "fail" +# check: $()error +# check: $()MyOption::Some::(foo::(value)) +# nextln: $()Mismatched types. +# nextln: $()expected: V +# nextln: $()found: MyOption. +# nextln: $()Function return type does not match up with local type annotation. + # check: $()error # check: $()MyOption::Some::(foo::(value)) # nextln: $()Mismatched types. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock new file mode 100644 index 00000000000..8407bd5c37c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.lock @@ -0,0 +1,13 @@ +[[package]] +name = "core" +source = "path+from-root-D73E65B1F4E48513" + +[[package]] +name = "function_return_type_unification" +source = "member" +dependencies = ["std"] + +[[package]] +name = "std" +source = "path+from-root-D73E65B1F4E48513" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml new file mode 100644 index 00000000000..96f4447a531 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/Forc.toml @@ -0,0 +1,8 @@ +[project] +name = "function_return_type_unification" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" + +[dependencies] +std = { path = "../../../../reduced_std_libs/sway-lib-std-assert" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw new file mode 100644 index 00000000000..9d5c8d4d08c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/src/main.sw @@ -0,0 +1,29 @@ +script; + +trait Build { + fn build() -> Self; +} + +impl Build for u32 { + fn build() -> Self { + 31 + } +} + +impl Build for u64 { + fn build() -> Self { + 63 + } +} + +fn produce() -> T +where T: Build, +{ + T::build() +} + +fn main() -> bool { + let _:u32 = produce(); + + true +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml new file mode 100644 index 00000000000..1591686ff87 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/function_return_type_unification/test.toml @@ -0,0 +1,4 @@ +category = "run" +expected_result = { action = "return", value = 1 } +expected_result_new_encoding = { action = "return_data", value = "01" } +validate_abi = false