Skip to content

Commit 0999124

Browse files
committed
Auto merge of #38121 - jonathandturner:better_e0061, r=nikomatsakis
Point arg num mismatch errors back to their definition This PR updates the arg num errors (like E0061) to point back at the function definition where they were defined. Before: ``` error[E0061]: this function takes 2 parameters but 1 parameter was supplied --> E0061.rs:18:7 | 18 | f(0); | ^ | = note: the following parameter types were expected: = note: u16, &str ``` Now: ``` error[E0061]: this function takes 2 parameters but 1 parameter was supplied --> E0061.rs:18:7 | 11 | fn f(a: u16, b: &str) {} | ------------------------ defined here ... 18 | f(0); | ^ expected 2 parameters ``` This is an incremental improvement. We probably want to underline only the function name and also have support for functions defined in crates outside of the current crate. r? @nikomatsakis
2 parents daf8c1d + c735d7f commit 0999124

12 files changed

+59
-59
lines changed

src/librustc_typeck/check/callee.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
193193
-> Ty<'tcx> {
194194
let error_fn_sig;
195195

196-
let fn_sig = match callee_ty.sty {
197-
ty::TyFnDef(.., &ty::BareFnTy {ref sig, ..}) |
198-
ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => sig,
196+
let (fn_sig, def_span) = match callee_ty.sty {
197+
ty::TyFnDef(def_id, .., &ty::BareFnTy {ref sig, ..}) => {
198+
(sig, self.tcx.map.span_if_local(def_id))
199+
}
200+
ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => (sig, None),
199201
ref t => {
200202
let mut unit_variant = None;
201203
if let &ty::TyAdt(adt_def, ..) = t {
@@ -241,7 +243,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
241243
variadic: false,
242244
});
243245

244-
&error_fn_sig
246+
(&error_fn_sig, None)
245247
}
246248
};
247249

@@ -266,7 +268,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
266268
&expected_arg_tys[..],
267269
arg_exprs,
268270
fn_sig.variadic,
269-
TupleArgumentsFlag::DontTupleArguments);
271+
TupleArgumentsFlag::DontTupleArguments,
272+
def_span);
270273

271274
fn_sig.output
272275
}
@@ -292,7 +295,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
292295
&expected_arg_tys,
293296
arg_exprs,
294297
fn_sig.variadic,
295-
TupleArgumentsFlag::TupleArguments);
298+
TupleArgumentsFlag::TupleArguments,
299+
None);
296300

297301
fn_sig.output
298302
}

src/librustc_typeck/check/mod.rs

+22-25
Original file line numberDiff line numberDiff line change
@@ -2467,17 +2467,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24672467
};
24682468

