diff options
| author | bors <bors@rust-lang.org> | 2022-12-04 22:46:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-04 22:46:11 +0000 |
| commit | d1449560e31f7f801d81268a3dad783181656dff (patch) | |
| tree | d56ddb5e322b58132ce5e60aa5bfa6774b551a86 /src/test/ui | |
| parent | 53e4b9dd74c29cc9308b8d0f10facac70bb101a7 (diff) | |
| parent | b5ae4c9629f697034fb93f660202f354f13b74c3 (diff) | |
Auto merge of #105094 - Swatinem:generator-not-future, r=compiler-errors
Make sure async constructs do not `impl Generator` Async lowering turns async functions and blocks into generators internally. Though these special kinds of generators should not `impl Generator` themselves. The other way around, normal generators should not `impl Future`. This was discovered in https://github.com/rust-lang/rust/pull/105082#issuecomment-1332210907 and is a regression from https://github.com/rust-lang/rust/pull/104321. r? `@compiler-errors`
Diffstat (limited to 'src/test/ui')
| -rw-r--r-- | src/test/ui/async-await/generator-not-future.rs | 45 | ||||
| -rw-r--r-- | src/test/ui/async-await/generator-not-future.stderr | 81 |
2 files changed, 126 insertions, 0 deletions
diff --git a/src/test/ui/async-await/generator-not-future.rs b/src/test/ui/async-await/generator-not-future.rs new file mode 100644 index 00000000000..37d7cfa6fb7 --- /dev/null +++ b/src/test/ui/async-await/generator-not-future.rs @@ -0,0 +1,45 @@ +// edition:2018 +#![feature(generators, generator_trait)] + +use std::future::Future; +use std::ops::Generator; + +async fn async_fn() {} +fn returns_async_block() -> impl Future<Output = ()> { + async {} +} +fn returns_generator() -> impl Generator<(), Yield = (), Return = ()> { + || { + let _: () = yield (); + } +} + +fn takes_future(_f: impl Future<Output = ()>) {} +fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {} + +fn main() { + // okay: + takes_future(async_fn()); + takes_future(returns_async_block()); + takes_future(async {}); + takes_generator(returns_generator()); + takes_generator(|| { + let _: () = yield (); + }); + + // async futures are not generators: + takes_generator(async_fn()); + //~^ ERROR the trait bound + takes_generator(returns_async_block()); + //~^ ERROR the trait bound + takes_generator(async {}); + //~^ ERROR the trait bound + + // generators are not futures: + takes_future(returns_generator()); + //~^ ERROR is not a future + takes_future(|ctx| { + //~^ ERROR is not a future + ctx = yield (); + }); +} diff --git a/src/test/ui/async-await/generator-not-future.stderr b/src/test/ui/async-await/generator-not-future.stderr new file mode 100644 index 00000000000..1b81b461f0a --- /dev/null +++ b/src/test/ui/async-await/generator-not-future.stderr @@ -0,0 +1,81 @@ +error[E0277]: the trait bound `impl Future<Output = ()>: Generator<_>` is not satisfied + --> $DIR/generator-not-future.rs:31:21 + | +LL | takes_generator(async_fn()); + | --------------- ^^^^^^^^^^ the trait `Generator<_>` is not implemented for `impl Future<Output = ()>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `takes_generator` + --> $DIR/generator-not-future.rs:18:39 + | +LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator` + +error[E0277]: the trait bound `impl Future<Output = ()>: Generator<_>` is not satisfied + --> $DIR/generator-not-future.rs:33:21 + | +LL | takes_generator(returns_async_block()); + | --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Generator<_>` is not implemented for `impl Future<Output = ()>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `takes_generator` + --> $DIR/generator-not-future.rs:18:39 + | +LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator` + +error[E0277]: the trait bound `[async block@$DIR/generator-not-future.rs:35:21: 35:29]: Generator<_>` is not satisfied + --> $DIR/generator-not-future.rs:35:21 + | +LL | takes_generator(async {}); + | --------------- ^^^^^^^^ the trait `Generator<_>` is not implemented for `[async block@$DIR/generator-not-future.rs:35:21: 35:29]` + | | + | required by a bound introduced by this call + | +note: required by a bound in `takes_generator` + --> $DIR/generator-not-future.rs:18:39 + | +LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator` + +error[E0277]: `impl Generator<Yield = (), Return = ()>` is not a future + --> $DIR/generator-not-future.rs:39:18 + | +LL | takes_future(returns_generator()); + | ------------ ^^^^^^^^^^^^^^^^^^^ `impl Generator<Yield = (), Return = ()>` is not a future + | | + | required by a bound introduced by this call + | + = help: the trait `Future` is not implemented for `impl Generator<Yield = (), Return = ()>` + = note: impl Generator<Yield = (), Return = ()> must be a future or must implement `IntoFuture` to be awaited +note: required by a bound in `takes_future` + --> $DIR/generator-not-future.rs:17:26 + | +LL | fn takes_future(_f: impl Future<Output = ()>) {} + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future` + +error[E0277]: `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` is not a future + --> $DIR/generator-not-future.rs:41:18 + | +LL | takes_future(|ctx| { + | _____------------_^ + | | | + | | required by a bound introduced by this call +LL | | +LL | | ctx = yield (); +LL | | }); + | |_____^ `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` is not a future + | + = help: the trait `Future` is not implemented for `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` + = note: [generator@$DIR/generator-not-future.rs:41:18: 41:23] must be a future or must implement `IntoFuture` to be awaited +note: required by a bound in `takes_future` + --> $DIR/generator-not-future.rs:17:26 + | +LL | fn takes_future(_f: impl Future<Output = ()>) {} + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. |
