From e9c18b53ec0ce59ce0c06524de90c8e69239fdeb Mon Sep 17 00:00:00 2001 From: Marcos Henrich Date: Tue, 23 Apr 2024 11:57:54 +0100 Subject: [PATCH] Fixes argument errors not displayed. type_check_method_application does the parsing of arguments in 2 passes, but when the resolved_method_name failed the argument error would not be displayed. We now store the arg_handlers and append their errors in case resolve_method_name fails. Fixes #5660 --- .../typed_expression/method_application.rs | 22 +++++++++---- .../variable_does_not_exist/Forc.lock | 8 +++++ .../variable_does_not_exist/Forc.toml | 9 ++++++ .../variable_does_not_exist/src/main.sw | 23 ++++++++++++++ .../variable_does_not_exist/test.toml | 31 +++++++++++++++++++ 5 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/test.toml diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs index 99d7bd2f578..c7ae5c92a2b 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs @@ -77,25 +77,35 @@ pub(crate) fn type_check_method_application( true } }); - handler.append(arg_handler); + handler.append(arg_handler.clone()); } - args_opt_buf.push_back((arg_opt, needs_second_pass)); + args_opt_buf.push_back((arg_opt, arg_handler, needs_second_pass)); } // resolve the method name to a typed function declaration and type_check - let (original_decl_ref, call_path_typeid) = resolve_method_name( + let method_result = resolve_method_name( handler, ctx.by_ref(), &method_name_binding, args_opt_buf .iter() - .map(|(arg, _has_errors)| match arg { + .map(|(arg, _, _has_errors)| match arg { Some(arg) => arg.return_type, None => type_engine.new_unknown(), }) .collect(), - )?; + ); + + // In case resolve_method_name fails throw argument errors. + let (original_decl_ref, call_path_typeid) = if let Err(e) = method_result { + for (_, arg_handler, _) in args_opt_buf.iter() { + handler.append(arg_handler.clone()); + } + return Err(e); + } else { + method_result.unwrap() + }; let mut fn_ref = monomorphize_method( handler, @@ -120,7 +130,7 @@ pub(crate) fn type_check_method_application( // type check the function arguments (2nd pass) let mut args_buf = VecDeque::new(); for (arg, index, arg_opt) in izip!(arguments.iter(), 0.., args_opt_buf.iter().cloned()) { - if let (Some(arg), false) = arg_opt { + if let (Some(arg), _, false) = arg_opt { args_buf.push_back(arg); } else { // We type check the argument expression again this time throwing out the error. diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.lock new file mode 100644 index 00000000000..478b462e84b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = "core" +source = "path+from-root-1C5801B8398D8ED4" + +[[package]] +name = "variable_does_not_exist" +source = "member" +dependencies = ["core"] diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.toml new file mode 100644 index 00000000000..31713fc97e7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/Forc.toml @@ -0,0 +1,9 @@ +[project] +name = "variable_does_not_exist" +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +implicit-std = false + +[dependencies] +core = { path = "../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/src/main.sw new file mode 100644 index 00000000000..73cc041ae7b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/src/main.sw @@ -0,0 +1,23 @@ +script; + +struct S {} + +impl S { + fn associated(a: u64, b: u64, c: u64) -> u64 { + a + b + c + } +} + +fn function(a: u64, b: u64, c: u64) -> u64 { + a + b + c +} + +fn main() { + let _ = S::associated(x, y, z); + + + let _ = function(x, y, z); + + + let _ = x + y + z; +} \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/test.toml new file mode 100644 index 00000000000..64c903bf329 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/variable_does_not_exist/test.toml @@ -0,0 +1,31 @@ +category = "fail" + +# check: $()let _ = S::associated(x, y, z); +# nextln:$()Variable "x" does not exist in this scope. + +# check: $()let _ = S::associated(x, y, z); +# nextln:$()Variable "y" does not exist in this scope. + +# check: $()let _ = S::associated(x, y, z); +# nextln:$()Variable "z" does not exist in this scope. + +# check: $()let _ = function(x, y, z); +# nextln:$()Variable "x" does not exist in this scope. + +# check: $()let _ = function(x, y, z); +# nextln:$()Variable "y" does not exist in this scope. + +# check: $()let _ = function(x, y, z); +# nextln:$()Variable "z" does not exist in this scope. + +# check: $()let _ = x + y + z; +# nextln: $()Variable "x" does not exist in this scope. + +# check: $()let _ = x + y + z; +# nextln: $()Variable "y" does not exist in this scope. + +# check: $()let _ = x + y + z; +# nextln: $()No method "add({unknown}, unknown)" found for type "{unknown}". + +# check: $()let _ = x + y + z; +# nextln: $()Variable "z" does not exist in this scope.