Show types of all args when missing args
When there're missing arguments in a function call, present a list of all the expected types: ```rust fn main() { t(""); } fn t(a: &str, x: String) {} ``` ```bash % rustc file.rs file.rs:3:5: 2:8 error: this function takes 2 parameters but 0 parameters were supplied [E0061] file.rs:3 t(); ^~~ file.rs:3:5: 2:8 help: run `rustc --explain E0061` to see a detailed explanation file.rs:3:5: 2:8 note: the following parameter types were expected: &str, std::string::String error: aborting due to previous error ``` Fixes #33649
This commit is contained in:
parent
ad5fbaf57c
commit
1020e3036b
@ -2407,29 +2407,45 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let mut expected_arg_tys = expected_arg_tys;
|
||||
let expected_arg_count = fn_inputs.len();
|
||||
|
||||
fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
|
||||
expected_count: usize, arg_count: usize, error_code: &str,
|
||||
variadic: bool) {
|
||||
let mut err = sess.struct_span_err_with_code(sp,
|
||||
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
|
||||
if variadic {"at least "} else {""},
|
||||
expected_count,
|
||||
if expected_count == 1 {""} else {"s"},
|
||||
arg_count,
|
||||
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() > 0 {
|
||||
err.note(&format!("the following parameter type{} expected: {}",
|
||||
if expected_count == 1 {" was"} else {"s were"},
|
||||
input_types.join(", ")));
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
let formal_tys = if tuple_arguments == TupleArguments {
|
||||
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, fn_inputs, arg_types.len(), args.len(),
|
||||
"E0057", false);
|
||||
expected_arg_tys = &[];
|
||||
self.err_args(args.len())
|
||||
}
|
||||
ty::TyTuple(arg_types) => {
|
||||
if arg_types.len() != args.len() {
|
||||
span_err!(tcx.sess, sp, E0057,
|
||||
"this function takes {} parameter{} but {} parameter{} supplied",
|
||||
arg_types.len(),
|
||||
if arg_types.len() == 1 {""} else {"s"},
|
||||
args.len(),
|
||||
if args.len() == 1 {" was"} else {"s were"});
|
||||
expected_arg_tys = &[];
|
||||
self.err_args(args.len())
|
||||
} else {
|
||||
expected_arg_tys = match expected_arg_tys.get(0) {
|
||||
Some(&ty) => match ty.sty {
|
||||
ty::TyTuple(ref tys) => &tys,
|
||||
_ => &[]
|
||||
},
|
||||
None => &[]
|
||||
};
|
||||
arg_types.to_vec()
|
||||
}
|
||||
expected_arg_tys = match expected_arg_tys.get(0) {
|
||||
Some(&ty) => match ty.sty {
|
||||
ty::TyTuple(ref tys) => &tys,
|
||||
_ => &[]
|
||||
},
|
||||
None => &[]
|
||||
};
|
||||
arg_types.to_vec()
|
||||
}
|
||||
_ => {
|
||||
span_err!(tcx.sess, sp, E0059,
|
||||
@ -2445,23 +2461,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
if supplied_arg_count >= expected_arg_count {
|
||||
fn_inputs.to_vec()
|
||||
} else {
|
||||
span_err!(tcx.sess, sp, E0060,
|
||||
"this function takes at least {} parameter{} \
|
||||
but {} parameter{} supplied",
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1 {""} else {"s"},
|
||||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count,
|
||||
supplied_arg_count, "E0060", true);
|
||||
expected_arg_tys = &[];
|
||||
self.err_args(supplied_arg_count)
|
||||
}
|
||||
} else {
|
||||
span_err!(tcx.sess, sp, E0061,
|
||||
"this function takes {} parameter{} but {} parameter{} supplied",
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1 {""} else {"s"},
|
||||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, supplied_arg_count,
|
||||
"E0061", false);
|
||||
expected_arg_tys = &[];
|
||||
self.err_args(supplied_arg_count)
|
||||
};
|
||||
|
@ -24,4 +24,5 @@ fn print_x(_: &Foo<Item=bool>, extra: &str) {
|
||||
|
||||
fn main() {
|
||||
print_x(X); //~error this function takes 2 parameters but 1 parameter was supplied
|
||||
//~^ NOTE the following parameter types were expected: &Foo<Item=bool>, &str
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ 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
|
||||
//
|
||||
// the first error is, um, non-ideal.
|
||||
}
|
||||
|
@ -12,3 +12,4 @@
|
||||
|
||||
fn foo(a: usize) {}
|
||||
fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied
|
||||
//~^ NOTE the following parameter type was expected
|
||||
|
@ -21,10 +21,13 @@ fn main() {
|
||||
let x = Foo;
|
||||
x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied
|
||||
.one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied
|
||||
//~^ NOTE the following parameter type was expected
|
||||
.two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
|
||||
//~^ NOTE the following parameter types were expected
|
||||
|
||||
let y = Foo;
|
||||
y.zero()
|
||||
.take() //~ ERROR no method named `take` found for type `Foo` in the current scope
|
||||
//~^ NOTE the method `take` exists but the following trait bounds were not satisfied
|
||||
.one(0);
|
||||
}
|
||||
|
@ -19,4 +19,5 @@ fn foo(a: isize, b: isize, c: isize, d:isize) {
|
||||
fn main() {
|
||||
foo(1, 2, 3);
|
||||
//~^ ERROR this function takes 4 parameters but 3
|
||||
//~^^ NOTE the following parameter types were expected
|
||||
}
|
||||
|
@ -36,7 +36,13 @@ fn main() {
|
||||
y: 3,
|
||||
};
|
||||
let ans = s("what"); //~ ERROR mismatched types
|
||||
let ans = s(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
|
||||
//~^ NOTE expected isize, found &-ptr
|
||||
//~| NOTE expected type
|
||||
//~| NOTE found type
|
||||
let ans = s();
|
||||
//~^ ERROR this function takes 1 parameter but 0 parameters were supplied
|
||||
//~| NOTE the following parameter type was expected
|
||||
let ans = s("burma", "shave");
|
||||
//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
|
||||
//~| NOTE the following parameter type was expected
|
||||
}
|
||||
|
@ -17,7 +17,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
|
||||
foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied
|
||||
//~^ NOTE the following parameter types were expected
|
||||
|
||||
let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
|
||||
//~^ ERROR: mismatched types
|
||||
|
Loading…
x
Reference in New Issue
Block a user