Skip to content

Commit 75a02a9

Browse files
committed
Auto merge of #46633 - estebank:arg-mismatch, r=arielb1
Point at whole method call instead of args To avoid confusion in cases where the code is ```rust fn foo() {} / foo( | bar() | ^^^ current diagnostics point here for arg count mismatch | ); |_^ new diagnostic span points here ``` as this leads to confusion making people think that the diagnostic is talking about `bar`'s arg count, not `foo`'s. Point at `fn`s definition on arg mismatch, just like we do for closures. Re #42855, Fix #45633.
2 parents 8954b16 + 92da913 commit 75a02a9

16 files changed

+94
-84
lines changed

src/librustc/traits/error_reporting.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
714714
let found_did = found_trait_ty.ty_to_def_id();
715715
let found_span = found_did.and_then(|did| {
716716
self.tcx.hir.span_if_local(did)
717-
});
717+
}).map(|sp| self.tcx.sess.codemap().def_span(sp)); // the sp could be an fn def
718718

719719
let found_ty_count =
720720
match found_trait_ref.skip_binder().substs.type_at(1).sty {
@@ -751,7 +751,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
751751
//
752752
// ```
753753
// [1i32, 2, 3].sort_by(|(a, b)| ..)
754-
// // ^^^^^^^^
754+
// // ^^^^^^^ --------
755755
// // expected_trait_ref: std::ops::FnMut<(&i32, &i32)>
756756
// // found_trait_ref: std::ops::FnMut<(&i32,)>
757757
// ```

src/librustc/ty/sty.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
15591559
TyAdt(def, _) => Some(def.did),
15601560
TyForeign(did) => Some(did),
15611561
TyClosure(id, _) => Some(id),
1562+
TyFnDef(id, _) => Some(id),
15621563
_ => None,
15631564
}
15641565
}

src/librustc_typeck/check/mod.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -2432,21 +2432,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24322432
let mut expected_arg_tys = expected_arg_tys;
24332433
let expected_arg_count = fn_inputs.len();
24342434

2435-
let sp_args = if args.len() > 0 {
2436-
let (first, args) = args.split_at(1);
2437-
let mut sp_tmp = first[0].span;
2438-
for arg in args {
2439-
let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span);
2440-
if ! sp_opt.is_some() {
2441-
break;
2442-
}
2443-
sp_tmp = sp_opt.unwrap();
2444-
};
2445-
sp_tmp
2446-
} else {
2447-
sp
2448-
};
2449-
24502435
fn parameter_count_error<'tcx>(sess: &Session,
24512436
sp: Span,
24522437
expr_sp: Span,
@@ -2465,7 +2450,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24652450
if arg_count == 1 {" was"} else {"s were"}),
24662451
DiagnosticId::Error(error_code.to_owned()));
24672452

