Skip to content

Commit cc12182

Browse files
authored
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.
2 parents f4b20da + e11ffb6 commit cc12182

File tree

3 files changed

+42
-32
lines changed

3 files changed

+42
-32
lines changed

Diff for: compiler/rustc_hir_typeck/src/callee.rs

+14-32
Original file line numberDiff line numberDiff line change
@@ -420,20 +420,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
420420
.steal_diagnostic(segment.ident.span, StashKey::CallIntoMethod)
421421
{
422422
// Try suggesting `foo(a)` -> `a.foo()` if possible.
423-
if let Some(ty) =
424-
self.suggest_call_as_method(
425-
&mut diag,
426-
segment,
427-
arg_exprs,
428-
call_expr,
429-
expected
430-
)
431-
{
432-
diag.emit();
433-
return ty;
434-
} else {
435-
diag.emit();
436-
}
423+
self.suggest_call_as_method(
424+
&mut diag,
425+
segment,
426+
arg_exprs,
427+
call_expr,
428+
expected
429+
);
430+
diag.emit();
437431
}
438432

439433
let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
@@ -496,9 +490,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496490
arg_exprs: &'tcx [hir::Expr<'tcx>],
497491
call_expr: &'tcx hir::Expr<'tcx>,
498492
expected: Expectation<'tcx>,
499-
) -> Option<Ty<'tcx>> {
493+
) {
500494
if let [callee_expr, rest @ ..] = arg_exprs {
501-
let callee_ty = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr)?;
495+
let Some(callee_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr) else {
496+
return;
497+
};
502498

503499
// First, do a probe with `IsSuggestion(true)` to avoid emitting
504500
// any strange errors. If it's successful, then we'll do a true
@@ -513,7 +509,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
513509
ProbeScope::AllTraits,
514510
expected.only_has_type(self),
515511
) else {
516-
return None;
512+
return;
517513
};
518514

519515
let pick = self.confirm_method(
@@ -525,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
525521
segment,
526522
);
527523
if pick.illegal_sized_bound.is_some() {
528-
return None;
524+
return;
529525
}
530526

531527
let up_to_rcvr_span = segment.ident.span.until(callee_expr.span);
@@ -567,22 +563,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
567563
sugg,
568564
Applicability::MaybeIncorrect,
569565
);
570-
571-
// Let's check the method fully now
572-
let return_ty = self.check_method_argument_types(
573-
segment.ident.span,
574-
call_expr,
575-
Ok(pick.callee),
576-
rest,
577-
TupleArgumentsFlag::DontTupleArguments,
578-
expected,
579-
);
580-
581-
return Some(return_ty);
582566
}
583567
}
584-
585-
None
586568
}
587569

588570
fn report_invalid_callee(

Diff for: tests/ui/typeck/issue-106929.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
struct Client;
2+
3+
impl Client {
4+
fn post<T: std::ops::Add>(&self, _: T, _: T) {}
5+
}
6+
7+
fn f() {
8+
let c = Client;
9+
post(c, ());
10+
//~^ ERROR cannot find function `post` in this scope
11+
}
12+
13+
fn main() {}

Diff for: tests/ui/typeck/issue-106929.stderr

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0425]: cannot find function `post` in this scope
2+
--> $DIR/issue-106929.rs:9:5
3+
|
4+
LL | post(c, ());
5+
| ^^^^ not found in this scope
6+
|
7+
help: use the `.` operator to call the method `post` on `&Client`
8+
|
9+
LL - post(c, ());
10+
LL + c.post(());
11+
|
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)