Skip to content

Commit c288563

Browse files
Fixes argument errors not displayed. (#5909)
## Description `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 ## 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). - [ ] I have requested a review from the relevant team or maintainers. Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
1 parent b7123c5 commit c288563

File tree

5 files changed

+87
-6
lines changed

5 files changed

+87
-6
lines changed

sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -77,25 +77,35 @@ pub(crate) fn type_check_method_application(
7777
true
7878
}
7979
});
80-
handler.append(arg_handler);
80+
handler.append(arg_handler.clone());
8181
}
8282

83-
args_opt_buf.push_back((arg_opt, needs_second_pass));
83+
args_opt_buf.push_back((arg_opt, arg_handler, needs_second_pass));
8484
}
8585

8686
// resolve the method name to a typed function declaration and type_check
87-
let (original_decl_ref, call_path_typeid) = resolve_method_name(
87+
let method_result = resolve_method_name(
8888
handler,
8989
ctx.by_ref(),
9090
&method_name_binding,
9191
args_opt_buf
9292
.iter()
93-
.map(|(arg, _has_errors)| match arg {
93+
.map(|(arg, _, _has_errors)| match arg {
9494
Some(arg) => arg.return_type,
9595
None => type_engine.new_unknown(),
9696
})
9797
.collect(),
98-
)?;
98+
);
99+
100+
// In case resolve_method_name fails throw argument errors.
101+
let (original_decl_ref, call_path_typeid) = if let Err(e) = method_result {
102+
for (_, arg_handler, _) in args_opt_buf.iter() {
103+
handler.append(arg_handler.clone());
104+
}
105+
return Err(e);
106+
} else {
107+
method_result.unwrap()
108+
};
99109

100110
let mut fn_ref = monomorphize_method(
101111
handler,
@@ -120,7 +130,7 @@ pub(crate) fn type_check_method_application(
120130
// type check the function arguments (2nd pass)
121131
let mut args_buf = VecDeque::new();
122132
for (arg, index, arg_opt) in izip!(arguments.iter(), 0.., args_opt_buf.iter().cloned()) {
123-
if let (Some(arg), false) = arg_opt {
133+
if let (Some(arg), _, false) = arg_opt {
124134
args_buf.push_back(arg);
125135
} else {
126136
// We type check the argument expression again this time throwing out the error.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[package]]
2+
name = "core"
3+
source = "path+from-root-1C5801B8398D8ED4"
4+
5+
[[package]]
6+
name = "variable_does_not_exist"
7+
source = "member"
8+
dependencies = ["core"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "variable_does_not_exist"
3+
authors = ["Fuel Labs <contact@fuel.sh>"]
4+
entry = "main.sw"
5+
license = "Apache-2.0"
6+
implicit-std = false
7+
8+
[dependencies]
9+
core = { path = "../../../../../../sway-lib-core" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
script;
2+
3+
struct S {}
4+
5+
impl S {
6+
fn associated(a: u64, b: u64, c: u64) -> u64 {
7+
a + b + c
8+
}
9+
}
10+
11+
fn function(a: u64, b: u64, c: u64) -> u64 {
12+
a + b + c
13+
}
14+
15+
fn main() {
16+
let _ = S::associated(x, y, z);
17+
18+
19+
let _ = function(x, y, z);
20+
21+
22+
let _ = x + y + z;
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
category = "fail"
2+
3+
# check: $()let _ = S::associated(x, y, z);
4+
# nextln:$()Variable "x" does not exist in this scope.
5+
6+
# check: $()let _ = S::associated(x, y, z);
7+
# nextln:$()Variable "y" does not exist in this scope.
8+
9+
# check: $()let _ = S::associated(x, y, z);
10+
# nextln:$()Variable "z" does not exist in this scope.
11+
12+
# check: $()let _ = function(x, y, z);
13+
# nextln:$()Variable "x" does not exist in this scope.
14+
15+
# check: $()let _ = function(x, y, z);
16+
# nextln:$()Variable "y" does not exist in this scope.
17+
18+
# check: $()let _ = function(x, y, z);
19+
# nextln:$()Variable "z" does not exist in this scope.
20+
21+
# check: $()let _ = x + y + z;
22+
# nextln: $()Variable "x" does not exist in this scope.
23+
24+
# check: $()let _ = x + y + z;
25+
# nextln: $()Variable "y" does not exist in this scope.
26+
27+
# check: $()let _ = x + y + z;
28+
# nextln: $()No method "add({unknown}, unknown)" found for type "{unknown}".
29+
30+
# check: $()let _ = x + y + z;
31+
# nextln: $()Variable "z" does not exist in this scope.

0 commit comments

Comments
 (0)