2468-
if let Some(def_s) = def_span {
2453+
if let Some(def_s) = def_span.map(|sp| sess.codemap().def_span(sp)) {
24692454
err.span_label(def_s, "defined here");
24702455
}
24712456
if sugg_unit {
@@ -2489,7 +2474,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24892474
let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
24902475
match tuple_type.sty {
24912476
ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
2492-
parameter_count_error(tcx.sess, sp_args, expr_sp, arg_types.len(), args.len(),
2477+
parameter_count_error(tcx.sess, sp, expr_sp, arg_types.len(), args.len(),
24932478
"E0057", false, def_span, false);
24942479
expected_arg_tys = &[];
24952480
self.err_args(args.len())
@@ -2518,7 +2503,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25182503
if supplied_arg_count >= expected_arg_count {
25192504
fn_inputs.to_vec()
25202505
} else {
2521-
parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
2506+
parameter_count_error(tcx.sess, sp, expr_sp, expected_arg_count,
25222507
supplied_arg_count, "E0060", true, def_span, false);
25232508
expected_arg_tys = &[];
25242509
self.err_args(supplied_arg_count)
@@ -2532,7 +2517,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25322517
} else {
25332518
false
25342519
};
2535-
parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
2520+
parameter_count_error(tcx.sess, sp, expr_sp, expected_arg_count,
25362521
supplied_arg_count, "E0061", false, def_span, sugg_unit);
25372522
expected_arg_tys = &[];
25382523
self.err_args(supplied_arg_count)

src/test/ui/anonymous-higher-ranked-lifetime.stderr

+11-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0631]: type mismatch in closure arguments
22
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
33
|
44
12 | f1(|_: (), _: ()| {}); //~ ERROR type mismatch
5-
| ^^ ----------------- found signature of `fn((), ()) -> _`
5+
| ^^ -------------- found signature of `fn((), ()) -> _`
66
| |
77
| expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _`
88
|
@@ -12,7 +12,7 @@ error[E0631]: type mismatch in closure arguments
1212
--> $DIR/anonymous-higher-ranked-lifetime.rs:13:5
1313
|
1414
13 | f2(|_: (), _: ()| {}); //~ ERROR type mismatch
15-
| ^^ ----------------- found signature of `fn((), ()) -> _`
15+
| ^^ -------------- found signature of `fn((), ()) -> _`
1616
| |
1717
| expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _`
1818
|
@@ -22,7 +22,7 @@ error[E0631]: type mismatch in closure arguments
2222
--> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
2323
|
2424
14 | f3(|_: (), _: ()| {}); //~ ERROR type mismatch
25-
| ^^ ----------------- found signature of `fn((), ()) -> _`
25+
| ^^ -------------- found signature of `fn((), ()) -> _`
2626
| |
2727
| expected signature of `for<'r> fn(&(), &'r ()) -> _`
2828
|
@@ -32,7 +32,7 @@ error[E0631]: type mismatch in closure arguments
3232
--> $DIR/anonymous-higher-ranked-lifetime.rs:15:5
3333
|
3434
15 | f4(|_: (), _: ()| {}); //~ ERROR type mismatch
35-
| ^^ ----------------- found signature of `fn((), ()) -> _`
35+
| ^^ -------------- found signature of `fn((), ()) -> _`
3636
| |
3737
| expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _`
3838
|
@@ -42,7 +42,7 @@ error[E0631]: type mismatch in closure arguments
4242
--> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
4343
|
4444
16 | f5(|_: (), _: ()| {}); //~ ERROR type mismatch
45-
| ^^ ----------------- found signature of `fn((), ()) -> _`
45+
| ^^ -------------- found signature of `fn((), ()) -> _`
4646
| |
4747
| expected signature of `for<'r> fn(&'r (), &'r ()) -> _`
4848
|
@@ -52,7 +52,7 @@ error[E0631]: type mismatch in closure arguments
5252
--> $DIR/anonymous-higher-ranked-lifetime.rs:17:5
5353
|
5454
17 | g1(|_: (), _: ()| {}); //~ ERROR type mismatch
55-
| ^^ ----------------- found signature of `fn((), ()) -> _`
55+
| ^^ -------------- found signature of `fn((), ()) -> _`
5656
| |
5757
| expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _`
5858
|
@@ -62,7 +62,7 @@ error[E0631]: type mismatch in closure arguments
6262
--> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
6363
|
6464
18 | g2(|_: (), _: ()| {}); //~ ERROR type mismatch
65-
| ^^ ----------------- found signature of `fn((), ()) -> _`
65+
| ^^ -------------- found signature of `fn((), ()) -> _`
6666
| |
6767
| expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _`
6868
|
@@ -72,7 +72,7 @@ error[E0631]: type mismatch in closure arguments
7272
--> $DIR/anonymous-higher-ranked-lifetime.rs:19:5
7373
|
7474
19 | g3(|_: (), _: ()| {}); //~ ERROR type mismatch
75-
| ^^ ----------------- found signature of `fn((), ()) -> _`
75+
| ^^ -------------- found signature of `fn((), ()) -> _`
7676
| |
7777
| expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _`
7878
|
@@ -82,7 +82,7 @@ error[E0631]: type mismatch in closure arguments
8282
--> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
8383
|
8484
20 | g4(|_: (), _: ()| {}); //~ ERROR type mismatch
85-
| ^^ ----------------- found signature of `fn((), ()) -> _`
85+
| ^^ -------------- found signature of `fn((), ()) -> _`
8686
| |
8787
| expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
8888
|
@@ -92,7 +92,7 @@ error[E0631]: type mismatch in closure arguments
9292
--> $DIR/anonymous-higher-ranked-lifetime.rs:21:5
9393
|
9494
21 | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
95-
| ^^ ------------------------------- found signature of `fn((), (), (), ()) -> _`
95+
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
9696
| |
9797
| expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
9898
|
@@ -102,7 +102,7 @@ error[E0631]: type mismatch in closure arguments
102102
--> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
103103
|
104104
22 | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
105-
| ^^ ------------------------------- found signature of `fn((), (), (), ()) -> _`
105+
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
106106
| |
107107
| expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
108108
|

src/test/ui/method-call-err-msg.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
error[E0061]: this function takes 0 parameters but 1 parameter was supplied
2-
--> $DIR/method-call-err-msg.rs:25:12
2+
--> $DIR/method-call-err-msg.rs:25:7
33
|
44
15 | fn zero(self) -> Foo { self }
5-
| ----------------------------- defined here
5+
| -------------------- defined here
66
...
77
25 | x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied
8-
| ^ expected 0 parameters
8+
| ^^^^ expected 0 parameters
99

1010
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
1111
--> $DIR/method-call-err-msg.rs:27:7
1212
|
1313
17 | fn one(self, _: isize) -> Foo { self }
14-
| -------------------------------------- defined here
14+
| ----------------------------- defined here
1515
...
1616
27 | .one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied
1717
| ^^^ expected 1 parameter
1818

1919
error[E0061]: this function takes 2 parameters but 1 parameter was supplied
20-
--> $DIR/method-call-err-msg.rs:29:11
20+
--> $DIR/method-call-err-msg.rs:29:7
2121
|
2222
19 | fn two(self, _: isize, _: isize) -> Foo { self }
23-
| ------------------------------------------------ defined here
23+
| --------------------------------------- defined here
2424
...
2525
29 | .two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
26-
| ^ expected 2 parameters
26+
| ^^^ expected 2 parameters
2727

2828
error[E0599]: no method named `take` found for type `Foo` in the current scope
2929
--> $DIR/method-call-err-msg.rs:34:7

src/test/ui/mismatched_types/E0631.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0631]: type mismatch in closure arguments
22
--> $DIR/E0631.rs:17:5
33
|
44
17 | foo(|_: isize| {}); //~ ERROR type mismatch
5-
| ^^^ ------------- found signature of `fn(isize) -> _`
5+
| ^^^ ---------- found signature of `fn(isize) -> _`
66
| |
77
| expected signature of `fn(usize) -> _`
88
|
@@ -12,7 +12,7 @@ error[E0631]: type mismatch in closure arguments
1212
--> $DIR/E0631.rs:18:5
1313
|
1414
18 | bar(|_: isize| {}); //~ ERROR type mismatch
15-
| ^^^ ------------- found signature of `fn(isize) -> _`
15+
| ^^^ ---------- found signature of `fn(isize) -> _`
1616
| |
1717
| expected signature of `fn(usize) -> _`
1818
|
@@ -21,22 +21,22 @@ error[E0631]: type mismatch in closure arguments
2121
error[E0631]: type mismatch in function arguments
2222
--> $DIR/E0631.rs:19:5
2323
|
24+
16 | fn f(_: u64) {}
25+
| ------------ found signature of `fn(u64) -> _`
26+
...
2427
19 | foo(f); //~ ERROR type mismatch
25-
| ^^^
26-
| |
27-
| expected signature of `fn(usize) -> _`
28-
| found signature of `fn(u64) -> _`
28+
| ^^^ expected signature of `fn(usize) -> _`
2929
|
3030
= note: required by `foo`
3131

3232
error[E0631]: type mismatch in function arguments
3333
--> $DIR/E0631.rs:20:5
3434
|
35+
16 | fn f(_: u64) {}
36+
| ------------ found signature of `fn(u64) -> _`
37+
...
3538
20 | bar(f); //~ ERROR type mismatch
36-
| ^^^
37-
| |
38-
| expected signature of `fn(usize) -> _`
39-
| found signature of `fn(u64) -> _`
39+
| ^^^ expected signature of `fn(usize) -> _`
4040
|
4141
= note: required by `bar`
4242

src/test/ui/mismatched_types/closure-arg-count.rs

+7
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@ fn main() {
2727
//~^ ERROR closure is expected to take
2828
let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i);
2929
//~^ ERROR closure is expected to take
30+
let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
31+
//~^ ERROR function is expected to take
32+
let bar = |i, x, y| i;
33+
let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
34+
//~^ ERROR closure is expected to take
3035
}
36+
37+
fn foo() {}

src/test/ui/mismatched_types/closure-arg-count.stderr

+18-1
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,22 @@ error[E0593]: closure is expected to take a single 2-tuple as argument, but it t
5656
| |
5757
| expected closure that takes a single 2-tuple as argument
5858

59-
error: aborting due to 7 previous errors
59+
error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments
60+
--> $DIR/closure-arg-count.rs:30:53
61+
|
62+
30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
63+
| ^^^ expected function that takes a single 2-tuple as argument
64+
...
65+
37 | fn foo() {}
66+
| -------- takes 0 arguments
67+
68+
error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
69+
--> $DIR/closure-arg-count.rs:33:53
70+
|
71+
32 | let bar = |i, x, y| i;
72+
| --------- takes 3 distinct arguments
73+
33 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
74+
| ^^^ expected closure that takes a single 2-tuple as argument
75+
76+
error: aborting due to 9 previous errors
6077

src/test/ui/mismatched_types/fn-variance-1.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
// except according to those terms.
1010

1111
fn takes_imm(x: &isize) { }
12+
//~^ NOTE found signature
1213

1314
fn takes_mut(x: &mut isize) { }
15+
//~^ NOTE found signature
1416

1517
fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
1618
f(t)
@@ -22,12 +24,10 @@ fn main() {
2224
//~^ ERROR type mismatch
2325
//~| NOTE required by `apply`
2426
//~| NOTE expected signature
25-
//~| NOTE found signature
2627

2728
apply(&mut 3, takes_mut);
2829
apply(&mut 3, takes_imm);
2930
//~^ ERROR type mismatch
3031
//~| NOTE required by `apply`
3132
//~| NOTE expected signature
32-
//~| NOTE found signature
3333
}

src/test/ui/mismatched_types/fn-variance-1.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
error[E0631]: type mismatch in function arguments
2-
--> $DIR/fn-variance-1.rs:21:5
2+
--> $DIR/fn-variance-1.rs:23:5
33
|
4-
21 | apply(&3, takes_mut);
5-
| ^^^^^
6-
| |
7-
| expected signature of `fn(&{integer}) -> _`
8-
| found signature of `for<'r> fn(&'r mut isize) -> _`
4+
14 | fn takes_mut(x: &mut isize) { }
5+
| --------------------------- found signature of `for<'r> fn(&'r mut isize) -> _`
6+
...
7+
23 | apply(&3, takes_mut);
8+
| ^^^^^ expected signature of `fn(&{integer}) -> _`
99
|
1010
= note: required by `apply`
1111

1212
error[E0631]: type mismatch in function arguments
13-
--> $DIR/fn-variance-1.rs:28:5
13+
--> $DIR/fn-variance-1.rs:29:5
1414
|
15-
28 | apply(&mut 3, takes_imm);
16-
| ^^^^^
17-
| |
18-
| expected signature of `fn(&mut {integer}) -> _`
19-
| found signature of `for<'r> fn(&'r isize) -> _`
15+
11 | fn takes_imm(x: &isize) { }
16+
| ----------------------- found signature of `for<'r> fn(&'r isize) -> _`
17+
...
18+
29 | apply(&mut 3, takes_imm);
19+
| ^^^^^ expected signature of `fn(&mut {integer}) -> _`
2020
|
2121
= note: required by `apply`
2222

src/test/ui/mismatched_types/overloaded-calls-bad.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ error[E0057]: this function takes 1 parameter but 0 parameters were supplied
1414
| ^^^ expected 1 parameter
1515

1616
error[E0057]: this function takes 1 parameter but 2 parameters were supplied
17-
--> $DIR/overloaded-calls-bad.rs:44:17
17+
--> $DIR/overloaded-calls-bad.rs:44:15
1818
|
1919
44 | let ans = s("burma", "shave");
20-
| ^^^^^^^^^^^^^^^^ expected 1 parameter
20+
| ^^^^^^^^^^^^^^^^^^^ expected 1 parameter
2121

2222
error: aborting due to 3 previous errors
2323

src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0631]: type mismatch in closure arguments
22
--> $DIR/unboxed-closures-vtable-mismatch.rs:24:13
33
|
44
22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
5-
| -------------------------------------------------- found signature of `fn(usize, isize) -> _`
5+
| ----------------------------- found signature of `fn(usize, isize) -> _`
66
23 | //~^ NOTE found signature of `fn(usize, isize)
77
24 | let z = call_it(3, f);
88
| ^^^^^^^ expected signature of `fn(isize, isize) -> _`

src/test/ui/span/E0057.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ error[E0057]: this function takes 1 parameter but 0 parameters were supplied
55
| ^^^ expected 1 parameter
66

77
error[E0057]: this function takes 1 parameter but 2 parameters were supplied
8-
--> $DIR/E0057.rs:15:15
8+
--> $DIR/E0057.rs:15:13
99
|
1010
15 | let c = f(2, 3); //~ ERROR E0057
11-
| ^^^^ expected 1 parameter
11+
| ^^^^^^^ expected 1 parameter
1212

1313
error: aborting due to 2 previous errors
1414

0 commit comments

Comments
 (0)