24692469
self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
2470-
false, tuple_arguments);
2470+
false, tuple_arguments, None);
24712471
self.tcx.types.err
24722472
} else {
24732473
match method_fn_ty.sty {
2474-
ty::TyFnDef(.., ref fty) => {
2474+
ty::TyFnDef(def_id, .., ref fty) => {
24752475
// HACK(eddyb) ignore self in the definition (see above).
24762476
let expected_arg_tys = self.expected_types_for_fn_args(sp, expected,
24772477
fty.sig.0.output,
24782478
&fty.sig.0.inputs[1..]);
2479+
24792480
self.check_argument_types(sp, &fty.sig.0.inputs[1..], &expected_arg_tys[..],
2480-
args_no_rcvr, fty.sig.0.variadic, tuple_arguments);
2481+
args_no_rcvr, fty.sig.0.variadic, tuple_arguments,
2482+
self.tcx.map.span_if_local(def_id));
24812483
fty.sig.0.output
24822484
}
24832485
_ => {
@@ -2495,7 +2497,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
24952497
expected_arg_tys: &[Ty<'tcx>],
24962498
args: &'gcx [hir::Expr],
24972499
variadic: bool,
2498-
tuple_arguments: TupleArgumentsFlag) {
2500+
tuple_arguments: TupleArgumentsFlag,
2501+
def_span: Option<Span>) {
24992502
let tcx = self.tcx;
25002503

25012504
// Grab the argument types, supplying fresh type variables
@@ -2530,9 +2533,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25302533
sp
25312534
};
25322535

2533-
fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
2534-
expected_count: usize, arg_count: usize, error_code: &str,
2535-
variadic: bool) {
2536+
fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
2537+
arg_count: usize, error_code: &str, variadic: bool,
2538+
def_span: Option<Span>) {
25362539
let mut err = sess.struct_span_err_with_code(sp,
25372540
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
25382541
if variadic {"at least "} else {""},
@@ -2542,18 +2545,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25422545
if arg_count == 1 {" was"} else {"s were"}),
25432546
error_code);
25442547

2545-
let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
2546-
if input_types.len() > 1 {
2547-
err.note("the following parameter types were expected:");
2548-
err.note(&input_types.join(", "));
2549-
} else if input_types.len() > 0 {
2550-
err.note(&format!("the following parameter type was expected: {}",
2551-
input_types[0]));
2552-
} else {
2553-
err.span_label(sp, &format!("expected {}{} parameter{}",
2554-
if variadic {"at least "} else {""},
2555-
expected_count,
2556-
if expected_count == 1 {""} else {"s"}));
2548+
err.span_label(sp, &format!("expected {}{} parameter{}",
2549+
if variadic {"at least "} else {""},
2550+
expected_count,
2551+
if expected_count == 1 {""} else {"s"}));
2552+
if let Some(def_s) = def_span {
2553+
err.span_label(def_s, &format!("defined here"));
25572554
}
25582555
err.emit();
25592556
}
@@ -2562,8 +2559,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25622559
let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
25632560
match tuple_type.sty {
25642561
ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
2565-
parameter_count_error(tcx.sess, sp_args, fn_inputs, arg_types.len(), args.len(),
2566-
"E0057", false);
2562+
parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
2563+
"E0057", false, def_span);
25672564
expected_arg_tys = &[];
25682565
self.err_args(args.len())
25692566
}
@@ -2591,14 +2588,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25912588
if supplied_arg_count >= expected_arg_count {
25922589
fn_inputs.to_vec()
25932590
} else {
2594-
parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count,
2595-
supplied_arg_count, "E0060", true);
2591+
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2592+
supplied_arg_count, "E0060", true, def_span);
25962593
expected_arg_tys = &[];
25972594
self.err_args(supplied_arg_count)
25982595
}
25992596
} else {
2600-
parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count,
2601-
supplied_arg_count, "E0061", false);
2597+
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
2598+
supplied_arg_count, "E0061", false, def_span);
26022599
expected_arg_tys = &[];
26032600
self.err_args(supplied_arg_count)
26042601
};

src/test/compile-fail/E0060.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010

1111
extern "C" {
1212
fn printf(_: *const u8, ...) -> u32;
13+
//~^ NOTE defined here
1314
}
1415

1516
fn main() {
1617
unsafe { printf(); }
1718
//~^ ERROR E0060
18-
//~| NOTE the following parameter type was expected: *const u8
19+
//~| expected at least 1 parameter
1920
}

src/test/compile-fail/E0061.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@
99
// except according to those terms.
1010

1111
fn f(a: u16, b: &str) {}
12+
//~^ NOTE defined here
1213

1314
fn f2(a: u16) {}
15+
//~^ NOTE defined here
1416

1517
fn main() {
1618
f(0);
1719
//~^ ERROR E0061
18-
//~| NOTE the following parameter types were expected:
19-
//~| NOTE u16, &str
20+
//~| expected 2 parameters
2021

2122
f2();
2223
//~^ ERROR E0061
23-
//~| NOTE the following parameter type was expected: u16
24+
//~| expected 1 parameter
2425
}

src/test/compile-fail/issue-18819.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ impl Foo for X {
1919
}
2020

2121
fn print_x(_: &Foo<Item=bool>, extra: &str) {
22+
//~^ NOTE defined here
2223
println!("{}", extra);
2324
}
2425

2526
fn main() {
2627
print_x(X);
27-
//~^ ERROR this function takes 2 parameters but 1 parameter was supplied
28-
//~| NOTE the following parameter types were expected:
29-
//~| NOTE &Foo<Item=bool>, &str
28+
//~^ ERROR E0061
29+
//~| NOTE expected 2 parameters
3030
}

