Skip to content

Commit d227a82

Browse files
authored
Rollup merge of #73672 - nellshamrell:async-fix, r=estebank
Adds a clearer message for when the async keyword is missing from a f… …unction This is a somewhat simple fix for #66731. Under the current version of Rust, if a user has a rust file that looks like this: ```rust fn boo (){} async fn foo() { boo().await; } fn main() { } ``` And they attempt to run it, they will receive an error message that looks like this: ```bash error: incorrect use of `await` --> test.rs:4:14 | 4 | boo.await(); | ^^ help: `await` is not a method call, remove the parentheses error[E0277]: the trait bound `fn() {boo}: std::future::Future` is not satisfied --> test.rs:4:5 | 4 | boo.await(); | ^^^^^^^^^ the trait `std::future::Future` is not implemented for `fn() {boo}` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. ``` This is not very clear. With the changes made in this PR, when a user compiles and runs that same rust code, they will receive an error message that looks like this: ```bash error[E0277]: `()` is not a future. --> test.rs:4:5 | 4 | boo().await; | ^^^^^^^^^^^ `()` is not a future | = help: the trait `std::future::Future` is not implemented for `()` = note: required by `std::future::Future::poll` ``` In the future, I think we should make this error message even clearer, perhaps through a solution like the one described in [this comment](#66731 (comment)). However, as that potentially involves a major change proposal, I would rather get this change in now and make the error message a little clearer while an MCP is drafted and discussed. Signed-off-by: Nell Shamrell <[email protected]>
2 parents 45ec25e + 5e28eb5 commit d227a82

9 files changed

+22
-15
lines changed

src/libcore/future/future.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::task::{Context, Poll};
2727
#[must_use = "futures do nothing unless you `.await` or poll them"]
2828
#[stable(feature = "futures_api", since = "1.36.0")]
2929
#[lang = "future_trait"]
30+
#[rustc_on_unimplemented(label = "`{Self}` is not a future", message = "`{Self}` is not a future")]
3031
pub trait Future {
3132
/// The type of value produced on completion.
3233
#[stable(feature = "futures_api", since = "1.36.0")]

src/test/ui/async-await/async-error-span.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use std::future::Future;
66

77
fn get_future() -> impl Future<Output = ()> {
8-
//~^ ERROR the trait bound `(): std::future::Future` is not satisfied
8+
//~^ ERROR `()` is not a future
99
panic!()
1010
}
1111

src/test/ui/async-await/async-error-span.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
error[E0277]: the trait bound `(): std::future::Future` is not satisfied
1+
error[E0277]: `()` is not a future
22
--> $DIR/async-error-span.rs:7:20
33
|
44
LL | fn get_future() -> impl Future<Output = ()> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
66
LL |
77
LL | panic!()
88
| -------- this returned value is of type `!`
99
|
10+
= help: the trait `std::future::Future` is not implemented for `()`
1011
= note: the return type of a function must have a statically known size
1112

1213
error[E0698]: type inside `async fn` body must be known in this context

src/test/ui/async-await/issue-70594.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ async fn fun() {
66
//~| error: `.await` is not allowed in a `const`
77
//~| error: `loop` is not allowed in a `const`
88
//~| error: `.await` is not allowed in a `const`
9-
//~| error: the trait bound `(): std::future::Future` is not satisfied
9+
//~| error: `()` is not a future
1010
}
1111

1212
fn main() {}

src/test/ui/async-await/issue-70594.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ error[E0744]: `.await` is not allowed in a `const`
2727
LL | [1; ().await];
2828
| ^^^^^^^^
2929

30-
error[E0277]: the trait bound `(): std::future::Future` is not satisfied
30+
error[E0277]: `()` is not a future
3131
--> $DIR/issue-70594.rs:4:9
3232
|
3333
LL | [1; ().await];
34-
| ^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
34+
| ^^^^^^^^ `()` is not a future
3535
|
36+
= help: the trait `std::future::Future` is not implemented for `()`
3637
= note: required by `std::future::Future::poll`
3738

3839
error: aborting due to 5 previous errors

src/test/ui/async-await/issues/issue-62009-1.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ LL | fn main() {
2727
LL | (|_| 2333).await;
2828
| ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
2929

30-
error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std::future::Future` is not satisfied
30+
error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
3131
--> $DIR/issue-62009-1.rs:12:5
3232
|
3333
LL | (|_| 2333).await;
34-
| ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
34+
| ^^^^^^^^^^^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
3535
|
36+
= help: the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
3637
= note: required by `std::future::Future::poll`
3738

3839
error: aborting due to 4 previous errors

src/test/ui/issues-71798.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
2-
*x //~^ ERROR the trait bound `u32: std::future::Future` is not satisfied
2+
*x //~^ ERROR `u32` is not a future
33
}
44

55
fn main() {

src/test/ui/issues-71798.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ error[E0425]: cannot find value `u` in this scope
44
LL | let _ = test_ref & u;
55
| ^ not found in this scope
66

7-
error[E0277]: the trait bound `u32: std::future::Future` is not satisfied
7+
error[E0277]: `u32` is not a future
88
--> $DIR/issues-71798.rs:1:25
99
|
1010
LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `u32`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not a future
1212
LL | *x
1313
| -- this returned value is of type `u32`
1414
|
15+
= help: the trait `std::future::Future` is not implemented for `u32`
1516
= note: the return type of a function must have a statically known size
1617

1718
error: aborting due to 2 previous errors

src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
1+
error[E0277]: `fn() -> impl std::future::Future {foo}` is not a future
22
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9
33
|
44
LL | async fn foo() {}
@@ -8,14 +8,15 @@ LL | fn bar(f: impl Future<Output=()>) {}
88
| ----------------- required by this bound in `bar`
99
...
1010
LL | bar(foo);
11-
| ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
11+
| ^^^ `fn() -> impl std::future::Future {foo}` is not a future
1212
|
13+
= help: the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
1314
help: use parentheses to call the function
1415
|
1516
LL | bar(foo());
1617
| ^^
1718

18-
error[E0277]: the trait bound `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]: std::future::Future` is not satisfied
19+
error[E0277]: `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]` is not a future
1920
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9
2021
|
2122
LL | fn bar(f: impl Future<Output=()>) {}
@@ -24,8 +25,9 @@ LL | fn bar(f: impl Future<Output=()>) {}
2425
LL | let async_closure = async || ();
2526
| -------- consider calling this closure
2627
LL | bar(async_closure);
27-
| ^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]`
28+
| ^^^^^^^^^^^^^ `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]` is not a future
2829
|
30+
= help: the trait `std::future::Future` is not implemented for `[closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:36]`
2931
help: use parentheses to call the closure
3032
|
3133
LL | bar(async_closure());

0 commit comments

Comments
 (0)