Skip to content

Provide the full span of method calls to check_argument_types #45123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/librustc_typeck/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn_sig.output(),
fn_sig.inputs());
self.check_argument_types(call_expr.span,
call_expr.span,
fn_sig.inputs(),
&expected_arg_tys[..],
arg_exprs,
Expand Down Expand Up @@ -298,6 +299,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn_sig.inputs());

self.check_argument_types(call_expr.span,
call_expr.span,
fn_sig.inputs(),
&expected_arg_tys,
arg_exprs,
Expand All @@ -315,6 +317,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
method_callee: MethodCallee<'tcx>)
-> Ty<'tcx> {
let output_type = self.check_method_argument_types(call_expr.span,
call_expr.span,
Ok(method_callee),
arg_exprs,
TupleArgumentsFlag::TupleArguments,
Expand Down
32 changes: 21 additions & 11 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2352,6 +2352,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

fn check_method_argument_types(&self,
sp: Span,
expr_sp: Span,
method: Result<MethodCallee<'tcx>, ()>,
args_no_rcvr: &'gcx [hir::Expr],
tuple_arguments: TupleArgumentsFlag,
Expand All @@ -2371,7 +2372,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
};

self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
false, tuple_arguments, None);
return self.tcx.types.err;
}
Expand All @@ -2384,7 +2385,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
method.sig.output(),
&method.sig.inputs()[1..]
);
self.check_argument_types(sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
args_no_rcvr, method.sig.variadic, tuple_arguments,
self.tcx.hir.span_if_local(method.def_id));
method.sig.output()
Expand All @@ -2394,6 +2395,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// method calls and overloaded operators.
fn check_argument_types(&self,
sp: Span,
expr_sp: Span,
fn_inputs: &[Ty<'tcx>],
expected_arg_tys: &[Ty<'tcx>],
args: &'gcx [hir::Expr],
Expand Down Expand Up @@ -2434,9 +2436,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
sp
};

fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
arg_count: usize, error_code: &str, variadic: bool,
def_span: Option<Span>, sugg_unit: bool) {
fn parameter_count_error<'tcx>(sess: &Session,
sp: Span,
expr_sp: Span,
expected_count: usize,
arg_count: usize,
error_code: &str,
variadic: bool,
def_span: Option<Span>,
sugg_unit: bool) {
let mut err = sess.struct_span_err_with_code(sp,
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
if variadic {"at least "} else {""},
Expand All @@ -2450,12 +2458,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
err.span_label(def_s, "defined here");
}
if sugg_unit {
let sugg_span = sp.end_point();
let sugg_span = expr_sp.end_point();
// remove closing `)` from the span
let sugg_span = sugg_span.with_hi(sugg_span.lo());
err.span_suggestion(
sugg_span,
"expected the unit value `()`. You can create one with a pair of parenthesis",
"expected the unit value `()`; create it with empty parentheses",
String::from("()"));
} else {
err.span_label(sp, format!("expected {}{} parameter{}",
Expand All @@ -2470,7 +2478,7 @@ 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, arg_types.len(), args.len(),
parameter_count_error(tcx.sess, sp_args, expr_sp, arg_types.len(), args.len(),
"E0057", false, def_span, false);
expected_arg_tys = &[];
self.err_args(args.len())
Expand Down Expand Up @@ -2499,7 +2507,7 @@ 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, expected_arg_count,
parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
supplied_arg_count, "E0060", true, def_span, false);
expected_arg_tys = &[];
self.err_args(supplied_arg_count)
Expand All @@ -2513,7 +2521,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} else {
false
};
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
parameter_count_error(tcx.sess, sp_args, expr_sp, expected_arg_count,
supplied_arg_count, "E0061", false, def_span, sugg_unit);
expected_arg_tys = &[];
self.err_args(supplied_arg_count)
Expand Down Expand Up @@ -2866,7 +2874,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};

// Call the generic checker.
self.check_method_argument_types(span, method,
self.check_method_argument_types(span,
expr.span,
method,
&args[1..],
DontTupleArguments,
expected)
Expand Down
44 changes: 44 additions & 0 deletions src/test/ui/method-call-err-msg.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0061]: this function takes 0 parameters but 1 parameter was supplied
--> $DIR/method-call-err-msg.rs:25:12
|
15 | fn zero(self) -> Foo { self }
| ----------------------------- defined here
...
25 | x.zero(0) //~ ERROR this function takes 0 parameters but 1 parameter was supplied
| ^ expected 0 parameters

error[E0061]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/method-call-err-msg.rs:27:7
|
17 | fn one(self, _: isize) -> Foo { self }
| -------------------------------------- defined here
...
27 | .one() //~ ERROR this function takes 1 parameter but 0 parameters were supplied
| ^^^ expected 1 parameter

error[E0061]: this function takes 2 parameters but 1 parameter was supplied
--> $DIR/method-call-err-msg.rs:29:11
|
19 | fn two(self, _: isize, _: isize) -> Foo { self }
| ------------------------------------------------ defined here
...
29 | .two(0); //~ ERROR this function takes 2 parameters but 1 parameter was supplied
| ^ expected 2 parameters

error[E0599]: no method named `take` found for type `Foo` in the current scope
--> $DIR/method-call-err-msg.rs:34:7
|
34 | .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:
`&mut Foo : std::iter::Iterator`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `take`, perhaps you need to implement one of them:
candidate #1: `std::collections::hash::Recover`
candidate #2: `std::io::Read`
candidate #3: `std::iter::Iterator`
candidate #4: `alloc::btree::Recover`

error: aborting due to 4 previous errors

8 changes: 8 additions & 0 deletions src/test/ui/span/missing-unit-argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@
fn foo(():(), ():()) {}
fn bar(():()) {}

struct S;
impl S {
fn baz(self, (): ()) { }
fn generic<T>(self, _: T) { }
}

fn main() {
let _: Result<(), String> = Ok();
foo();
foo(());
bar();
S.baz();
S.generic::<()>();
}
54 changes: 41 additions & 13 deletions src/test/ui/span/missing-unit-argument.stderr
Original file line number Diff line number Diff line change
@@ -1,45 +1,73 @@
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/missing-unit-argument.rs:15:33
--> $DIR/missing-unit-argument.rs:21:33
|
15 | let _: Result<(), String> = Ok();
21 | let _: Result<(), String> = Ok();
| ^^^^
|
help: expected the unit value `()`. You can create one with a pair of parenthesis
help: expected the unit value `()`; create it with empty parentheses
|
15 | let _: Result<(), String> = Ok(());
21 | let _: Result<(), String> = Ok(());
| ^^

error[E0061]: this function takes 2 parameters but 0 parameters were supplied
--> $DIR/missing-unit-argument.rs:16:5
--> $DIR/missing-unit-argument.rs:22:5
|
11 | fn foo(():(), ():()) {}
| ----------------------- defined here
...
16 | foo();
22 | foo();
| ^^^^^ expected 2 parameters

error[E0061]: this function takes 2 parameters but 1 parameter was supplied
--> $DIR/missing-unit-argument.rs:17:9
--> $DIR/missing-unit-argument.rs:23:9
|
11 | fn foo(():(), ():()) {}
| ----------------------- defined here
...
17 | foo(());
23 | foo(());
| ^^ expected 2 parameters

error[E0061]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/missing-unit-argument.rs:18:5
--> $DIR/missing-unit-argument.rs:24:5
|
12 | fn bar(():()) {}
| ---------------- defined here
...
18 | bar();
24 | bar();
| ^^^^^
|
help: expected the unit value `()`. You can create one with a pair of parenthesis
help: expected the unit value `()`; create it with empty parentheses
|
18 | bar(());
24 | bar(());
| ^^

error: aborting due to 4 previous errors
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/missing-unit-argument.rs:25:7
|
16 | fn baz(self, (): ()) { }
| ------------------------ defined here
...
25 | S.baz();
| ^^^
|
help: expected the unit value `()`; create it with empty parentheses
|
25 | S.baz(());
| ^^

error[E0061]: this function takes 1 parameter but 0 parameters were supplied
--> $DIR/missing-unit-argument.rs:26:7
|
17 | fn generic<T>(self, _: T) { }
| ----------------------------- defined here
...
26 | S.generic::<()>();
| ^^^^^^^
|
help: expected the unit value `()`; create it with empty parentheses
|
26 | S.generic::<()>(());
| ^^

error: aborting due to 6 previous errors