src/test/compile-fail/issue-3044.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,5 @@ fn main() {
1414
needlesArr.iter().fold(|x, y| {
1515
});
1616
//~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
17-
//~| NOTE the following parameter types were expected
18-
//~| NOTE _, _
19-
// the first error is, um, non-ideal.
17+
//~| NOTE expected 2 parameters
2018
}

src/test/compile-fail/issue-4935.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// Regression test for issue #4935
1212

1313
fn foo(a: usize) {}
14+
//~^ defined here
1415
fn main() { foo(5, 6) }
1516
//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
16-
//~| NOTE the following parameter type was expected
17+
//~| NOTE expected 1 parameter

src/test/compile-fail/method-call-err-msg.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@
1313
pub struct Foo;
1414
impl Foo {
1515
fn zero(self) -> Foo { self }
16+
//~^ NOTE defined here
1617
fn one(self, _: isize) -> Foo { self }
18+
//~^ NOTE defined here
1719
fn two(self, _: isize, _: isize) -> Foo { self }
20+
//~^ NOTE defined here
1821
}
1922

2023
fn main() {
2124
let x = Foo;
2225
x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied
2326
//~^ NOTE expected 0 parameters
2427
.one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied
25-
//~^ NOTE the following parameter type was expected
28+
//~^ NOTE expected 1 parameter
2629
.two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
27-
//~^ NOTE the following parameter types were expected
28-
//~| NOTE isize, isize
30+
//~^ NOTE expected 2 parameters
2931

3032
let y = Foo;
3133
y.zero()

src/test/compile-fail/not-enough-arguments.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
// unrelated errors.
1414

1515
fn foo(a: isize, b: isize, c: isize, d:isize) {
16+
//~^ NOTE defined here
1617
panic!();
1718
}
1819

1920
fn main() {
2021
foo(1, 2, 3);
2122
//~^ ERROR this function takes 4 parameters but 3
22-
//~| NOTE the following parameter types were expected:
23-
//~| NOTE isize, isize, isize, isize
23+
//~| NOTE expected 4 parameters
2424
}

src/test/compile-fail/overloaded-calls-bad.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ fn main() {
4141
//~| NOTE found type
4242
let ans = s();
4343
//~^ ERROR this function takes 1 parameter but 0 parameters were supplied
44-
//~| NOTE the following parameter type was expected
44+
//~| NOTE expected 1 parameter
4545
let ans = s("burma", "shave");
4646
//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
47-
//~| NOTE the following parameter type was expected
47+
//~| NOTE expected 1 parameter
4848
}

src/test/compile-fail/variadic-ffi-3.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@
1010

1111
extern {
1212
fn foo(f: isize, x: u8, ...);
13+
//~^ defined here
14+
//~| defined here
1315
}
1416

1517
extern "C" fn bar(f: isize, x: u8) {}
1618

1719
fn main() {
1820
unsafe {
1921
foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied
20-
//~^ NOTE the following parameter types were expected:
21-
//~| NOTE isize, u8
22+
//~| NOTE expected at least 2 parameters
2223
foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied
23-
//~^ NOTE the following parameter types were expected:
24-
//~| NOTE isize, u8
24+
//~| NOTE expected at least 2 parameters
2525

2626
let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
2727
//~^ ERROR: mismatched types

src/test/ui/span/E0057.stderr

+2-6
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,13 @@ error[E0057]: this function takes 1 parameter but 0 parameters were supplied
22
--> $DIR/E0057.rs:13:13
33
|
44
13 | let a = f(); //~ ERROR E0057
5-
| ^^^
6-
|
7-
= note: the following parameter type was expected: (_,)
5+
| ^^^ expected 1 parameter
86

97
error[E0057]: this function takes 1 parameter but 2 parameters were supplied
108
--> $DIR/E0057.rs:15:15
119
|
1210
15 | let c = f(2, 3); //~ ERROR E0057
13-
| ^^^^
14-
|
15-
= note: the following parameter type was expected: (_,)
11+
| ^^^^ expected 1 parameter
1612

1713
error: aborting due to 2 previous errors
1814

0 commit comments

Comments
 (0)