Suggest calling await on method call and field access

When encountering a failing method or field resolution on a `Future`,
look at the `Output` and try the same operation on it. If successful,
suggest calling `.await` on the `Future`.

This had already been introduced in #72784, but at some point they
stopped working.
This commit is contained in:
Esteban Küber 2020-10-23 10:54:34 -07:00
parent 9f6c670c4b
commit 28f02fbf3e
5 changed files with 90 additions and 95 deletions

View file

@ -40,6 +40,14 @@ async fn foo() -> Result<(), ()> {
async fn bar() -> Result<(), ()> {
foo()?; //~ ERROR the `?` operator can only be applied to values that implement `Try`
//~^ NOTE the `?` operator cannot be applied to type `impl Future`
//~| HELP the trait `Try` is not implemented for `impl Future`
//~| NOTE required by `into_result`
//~| HELP consider `await`ing on the `Future`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
Ok(())
}
@ -48,25 +56,42 @@ async fn struct_() -> Struct {
}
async fn tuple() -> Tuple {
//~^ NOTE the `Output` of this `async fn`'s expected opaque type
Tuple(1i32)
}
async fn baz() -> Result<(), ()> {
let t = T;
t?; //~ ERROR the `?` operator can only be applied to values that implement `Try`
//~^ NOTE the `?` operator cannot be applied to type `T`
//~| HELP the trait `Try` is not implemented for `T`
//~| NOTE required by `into_result`
//~| HELP consider `await`ing on the `Future`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`
let _: i32 = tuple().0; //~ ERROR no field `0`
//~^ HELP consider `await`ing on the `Future`
//~| NOTE field not available in `impl Future`
let _: i32 = struct_().a; //~ ERROR no field `a`
//~^ HELP consider `await`ing on the `Future`
//~| NOTE field not available in `impl Future`
struct_().method(); //~ ERROR no method named
//~^ NOTE method not found in `impl Future`
//~| HELP consider `await`ing on the `Future`
Ok(())
}
async fn match_() {
match tuple() {
match tuple() { //~ HELP consider `await`ing on the `Future`
Tuple(_) => {} //~ ERROR mismatched types
//~^ NOTE expected opaque type, found struct `Tuple`
//~| NOTE expected opaque type `impl Future`
}
}

View file

@ -12,7 +12,7 @@ LL | foo().await?;
| ^^^^^^
error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/issue-61076.rs:56:5
--> $DIR/issue-61076.rs:65:5
|
LL | t?;
| ^^ the `?` operator cannot be applied to type `T`
@ -25,25 +25,40 @@ LL | t.await?;
| ^^^^^^
error[E0609]: no field `0` on type `impl Future`
--> $DIR/issue-61076.rs:58:26
--> $DIR/issue-61076.rs:76:26
|
LL | let _: i32 = tuple().0;
| ^
| ^ field not available in `impl Future`, but it is available in its `Output`
|
help: consider `await`ing on the `Future` and access the field of its `Output`
|
LL | let _: i32 = tuple().await.0;
| ^^^^^^
error[E0609]: no field `a` on type `impl Future`
--> $DIR/issue-61076.rs:60:28
--> $DIR/issue-61076.rs:80:28
|
LL | let _: i32 = struct_().a;
| ^
| ^ field not available in `impl Future`, but it is available in its `Output`
|
help: consider `await`ing on the `Future` and access the field of its `Output`
|
LL | let _: i32 = struct_().await.a;
| ^^^^^^
error[E0599]: no method named `method` found for opaque type `impl Future` in the current scope
--> $DIR/issue-61076.rs:62:15
--> $DIR/issue-61076.rs:84:15
|
LL | struct_().method();
| ^^^^^^ method not found in `impl Future`
|
help: consider `await`ing on the `Future` and calling the method on its `Output`
|
LL | struct_().await.method();
| ^^^^^^
error[E0308]: mismatched types
--> $DIR/issue-61076.rs:69:9
--> $DIR/issue-61076.rs:92:9
|
LL | async fn tuple() -> Tuple {
| ----- the `Output` of this `async fn`'s expected opaque type