Skip to content

Commit 77e3594

Browse files
Rollup merge of rust-lang#140591 - Kivooeo:new-fix-five, r=davidtwco
Fix malformed suggestion for E0061 when method is a macro token in macro context fixes rust-lang#140512 before ```rust 3 - <Self>::$method(8) 3 + <Self>::<Self>::$method(8, /* u8 */) ``` now ```rust 3 | <Self>::$method(8, /* u8 */) | ++++++++++ ```
2 parents d76fe15 + 3cd065d commit 77e3594

File tree

4 files changed

+124
-55
lines changed

4 files changed

+124
-55
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,25 +1556,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15561556
SuggestionText::Reorder => Some("reorder these arguments".to_string()),
15571557
SuggestionText::DidYouMean => Some("did you mean".to_string()),
15581558
};
1559-
if let Some(suggestion_text) = suggestion_text {
1559+
if let Some(suggestion_text) = suggestion_text
1560+
&& !full_call_span.in_external_macro(self.sess().source_map())
1561+
{
15601562
let source_map = self.sess().source_map();
1561-
let (mut suggestion, suggestion_span) = if let Some(call_span) =
1562-
full_call_span.find_ancestor_inside_same_ctxt(error_span)
1563-
{
1564-
("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
1563+
let suggestion_span = if let Some(args_span) = error_span.trim_start(full_call_span) {
1564+
// Span of the braces, e.g. `(a, b, c)`.
1565+
args_span
15651566
} else {
1566-
(
1567-
format!(
1568-
"{}(",
1569-
source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
1570-
fn_def_id.map_or("".to_string(), |fn_def_id| {
1571-
tcx.item_name(fn_def_id).to_string()
1572-
})
1573-
})
1574-
),
1575-
error_span,
1576-
)
1567+
// The arg span of a function call that wasn't even given braces
1568+
// like what might happen with delegation reuse.
1569+
// e.g. `reuse HasSelf::method;` should suggest `reuse HasSelf::method($args);`.
1570+
full_call_span.shrink_to_hi()
15771571
};
1572+
let mut suggestion = "(".to_owned();
15781573
let mut needs_comma = false;
15791574
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
15801575
if needs_comma {

tests/ui/auxiliary/delegate_macro.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[macro_export]
2+
macro_rules! delegate {
3+
($method:ident) => {
4+
<Self>::$method(8)
5+
};
6+
}

tests/ui/not-enough-arguments.rs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1+
//@ aux-build: delegate_macro.rs
2+
extern crate delegate_macro;
3+
use delegate_macro::delegate;
4+
15
// Check that the only error msg we report is the
26
// mismatch between the # of params, and not other
37
// unrelated errors.
4-
5-
fn foo(a: isize, b: isize, c: isize, d:isize) {
6-
panic!();
8+
fn foo(a: isize, b: isize, c: isize, d: isize) {
9+
panic!();
710
}
811

912
// Check that all arguments are shown in the error message, even if they're across multiple lines.
10-
fn bar(
11-
a: i32,
12-
b: i32,
13-
c: i32,
14-
d: i32,
15-
e: i32,
16-
f: i32,
17-
) {
13+
fn bar(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32) {
1814
println!("{}", a);
1915
println!("{}", b);
2016
println!("{}", c);
@@ -23,9 +19,35 @@ fn bar(
2319
println!("{}", f);
2420
}
2521

22+
macro_rules! delegate_local {
23+
($method:ident) => {
24+
<Self>::$method(8)
25+
//~^ ERROR function takes 2 arguments but 1
26+
};
27+
}
28+
29+
macro_rules! delegate_from {
30+
($from:ident, $method:ident) => {
31+
<$from>::$method(8)
32+
//~^ ERROR function takes 2 arguments but 1
33+
};
34+
}
35+
36+
struct Bar;
37+
38+
impl Bar {
39+
fn foo(a: u8, b: u8) {}
40+
fn bar() {
41+
delegate_local!(foo);
42+
delegate!(foo);
43+
//~^ ERROR function takes 2 arguments but 1
44+
delegate_from!(Bar, foo);
45+
}
46+
}
47+
2648
fn main() {
27-
foo(1, 2, 3);
28-
//~^ ERROR function takes 4 arguments but 3
29-
bar(1, 2, 3);
30-
//~^ ERROR function takes 6 arguments but 3
49+
foo(1, 2, 3);
50+
//~^ ERROR function takes 4 arguments but 3
51+
bar(1, 2, 3);
52+
//~^ ERROR function takes 6 arguments but 3
3153
}

tests/ui/not-enough-arguments.stderr

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,88 @@
1+
error[E0061]: this function takes 2 arguments but 1 argument was supplied
2+
--> $DIR/not-enough-arguments.rs:24:9
3+
|
4+
LL | <Self>::$method(8)
5+
| ^^^^^^^^^^^^^^^--- argument #2 of type `u8` is missing
6+
...
7+
LL | delegate_local!(foo);
8+
| -------------------- in this macro invocation
9+
|
10+
note: associated function defined here
11+
--> $DIR/not-enough-arguments.rs:39:8
12+
|
13+
LL | fn foo(a: u8, b: u8) {}
14+
| ^^^ -----
15+
= note: this error originates in the macro `delegate_local` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
help: provide the argument
17+
|
18+
LL | <Self>::$method(8, /* u8 */)
19+
| ++++++++++
20+
21+
error[E0061]: this function takes 2 arguments but 1 argument was supplied
22+
--> $DIR/not-enough-arguments.rs:42:9
23+
|
24+
LL | delegate!(foo);
25+
| ^^^^^^^^^^^^^^ argument #2 of type `u8` is missing
26+
|
27+
note: associated function defined here
28+
--> $DIR/not-enough-arguments.rs:39:8
29+
|
30+
LL | fn foo(a: u8, b: u8) {}
31+
| ^^^ -----
32+
= note: this error originates in the macro `delegate` (in Nightly builds, run with -Z macro-backtrace for more info)
33+
34+
error[E0061]: this function takes 2 arguments but 1 argument was supplied
35+
--> $DIR/not-enough-arguments.rs:31:9
36+
|
37+
LL | <$from>::$method(8)
38+
| ^^^^^^^^^^^^^^^^--- argument #2 of type `u8` is missing
39+
...
40+
LL | delegate_from!(Bar, foo);
41+
| ------------------------ in this macro invocation
42+
|
43+
note: associated function defined here
44+
--> $DIR/not-enough-arguments.rs:39:8
45+
|
46+
LL | fn foo(a: u8, b: u8) {}
47+
| ^^^ -----
48+
= note: this error originates in the macro `delegate_from` (in Nightly builds, run with -Z macro-backtrace for more info)
49+
help: provide the argument
50+
|
51+
LL | <$from>::$method(8, /* u8 */)
52+
| ++++++++++
53+
154
error[E0061]: this function takes 4 arguments but 3 arguments were supplied
2-
--> $DIR/not-enough-arguments.rs:27:3
55+
--> $DIR/not-enough-arguments.rs:49:5
356
|
4-
LL | foo(1, 2, 3);
5-
| ^^^--------- argument #4 of type `isize` is missing
57+
LL | foo(1, 2, 3);
58+
| ^^^--------- argument #4 of type `isize` is missing
659
|
760
note: function defined here
8-
--> $DIR/not-enough-arguments.rs:5:4
61+
--> $DIR/not-enough-arguments.rs:8:4
962
|
10-
LL | fn foo(a: isize, b: isize, c: isize, d:isize) {
11-
| ^^^ -------
63+
LL | fn foo(a: isize, b: isize, c: isize, d: isize) {
64+
| ^^^ --------
1265
help: provide the argument
1366
|
14-
LL | foo(1, 2, 3, /* isize */);
15-
| +++++++++++++
67+
LL | foo(1, 2, 3, /* isize */);
68+
| +++++++++++++
1669

1770
error[E0061]: this function takes 6 arguments but 3 arguments were supplied
18-
--> $DIR/not-enough-arguments.rs:29:3
71+
--> $DIR/not-enough-arguments.rs:51:5
1972
|
20-
LL | bar(1, 2, 3);
21-
| ^^^--------- three arguments of type `i32`, `i32`, and `i32` are missing
73+
LL | bar(1, 2, 3);
74+
| ^^^--------- three arguments of type `i32`, `i32`, and `i32` are missing
2275
|
2376
note: function defined here
24-
--> $DIR/not-enough-arguments.rs:10:4
77+
--> $DIR/not-enough-arguments.rs:13:4
2578
|
26-
LL | fn bar(
27-
| ^^^
28-
...
29-
LL | d: i32,
30-
| ------
31-
LL | e: i32,
32-
| ------
33-
LL | f: i32,
34-
| ------
79+
LL | fn bar(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32) {
80+
| ^^^ ------ ------ ------
3581
help: provide the arguments
3682
|
37-
LL | bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */);
38-
| +++++++++++++++++++++++++++++++++
83+
LL | bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */);
84+
| +++++++++++++++++++++++++++++++++
3985

40-
error: aborting due to 2 previous errors
86+
error: aborting due to 5 previous errors
4187

4288
For more information about this error, try `rustc --explain E0061`.

0 commit comments

Comments
 (0)