Rollup merge of #135492 - metamuffin:bug-invalid-await-suggest, r=compiler-errors
Add missing check for async body when suggesting await on futures. Currently the compiler suggests adding `.await` to resolve some type conflicts without checking if the conflict happens in an async context. This can lead to the compiler suggesting `.await` in function signatures where it is invalid. Example: ```rs trait A { fn a() -> impl Future<Output = ()>; } struct B; impl A for B { fn a() -> impl Future<Output = impl Future<Output = ()>> { async { async { () } } } } ``` ``` error[E0271]: expected `impl Future<Output = impl Future<Output = ()>>` to be a future that resolves to `()`, but it resolves to `impl Future<Output = ()>` --> bug.rs:6:15 | 6 | fn a() -> impl Future<Output = impl Future<Output = ()>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found future | note: calling an async function returns a future --> bug.rs:6:15 | 6 | fn a() -> impl Future<Output = impl Future<Output = ()>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `A::{synthetic#0}` --> bug.rs:2:27 | 2 | fn a() -> impl Future<Output = ()>; | ^^^^^^^^^^^ required by this bound in `A::{synthetic#0}` help: consider `await`ing on the `Future` | 6 | fn a() -> impl Future<Output = impl Future<Output = ()>>.await { | ++++++ ``` The documentation of suggest_await_on_expect_found (`compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs:156`) even mentions such a check but does not actually implement it. This PR adds that check to ensure `.await` is only suggested within async blocks. There were 3 unit tests whose expected output needed to be changed because they had the suggestion outside of async. One of them (`tests/ui/async-await/dont-suggest-missing-await.rs`) actually tests that exact problem but expects it to be present. Thanks to `@llenck` for initially noticing the bug and helping with fixing it
This commit is contained in:
commit
4496f23ca9
4 changed files with 12 additions and 19 deletions
|
@ -167,6 +167,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
exp_span, exp_found.expected, exp_found.found,
|
||||
);
|
||||
|
||||
match self.tcx.coroutine_kind(cause.body_id) {
|
||||
Some(hir::CoroutineKind::Desugared(
|
||||
hir::CoroutineDesugaring::Async | hir::CoroutineDesugaring::AsyncGen,
|
||||
_,
|
||||
)) => (),
|
||||
None
|
||||
| Some(
|
||||
hir::CoroutineKind::Coroutine(_)
|
||||
| hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _),
|
||||
) => return,
|
||||
}
|
||||
|
||||
if let ObligationCauseCode::CompareImplItem { .. } = cause.code() {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue