Skip to content

Commit

Permalink
On mismatched argument count point at arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Feb 11, 2020
1 parent a19edd6 commit 683ebc2
Show file tree
Hide file tree
Showing 35 changed files with 214 additions and 105 deletions.
54 changes: 47 additions & 7 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3761,17 +3761,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error_code: &str,
c_variadic: bool,
sugg_unit: bool| {
let (span, start_span, args) = match &expr.kind {
hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
hir::ExprKind::MethodCall(path_segment, span, args) => (
*span,
// `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
path_segment
.args
.and_then(|args| args.args.iter().last())
// Account for `foo.bar::<T>()`.
.map(|arg| {
// Skip the closing `>`.
tcx.sess
.source_map()
.next_point(tcx.sess.source_map().next_point(arg.span()))
})
.unwrap_or(*span),
&args[1..], // Skip the receiver.
),
k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
};
let arg_spans = if args.is_empty() {
// foo()
// ^^^-- supplied 0 arguments
// |
// expected 2 arguments
vec![tcx.sess.source_map().next_point(start_span).with_hi(sp.hi())]
} else {
// foo(1, 2, 3)
// ^^^ - - - supplied 3 arguments
// |
// expected 2 arguments
args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
};

let mut err = tcx.sess.struct_span_err_with_code(
sp,
span,
&format!(
"this function takes {}{} but {} {} supplied",
if c_variadic { "at least " } else { "" },
potentially_plural_count(expected_count, "parameter"),
potentially_plural_count(arg_count, "parameter"),
potentially_plural_count(expected_count, "argument"),
potentially_plural_count(arg_count, "argument"),
if arg_count == 1 { "was" } else { "were" }
),
DiagnosticId::Error(error_code.to_owned()),
);
let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
for (i, span) in arg_spans.into_iter().enumerate() {
err.span_label(
span,
if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
);
}

if let Some(def_s) = def_span.map(|sp| tcx.sess.source_map().def_span(sp)) {
err.span_label(def_s, "defined here");
Expand All @@ -3788,11 +3829,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
} else {
err.span_label(
sp,
span,
format!(
"expected {}{}",
if c_variadic { "at least " } else { "" },
potentially_plural_count(expected_count, "parameter")
potentially_plural_count(expected_count, "argument")
),
);
}
Expand Down Expand Up @@ -5494,8 +5535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

self.tcx.sess.span_err(
span,
"this function can only be invoked \
directly, not through a function pointer",
"this function can only be invoked directly, not through a function pointer",
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/arg-count-mismatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// error-pattern: parameters were supplied
// error-pattern: arguments were supplied

fn f(x: isize) { }

Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/arg-count-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/arg-count-mismatch.rs:5:28
|
LL | fn f(x: isize) { }
| -------------- defined here
LL |
LL | fn main() { let i: (); i = f(); }
| ^^^ expected 1 parameter
| ^-- supplied 0 arguments
| |
| expected 1 argument

error: aborting due to previous error

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/c-variadic/variadic-ffi-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ 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
foo(1); //~ ERROR this function takes at least 2 parameters but 1 parameter was supplied
foo(); //~ ERROR this function takes at least 2 arguments but 0 arguments were supplied
foo(1); //~ ERROR this function takes at least 2 arguments but 1 argument was supplied

let x: unsafe extern "C" fn(f: isize, x: u8) = foo; //~ ERROR mismatched types
let y: extern "C" fn(f: isize, x: u8, ...) = bar; //~ ERROR mismatched types
Expand Down
12 changes: 8 additions & 4 deletions src/test/ui/c-variadic/variadic-ffi-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,27 @@ error[E0045]: C-variadic function must have C or cdecl calling convention
LL | fn printf(_: *const u8, ...);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention

error[E0060]: this function takes at least 2 parameters but 0 parameters were supplied
error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
--> $DIR/variadic-ffi-1.rs:16:9
|
LL | fn foo(f: isize, x: u8, ...);
| ----------------------------- defined here
...
LL | foo();
| ^^^^^ expected at least 2 parameters
| ^^^-- supplied 0 arguments
| |
| expected at least 2 arguments

error[E0060]: this function takes at least 2 parameters but 1 parameter was supplied
error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
--> $DIR/variadic-ffi-1.rs:17:9
|
LL | fn foo(f: isize, x: u8, ...);
| ----------------------------- defined here
...
LL | foo(1);
| ^^^^^^ expected at least 2 parameters
| ^^^ - supplied 1 argument
| |
| expected at least 2 arguments

error[E0308]: mismatched types
--> $DIR/variadic-ffi-1.rs:19:56
Expand Down
12 changes: 8 additions & 4 deletions src/test/ui/error-codes/E0057.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
error[E0057]: this function takes 1 parameter but 0 parameters were supplied
error[E0057]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/E0057.rs:3:13
|
LL | let a = f();
| ^^^ expected 1 parameter
| ^-- supplied 0 arguments
| |
| expected 1 argument

error[E0057]: this function takes 1 parameter but 2 parameters were supplied
error[E0057]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/E0057.rs:5:13
|
LL | let c = f(2, 3);
| ^^^^^^^ expected 1 parameter
| ^ - - supplied 2 arguments
| |
| expected 1 argument

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0060.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ extern "C" {
fn main() {
unsafe { printf(); }
//~^ ERROR E0060
//~| expected at least 1 parameter
//~| expected at least 1 argument
}
6 changes: 4 additions & 2 deletions src/test/ui/error-codes/E0060.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0060]: this function takes at least 1 parameter but 0 parameters were supplied
error[E0060]: this function takes at least 1 argument but 0 arguments were supplied
--> $DIR/E0060.rs:6:14
|
LL | fn printf(_: *const u8, ...) -> u32;
| ------------------------------------ defined here
...
LL | unsafe { printf(); }
| ^^^^^^^^ expected at least 1 parameter
| ^^^^^^-- supplied 0 arguments
| |
| expected at least 1 argument

error: aborting due to previous error

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/error-codes/E0061.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ fn f2(a: u16) {}
fn main() {
f(0);
//~^ ERROR E0061
//~| expected 2 parameters
//~| expected 2 arguments

f2();
//~^ ERROR E0061
//~| expected 1 parameter
//~| expected 1 argument
}
12 changes: 8 additions & 4 deletions src/test/ui/error-codes/E0061.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
error[E0061]: this function takes 2 parameters but 1 parameter was supplied
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/E0061.rs:6:5
|
LL | fn f(a: u16, b: &str) {}
| --------------------- defined here
...
LL | f(0);
| ^^^^ expected 2 parameters
| ^ - supplied 1 argument
| |
| expected 2 arguments

error[E0061]: this function takes 1 parameter but 0 parameters were supplied
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/E0061.rs:10:5
|
LL | fn f2(a: u16) {}
| ------------- defined here
...
LL | f2();
| ^^^^ expected 1 parameter
| ^^-- supplied 0 arguments
| |
| expected 1 argument

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/hrtb/issue-58451.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ where
{}

fn main() {
f(&[f()]); //~ ERROR this function takes 1 parameter
f(&[f()]); //~ ERROR this function takes 1 argument
}
6 changes: 4 additions & 2 deletions src/test/ui/hrtb/issue-58451.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> $DIR/issue-58451.rs:12:9
|
LL | / fn f<I>(i: I)
Expand All @@ -9,7 +9,9 @@ LL | | {}
| |__- defined here
...
LL | f(&[f()]);
| ^^^ expected 1 parameter
| ^-- supplied 0 arguments
| |
| expected 1 argument

error: aborting due to previous error

Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/issues/issue-16939.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0057]: this function takes 0 parameters but 1 parameter was supplied
error[E0057]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/issue-16939.rs:5:9
|
LL | |t| f(t);
| ^^^^ expected 0 parameters
| ^ - supplied 1 argument
| |
| expected 0 arguments

error: aborting due to previous error

Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/issues/issue-18819.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0061]: this function takes 2 parameters but 1 parameter was supplied
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/issue-18819.rs:16:5
|
LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
| ----------------------------------------------- defined here
...
LL | print_x(X);
| ^^^^^^^^^^ expected 2 parameters
| ^^^^^^^ - supplied 1 argument
| |
| expected 2 arguments

