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) { 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) { 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::>(); - 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, 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, &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