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)
|
||||
{
|
||||
// Try suggesting `foo(a)` -> `a.foo()` if possible.
|
||||
if let Some(ty) =
|
||||
self.suggest_call_as_method(
|
||||
&mut diag,
|
||||
segment,
|
||||
arg_exprs,
|
||||
call_expr,
|
||||
expected
|
||||
)
|
||||
{
|
||||
diag.emit();
|
||||
return ty;
|
||||
} else {
|
||||
diag.emit();
|
||||
}
|
||||
self.suggest_call_as_method(
|
||||
&mut diag,
|
||||
segment,
|
||||
arg_exprs,
|
||||
call_expr,
|
||||
expected
|
||||
);
|
||||
diag.emit();
|
||||
}
|
||||
|
||||
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>],
|
||||
call_expr: &'tcx hir::Expr<'tcx>,
|
||||
expected: Expectation<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
) {
|
||||
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
|
||||
// any strange errors. If it's successful, then we'll do a true
|
||||
@ -513,7 +509,7 @@ fn suggest_call_as_method(
|
||||
ProbeScope::AllTraits,
|
||||
expected.only_has_type(self),
|
||||
) else {
|
||||
return None;
|
||||
return;
|
||||
};
|
||||
|
||||
let pick = self.confirm_method(
|
||||
@ -525,7 +521,7 @@ fn suggest_call_as_method(
|
||||
segment,
|
||||
);
|
||||
if pick.illegal_sized_bound.is_some() {
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
|
||||
let up_to_rcvr_span = segment.ident.span.until(callee_expr.span);
|
||||
@ -567,22 +563,8 @@ fn suggest_call_as_method(
|
||||
sugg,
|
||||
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(
|
||||
|
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