error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/issues/issue-26094.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
macro_rules! some_macro {
($other: expr) => ({
$other(None)
//~^ this function takes 0 parameters but 1 parameter was supplied
$other(None) //~ NOTE supplied 1 argument
})
}

fn some_function() {}
fn some_function() {} //~ NOTE defined here

fn main() {
some_macro!(some_function);
//~^ in this expansion of some_macro!
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
//~| NOTE expected 0 arguments
}
10 changes: 4 additions & 6 deletions src/test/ui/issues/issue-26094.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
error[E0061]: this function takes 0 parameters but 1 parameter was supplied
--> $DIR/issue-26094.rs:3:9
error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/issue-26094.rs:10:17
|
LL | $other(None)
| ^^^^^^^^^^^^ expected 0 parameters
| ---- supplied 1 argument
...
LL | fn some_function() {}
| ------------------ defined here
...
LL | some_macro!(some_function);
| --------------------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
| ^^^^^^^^^^^^^ expected 0 arguments

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-3044.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ fn main() {
let needlesArr: Vec<char> = vec!['a', 'f'];
needlesArr.iter().fold(|x, y| {
});
//~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
//~^^ ERROR this function takes 2 arguments but 1 argument was supplied
}
10 changes: 7 additions & 3 deletions src/test/ui/issues/issue-3044.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error[E0061]: this function takes 2 parameters but 1 parameter was supplied
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/issue-3044.rs:3:23
|
LL | needlesArr.iter().fold(|x, y| {
| ^^^^ expected 2 parameters
LL | needlesArr.iter().fold(|x, y| {
| _______________________^^^^_-
| | |
| | expected 2 arguments
LL | | });
| |_____- supplied 1 argument

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-4935.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
fn foo(a: usize) {}
//~^ defined here
fn main() { foo(5, 6) }
//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
//~^ ERROR this function takes 1 argument but 2 arguments were supplied
6 changes: 4 additions & 2 deletions src/test/ui/issues/issue-4935.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0061]: this function takes 1 parameter but 2 parameters were supplied
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/issue-4935.rs:5:13
|
LL | fn foo(a: usize) {}
| ---------------- defined here
LL |
LL | fn main() { foo(5, 6) }
| ^^^^^^^^^ expected 1 parameter
| ^^^ - - supplied 2 arguments
| |
| expected 1 argument

error: aborting due to previous error

Expand Down
8 changes: 5 additions & 3 deletions src/test/ui/methods/method-call-err-msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ impl Foo {
fn zero(self) -> Foo { self }
fn one(self, _: isize) -> Foo { self }
fn two(self, _: isize, _: isize) -> Foo { self }
fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
}

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
.two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
x.zero(0) //~ ERROR this function takes 0 arguments but 1 argument was supplied
.one() //~ ERROR this function takes 1 argument but 0 arguments were supplied
.two(0); //~ ERROR this function takes 2 arguments but 1 argument was supplied

let y = Foo;
y.zero()
.take() //~ ERROR no method named `take` found
.one(0);
y.three::<usize>(); //~ ERROR this function takes 3 arguments but 0 arguments were supplied
}
Loading

0 comments on commit 683ebc2

Please sign in to comment.