Rollup merge of #112100 - jieyouxu:issue-106929, r=oli-obk
Don't typecheck recovered method call from suggestion Only make the use-dot-operator-to-call-method suggestion, but do not double down and use the recovered type to perform method call typechecking as it will produce confusing diagnostics relevant for the *fixed* code. ### Code Sample ```rust struct Client; impl Client { fn post<T: std::ops::Add>(&self, _: T, _: T) {} } fn f() { let c = Client; post(c, ()); } ``` ### Before This PR ``` error[[E0277]](https://doc.rust-lang.org/stable/error_codes/E0277.html): cannot add `()` to `()` --> src/lib.rs:9:5 | 9 | post(c, ()); | ^^^^^^^^^^^ no implementation for `() + ()` | = help: the trait `Add` is not implemented for `()` note: required by a bound in `Client::post` --> src/lib.rs:4:16 | 4 | fn post<T: std::ops::Add>(&self, _: T, _: T) {} | ^^^^^^^^^^^^^ required by this bound in `Client::post` error[[E0061]](https://doc.rust-lang.org/stable/error_codes/E0061.html): this function takes 2 arguments but 1 argument was supplied --> src/lib.rs:9:5 | 9 | post(c, ()); | ^^^^ an argument of type `()` is missing | note: method defined here --> src/lib.rs:4:8 | 4 | fn post<T: std::ops::Add>(&self, _: T, _: T) {} | ^^^^ ----- ---- ---- help: provide the argument | 9 | post((), ())(c, ()); | ++++++++ error[[E0425]](https://doc.rust-lang.org/stable/error_codes/E0425.html): cannot find function `post` in this scope --> src/lib.rs:9:5 | 9 | post(c, ()); | ^^^^ not found in this scope | help: use the `.` operator to call the method `post` on `&Client` | 9 - post(c, ()); 9 + c.post(()); | Some errors have detailed explanations: E0061, E0277, E0425. For more information about an error, try `rustc --explain E0061`. ``` ### After This PR ``` error[E0425]: cannot find function `post` in this scope --> tests/ui/typeck/issue-106929.rs:9:5 | 9 | post(c, ()); | ^^^^ not found in this scope | help: use the `.` operator to call the method `post` on `&Client` | 9 - post(c, ()); 9 + c.post(()); | error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. ``` Fixes #106929.
This commit is contained in:
commit
cc121828ee
@ -420,20 +420,14 @@ fn confirm_builtin_call(
|
|||||||
.steal_diagnostic(segment.ident.span, StashKey::CallIntoMethod)
|
.steal_diagnostic(segment.ident.span, StashKey::CallIntoMethod)
|
||||||
{
|
{
|
||||||
// Try suggesting `foo(a)` -> `a.foo()` if possible.
|
// Try suggesting `foo(a)` -> `a.foo()` if possible.
|
||||||
if let Some(ty) =
|
|
||||||
self.suggest_call_as_method(
|
self.suggest_call_as_method(
|
||||||
&mut diag,
|
&mut diag,
|
||||||
segment,
|
segment,
|
||||||
arg_exprs,
|
arg_exprs,
|
||||||
call_expr,
|
call_expr,
|
||||||
expected
|
expected
|
||||||
)
|
);
|
||||||
{
|
|
||||||
diag.emit();
|
diag.emit();
|
||||||
return ty;
|
|
||||||
} else {
|
|
||||||
diag.emit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
|
let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
|
||||||
@ -496,9 +490,11 @@ fn suggest_call_as_method(
|
|||||||
arg_exprs: &'tcx [hir::Expr<'tcx>],
|
arg_exprs: &'tcx [hir::Expr<'tcx>],
|
||||||
call_expr: &'tcx hir::Expr<'tcx>,
|
call_expr: &'tcx hir::Expr<'tcx>,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
) -> Option<Ty<'tcx>> {
|
) {
|
||||||
if let [callee_expr, rest @ ..] = arg_exprs {
|
if let [callee_expr, rest @ ..] = arg_exprs {
|
||||||
let callee_ty = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr)?;
|
let Some(callee_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
// First, do a probe with `IsSuggestion(true)` to avoid emitting
|
// First, do a probe with `IsSuggestion(true)` to avoid emitting
|
||||||
// any strange errors. If it's successful, then we'll do a true
|
// any strange errors. If it's successful, then we'll do a true
|
||||||
@ -513,7 +509,7 @@ fn suggest_call_as_method(
|
|||||||
ProbeScope::AllTraits,
|
ProbeScope::AllTraits,
|
||||||
expected.only_has_type(self),
|
expected.only_has_type(self),
|
||||||
) else {
|
) else {
|
||||||
return None;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let pick = self.confirm_method(
|
let pick = self.confirm_method(
|
||||||
@ -525,7 +521,7 @@ fn suggest_call_as_method(
|
|||||||
segment,
|
segment,
|
||||||
);
|
);
|
||||||
if pick.illegal_sized_bound.is_some() {
|
if pick.illegal_sized_bound.is_some() {
|
||||||
return None;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let up_to_rcvr_span = segment.ident.span.until(callee_expr.span);
|
let up_to_rcvr_span = segment.ident.span.until(callee_expr.span);
|
||||||
@ -567,22 +563,8 @@ fn suggest_call_as_method(
|
|||||||
sugg,
|
sugg,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Let's check the method fully now
|
|
||||||
let return_ty = self.check_method_argument_types(
|
|
||||||
segment.ident.span,
|
|
||||||
call_expr,
|
|
||||||
Ok(pick.callee),
|
|
||||||
rest,
|
|
||||||
TupleArgumentsFlag::DontTupleArguments,
|
|
||||||
expected,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Some(return_ty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_invalid_callee(
|
fn report_invalid_callee(
|
||||||
|
13
tests/ui/typeck/issue-106929.rs
Normal file
13
tests/ui/typeck/issue-106929.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
struct Client;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
fn post<T: std::ops::Add>(&self, _: T, _: T) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
let c = Client;
|
||||||
|
post(c, ());
|
||||||
|
//~^ ERROR cannot find function `post` in this scope
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
tests/ui/typeck/issue-106929.stderr
Normal file
15
tests/ui/typeck/issue-106929.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0425]: cannot find function `post` in this scope
|
||||||
|
--> $DIR/issue-106929.rs:9:5
|
||||||
|
|
|
||||||
|
LL | post(c, ());
|
||||||
|
| ^^^^ not found in this scope
|
||||||
|
|
|
||||||
|
help: use the `.` operator to call the method `post` on `&Client`
|
||||||
|
|
|
||||||
|
LL - post(c, ());
|
||||||
|
LL + c.post(());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0425`.
|
Loading…
Reference in New Issue
Block a user