diff options
| author | bors <bors@rust-lang.org> | 2016-12-06 00:17:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-06 00:17:24 +0000 |
| commit | 09991241fd75ec69281d06c8f907d2e9f61ac5e2 (patch) | |
| tree | 9a669760f99a625b7150987db9cac4d9f9107c86 | |
| parent | daf8c1dfce3b448fc581cc319f64632ec22bd0e1 (diff) | |
| parent | c735d7f2a53d6b3ecf9151e43066f8a30f42921c (diff) | |
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
| -rw-r--r-- | src/librustc_typeck/check/callee.rs | 16 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 47 | ||||
| -rw-r--r-- | src/test/compile-fail/E0060.rs | 3 | ||||
| -rw-r--r-- | src/test/compile-fail/E0061.rs | 7 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-18819.rs | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-3044.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-4935.rs | 3 | ||||
| -rw-r--r-- | src/test/compile-fail/method-call-err-msg.rs | 8 | ||||
| -rw-r--r-- | src/test/compile-fail/not-enough-arguments.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/overloaded-calls-bad.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/variadic-ffi-3.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/span/E0057.stderr | 8 |
12 files changed, 59 insertions, 59 deletions
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 6d00f481fa2..5b17b37e279 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -193,9 +193,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { -> Ty<'tcx> { let error_fn_sig; - let fn_sig = match callee_ty.sty { - ty::TyFnDef(.., &ty::BareFnTy {ref sig, ..}) | - ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => sig, + let (fn_sig, def_span) = match callee_ty.sty { + ty::TyFnDef(def_id, .., &ty::BareFnTy {ref sig, ..}) => { + (sig, self.tcx.map.span_if_local(def_id)) + } + ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => (sig, None), ref t => { let mut unit_variant = None; if let &ty::TyAdt(adt_def, ..) = t { @@ -241,7 +243,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { variadic: false, }); - &error_fn_sig + (&error_fn_sig, None) } }; @@ -266,7 +268,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &expected_arg_tys[..], arg_exprs, fn_sig.variadic, - TupleArgumentsFlag::DontTupleArguments); + TupleArgumentsFlag::DontTupleArguments, + def_span); fn_sig.output } @@ -292,7 +295,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &expected_arg_tys, arg_exprs, fn_sig.variadic, - TupleArgumentsFlag::TupleArguments); + TupleArgumentsFlag::TupleArguments, + None); fn_sig.output } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 764ea944556..1950adf8329 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2467,17 +2467,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr, - false, tuple_arguments); + false, tuple_arguments, None); self.tcx.types.err } else { match method_fn_ty.sty { - ty::TyFnDef(.., ref fty) => { + ty::TyFnDef(def_id, .., ref fty) => { // HACK(eddyb) ignore self in the definition (see above). let expected_arg_tys = self.expected_types_for_fn_args(sp, expected, fty.sig.0.output, &fty.sig.0.inputs[1..]); + self.check_argument_types(sp, &fty.sig.0.inputs[1..], &expected_arg_tys[..], - args_no_rcvr, fty.sig.0.variadic, tuple_arguments); + args_no_rcvr, fty.sig.0.variadic, tuple_arguments, + self.tcx.map.span_if_local(def_id)); fty.sig.0.output } _ => { @@ -2495,7 +2497,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected_arg_tys: &[Ty<'tcx>], args: &'gcx [hir::Expr], variadic: bool, - tuple_arguments: TupleArgumentsFlag) { + tuple_arguments: TupleArgumentsFlag, + def_span: Option<Span>) { let tcx = self.tcx; // Grab the argument types, supplying fresh type variables @@ -2530,9 +2533,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { sp }; - fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>], - expected_count: usize, arg_count: usize, error_code: &str, - variadic: bool) { + fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize, + arg_count: usize, error_code: &str, variadic: bool, + def_span: Option<Span>) { let mut err = sess.struct_span_err_with_code(sp, &format!("this function takes {}{} parameter{} but {} parameter{} supplied", if variadic {"at least "} else {""}, @@ -2542,18 +2545,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if arg_count == 1 {" was"} else {"s were"}), error_code); - let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>(); - if input_types.len() > 1 { - err.note("the following parameter types were expected:"); - err.note(&input_types.join(", ")); - } else if input_types.len() > 0 { - err.note(&format!("the following parameter type was expected: {}", - input_types[0])); - } else { - err.span_label(sp, &format!("expected {}{} parameter{}", - if variadic {"at least "} else {""}, - expected_count, - if expected_count == 1 {""} else {"s"})); + err.span_label(sp, &format!("expected {}{} parameter{}", + if variadic {"at least "} else {""}, + expected_count, + if expected_count == 1 {""} else {"s"})); + if let Some(def_s) = def_span { + err.span_label(def_s, &format!("defined here")); } err.emit(); } @@ -2562,8 +2559,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]); match tuple_type.sty { ty::TyTuple(arg_types) if arg_types.len() != args.len() => { - parameter_count_error(tcx.sess, sp_args, fn_inputs, arg_types.len(), args.len(), - "E0057", false); + parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(), + "E0057", false, def_span); expected_arg_tys = &[]; self.err_args(args.len()) } @@ -2591,14 +2588,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if supplied_arg_count >= expected_arg_count { fn_inputs.to_vec() } else { - parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count, - supplied_arg_count, "E0060", true); + parameter_count_error(tcx.sess, sp_args, expected_arg_count, + supplied_arg_count, "E0060", true, def_span); expected_arg_tys = &[]; self.err_args(supplied_arg_count) } } else { - parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count, - supplied_arg_count, "E0061", false); + parameter_count_error(tcx.sess, sp_args, expected_arg_count, + supplied_arg_count, "E0061", false, def_span); expected_arg_tys = &[]; self.err_args(supplied_arg_count) }; diff --git a/src/test/compile-fail/E0060.rs b/src/test/compile-fail/E0060.rs index 5182a2bf5a0..8246c42a4d4 100644 --- a/src/test/compile-fail/E0060.rs +++ b/src/test/compile-fail/E0060.rs @@ -10,10 +10,11 @@ extern "C" { fn printf(_: *const u8, ...) -> u32; + //~^ NOTE defined here } fn main() { unsafe { printf(); } //~^ ERROR E0060 - //~| NOTE the following parameter type was expected: *const u8 + //~| expected at least 1 parameter } diff --git a/src/test/compile-fail/E0061.rs b/src/test/compile-fail/E0061.rs index 4c7c0dfd44c..ebd4ad2e292 100644 --- a/src/test/compile-fail/E0061.rs +++ b/src/test/compile-fail/E0061.rs @@ -9,16 +9,17 @@ // except according to those terms. fn f(a: u16, b: &str) {} +//~^ NOTE defined here fn f2(a: u16) {} +//~^ NOTE defined here fn main() { f(0); //~^ ERROR E0061 - //~| NOTE the following parameter types were expected: - //~| NOTE u16, &str + //~| expected 2 parameters f2(); //~^ ERROR E0061 - //~| NOTE the following parameter type was expected: u16 + //~| expected 1 parameter } diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs index 8035d798e32..148eea31ec6 100644 --- a/src/test/compile-fail/issue-18819.rs +++ b/src/test/compile-fail/issue-18819.rs @@ -19,12 +19,12 @@ impl Foo for X { } fn print_x(_: &Foo<Item=bool>, extra: &str) { + //~^ NOTE defined here println!("{}", extra); } fn main() { print_x(X); - //~^ ERROR this function takes 2 parameters but 1 parameter was supplied - //~| NOTE the following parameter types were expected: - //~| NOTE &Foo<Item=bool>, &str + //~^ ERROR E0061 + //~| NOTE expected 2 parameters } diff --git a/src/test/compile-fail/issue-3044.rs b/src/test/compile-fail/issue-3044.rs index c7b276da573..4c63f7761a6 100644 --- a/src/test/compile-fail/issue-3044.rs +++ b/src/test/compile-fail/issue-3044.rs @@ -14,7 +14,5 @@ fn main() { needlesArr.iter().fold(|x, y| { }); //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied - //~| NOTE the following parameter types were expected - //~| NOTE _, _ - // the first error is, um, non-ideal. + //~| NOTE expected 2 parameters } diff --git a/src/test/compile-fail/issue-4935.rs b/src/test/compile-fail/issue-4935.rs index 08707a187df..e9f8367378a 100644 --- a/src/test/compile-fail/issue-4935.rs +++ b/src/test/compile-fail/issue-4935.rs @@ -11,6 +11,7 @@ // Regression test for issue #4935 fn foo(a: usize) {} +//~^ defined here fn main() { foo(5, 6) } //~^ ERROR this function takes 1 parameter but 2 parameters were supplied -//~| NOTE the following parameter type was expected +//~| NOTE expected 1 parameter diff --git a/src/test/compile-fail/method-call-err-msg.rs b/src/test/compile-fail/method-call-err-msg.rs index b7e0c5b81d9..b8eb8434b35 100644 --- a/src/test/compile-fail/method-call-err-msg.rs +++ b/src/test/compile-fail/method-call-err-msg.rs @@ -13,8 +13,11 @@ pub struct Foo; impl Foo { fn zero(self) -> Foo { self } + //~^ NOTE defined here fn one(self, _: isize) -> Foo { self } + //~^ NOTE defined here fn two(self, _: isize, _: isize) -> Foo { self } + //~^ NOTE defined here } fn main() { @@ -22,10 +25,9 @@ fn main() { x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied //~^ NOTE expected 0 parameters .one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied - //~^ NOTE the following parameter type was expected + //~^ NOTE expected 1 parameter .two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied - //~^ NOTE the following parameter types were expected - //~| NOTE isize, isize + //~^ NOTE expected 2 parameters let y = Foo; y.zero() diff --git a/src/test/compile-fail/not-enough-arguments.rs b/src/test/compile-fail/not-enough-arguments.rs index 660d48da4db..e13008df0d9 100644 --- a/src/test/compile-fail/not-enough-arguments.rs +++ b/src/test/compile-fail/not-enough-arguments.rs @@ -13,12 +13,12 @@ // unrelated errors. fn foo(a: isize, b: isize, c: isize, d:isize) { + //~^ NOTE defined here panic!(); } fn main() { foo(1, 2, 3); //~^ ERROR this function takes 4 parameters but 3 - //~| NOTE the following parameter types were expected: - //~| NOTE isize, isize, isize, isize + //~| NOTE expected 4 parameters } diff --git a/src/test/compile-fail/overloaded-calls-bad.rs b/src/test/compile-fail/overloaded-calls-bad.rs index 1b8284debb4..3295e2bebd2 100644 --- a/src/test/compile-fail/overloaded-calls-bad.rs +++ b/src/test/compile-fail/overloaded-calls-bad.rs @@ -41,8 +41,8 @@ fn main() { //~| NOTE found type let ans = s(); //~^ ERROR this function takes 1 parameter but 0 parameters were supplied - //~| NOTE the following parameter type was expected + //~| NOTE expected 1 parameter let ans = s("burma", "shave"); //~^ ERROR this function takes 1 parameter but 2 parameters were supplied - //~| NOTE the following parameter type was expected + //~| NOTE expected 1 parameter } diff --git a/src/test/compile-fail/variadic-ffi-3.rs b/src/test/compile-fail/variadic-ffi-3.rs index 334b8bb08ae..565d8549b37 100644 --- a/src/test/compile-fail/variadic-ffi-3.rs +++ b/src/test/compile-fail/variadic-ffi-3.rs @@ -10,6 +10,8 @@ extern { fn foo(f: isize, x: u8, ...); + //~^ defined here + //~| defined here } extern "C" fn bar(f: isize, x: u8) {} @@ -17,11 +19,9 @@ extern "C" fn bar(f: isize, x: u8) {} fn main() { unsafe { foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied - //~^ NOTE the following parameter types were expected: - //~| NOTE isize, u8 + //~| NOTE expected at least 2 parameters foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied - //~^ NOTE the following parameter types were expected: - //~| NOTE isize, u8 + //~| NOTE expected at least 2 parameters let x: unsafe extern "C" fn(f: isize, x: u8) = foo; //~^ ERROR: mismatched types diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr index 656fdbe2b29..0d6b0a552e4 100644 --- a/src/test/ui/span/E0057.stderr +++ b/src/test/ui/span/E0057.stderr @@ -2,17 +2,13 @@ error[E0057]: this function takes 1 parameter but 0 parameters were supplied --> $DIR/E0057.rs:13:13 | 13 | let a = f(); //~ ERROR E0057 - | ^^^ - | - = note: the following parameter type was expected: (_,) + | ^^^ expected 1 parameter error[E0057]: this function takes 1 parameter but 2 parameters were supplied --> $DIR/E0057.rs:15:15 | 15 | let c = f(2, 3); //~ ERROR E0057 - | ^^^^ - | - = note: the following parameter type was expected: (_,) + | ^^^^ expected 1 parameter error: aborting due to 2 previous errors |
