1
Fork 0

Point arg num mismatch errors back to their definition

This commit is contained in:
Jonathan Turner 2016-12-01 16:33:48 -08:00
parent b30022a1d3
commit c735d7f2a5
12 changed files with 59 additions and 59 deletions

View file

@ -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
}

View file

@ -2465,17 +2465,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
}
_ => {
@ -2493,7 +2495,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
@ -2528,9 +2531,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 {""},
@ -2540,18 +2543,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();
}
@ -2560,8 +2557,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())
}
@ -2589,14 +2586,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)
};

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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

View file

@ -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()

View file

@ -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
}

View file

@ -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
}

View file

@ -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

View file

@ -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