Pass the full span for method calls

This commit is contained in:
Geoffry Song 2017-10-08 18:13:37 -07:00 committed by Geoffry Song
parent fbb5054fa9
commit bb4d1caad7
6 changed files with 117 additions and 24 deletions

View file

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

View file

@ -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,
@ -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;
}
@ -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()
@ -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],
@ -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 {""},
@ -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{}",
@ -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())
@ -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)
@ -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)
@ -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)

View file

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

View file

@ -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::<()>();
}

View file

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