Skip to content

Commit a85a3d7

Browse files
committed
feat: be more precise in mismatch arg counts highlighting
1 parent 6005ea5 commit a85a3d7

File tree

1 file changed

+54
-12
lines changed

1 file changed

+54
-12
lines changed

crates/ide_diagnostics/src/handlers/mismatched_arg_count.rs

+54-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
use ide_db::base_db::{FileRange, SourceDatabase};
2+
use syntax::{
3+
algo::find_node_at_range,
4+
ast::{self, HasArgList},
5+
AstNode,
6+
};
7+
18
use crate::{Diagnostic, DiagnosticsContext};
29

310
// Diagnostic: mismatched-arg-count
@@ -12,10 +19,45 @@ pub(crate) fn mismatched_arg_count(
1219
Diagnostic::new(
1320
"mismatched-arg-count",
1421
message,
15-
ctx.sema.diagnostics_display_range(d.call_expr.clone().map(|it| it.into())).range,
22+
invalid_args_range(ctx, d).unwrap_or_else(|it| it).range,
1623
)
1724
}
1825

26+
fn invalid_args_range(
27+
ctx: &DiagnosticsContext<'_>,
28+
d: &hir::MismatchedArgCount,
29+
) -> Result<FileRange, FileRange> {
30+
let full_range = ctx.sema.diagnostics_display_range(d.call_expr.clone().map(|it| it.into()));
31+
32+
let source_file = ctx.sema.db.parse(full_range.file_id);
33+
let expr = find_node_at_range::<ast::Expr>(&source_file.syntax_node(), full_range.range)
34+
.filter(|it| it.syntax().text_range() == full_range.range);
35+
let arg_list = match expr {
36+
Some(ast::Expr::CallExpr(call)) => call.arg_list(),
37+
Some(ast::Expr::MethodCallExpr(call)) => call.arg_list(),
38+
_ => None,
39+
};
40+
let arg_list = match arg_list {
41+
Some(it) => it,
42+
None => return Err(full_range),
43+
};
44+
let arg_list_range =
45+
FileRange { file_id: full_range.file_id, range: arg_list.syntax().text_range() };
46+
if d.found < d.expected {
47+
if d.found == 0 {
48+
return Ok(arg_list_range);
49+
}
50+
if let Some(r_paren) = arg_list.r_paren_token() {
51+
return Ok(FileRange { file_id: full_range.file_id, range: r_paren.text_range() });
52+
}
53+
}
54+
if d.expected < d.found {
55+
return Ok(arg_list_range);
56+
}
57+
58+
Err(full_range)
59+
}
60+
1961
#[cfg(test)]
2062
mod tests {
2163
use crate::tests::check_diagnostics;
@@ -26,7 +68,7 @@ mod tests {
2668
r#"
2769
fn zero() {}
2870
fn f() { zero(1); }
29-
//^^^^^^^ error: expected 0 arguments, found 1
71+
//^^^ error: expected 0 arguments, found 1
3072
"#,
3173
);
3274

@@ -44,7 +86,7 @@ fn f() { zero(); }
4486
r#"
4587
fn one(arg: u8) {}
4688
fn f() { one(); }
47-
//^^^^^ error: expected 1 argument, found 0
89+
//^^ error: expected 1 argument, found 0
4890
"#,
4991
);
5092

@@ -65,7 +107,7 @@ impl S { fn method(&self) {} }
65107
66108
fn f() {
67109
S::method();
68-
} //^^^^^^^^^^^ error: expected 1 argument, found 0
110+
} //^^ error: expected 1 argument, found 0
69111
"#,
70112
);
71113

@@ -91,7 +133,7 @@ impl S { fn method(&self, arg: u8) {} }
91133
92134
fn f() {
93135
S.method();
94-
} //^^^^^^^^^^ error: expected 1 argument, found 0
136+
} //^^ error: expected 1 argument, found 0
95137
"#,
96138
);
97139

@@ -131,7 +173,7 @@ fn f() {
131173
struct Tup(u8, u16);
132174
fn f() {
133175
Tup(0);
134-
} //^^^^^^ error: expected 2 arguments, found 1
176+
} //^ error: expected 2 arguments, found 1
135177
"#,
136178
)
137179
}
@@ -143,7 +185,7 @@ fn f() {
143185
enum En { Variant(u8, u16), }
144186
fn f() {
145187
En::Variant(0);
146-
} //^^^^^^^^^^^^^^ error: expected 2 arguments, found 1
188+
} //^ error: expected 2 arguments, found 1
147189
"#,
148190
)
149191
}
@@ -162,9 +204,9 @@ impl Foo {
162204
fn new() {
163205
Foo::Bar(0);
164206
Foo::Bar(0, 1);
165-
//^^^^^^^^^^^^^^ error: expected 1 argument, found 2
207+
//^^^^^^ error: expected 1 argument, found 2
166208
Foo::Bar();
167-
//^^^^^^^^^^ error: expected 1 argument, found 0
209+
//^^ error: expected 1 argument, found 0
168210
}
169211
}
170212
"#,
@@ -185,7 +227,7 @@ fn f() {
185227
unsafe {
186228
fixed(0);
187229
fixed(0, 1);
188-
//^^^^^^^^^^^ error: expected 1 argument, found 2
230+
//^^^^^^ error: expected 1 argument, found 2
189231
varargs(0);
190232
varargs(0, 1);
191233
varargs2();
@@ -204,10 +246,10 @@ fn f() {
204246
fn main() {
205247
let f = |()| ();
206248
f();
207-
//^^^ error: expected 1 argument, found 0
249+
//^^ error: expected 1 argument, found 0
208250
f(());
209251
f((), ());
210-
//^^^^^^^^^ error: expected 1 argument, found 2
252+
//^^^^^^^^ error: expected 1 argument, found 2
211253
}
212254
"#,
213255
)

0 commit comments

Comments
 (0)