mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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
This commit is contained in:
commit
09991241fd
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user