Pass the full span for method calls
This commit is contained in:
parent
fbb5054fa9
commit
bb4d1caad7
6 changed files with 117 additions and 24 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
44
src/test/ui/method-call-err-msg.stderr
Normal file
44
src/test/ui/method-call-err-msg.stderr
Normal 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
|
||||
|
||||
|
|
@ -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::<()>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue