Actually parse async gen blocks correctly
This commit is contained in:
parent
27d8a57713
commit
1d78ce681e
@ -1440,21 +1440,23 @@ fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
|
||||
} else if this.eat_keyword(kw::Underscore) {
|
||||
Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
|
||||
} else if this.token.uninterpolated_span().at_least_rust_2018() {
|
||||
// `Span:.at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
|
||||
if this.check_keyword(kw::Async) {
|
||||
// `Span::at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
|
||||
if this.token.uninterpolated_span().at_least_rust_2024()
|
||||
// check for `gen {}` and `gen move {}`
|
||||
// or `async gen {}` and `async gen move {}`
|
||||
&& (this.is_gen_block(kw::Gen, 0)
|
||||
|| (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1)))
|
||||
{
|
||||
// FIXME: (async) gen closures aren't yet parsed.
|
||||
this.parse_gen_block()
|
||||
} else if this.check_keyword(kw::Async) {
|
||||
// FIXME(gen_blocks): Parse `gen async` and suggest swap
|
||||
if this.is_gen_block(kw::Async, 0) {
|
||||
// Check for `async {` and `async move {`,
|
||||
// or `async gen {` and `async gen move {`.
|
||||
this.parse_gen_block()
|
||||
} else {
|
||||
this.parse_expr_closure()
|
||||
}
|
||||
} else if this.token.uninterpolated_span().at_least_rust_2024()
|
||||
&& (this.is_gen_block(kw::Gen, 0)
|
||||
|| (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1)))
|
||||
{
|
||||
this.parse_gen_block()
|
||||
} else if this.eat_keyword_noexpect(kw::Await) {
|
||||
this.recover_incorrect_await_syntax(lo, this.prev_token.span)
|
||||
} else {
|
||||
@ -3219,9 +3221,16 @@ fn parse_gen_block(&mut self) -> PResult<'a, P<Expr>> {
|
||||
if self.eat_keyword(kw::Gen) { GenBlockKind::AsyncGen } else { GenBlockKind::Async }
|
||||
} else {
|
||||
assert!(self.eat_keyword(kw::Gen));
|
||||
self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.token.span));
|
||||
GenBlockKind::Gen
|
||||
};
|
||||
match kind {
|
||||
GenBlockKind::Async => {
|
||||
// `async` blocks are stable
|
||||
}
|
||||
GenBlockKind::Gen | GenBlockKind::AsyncGen => {
|
||||
self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.prev_token.span));
|
||||
}
|
||||
}
|
||||
let capture_clause = self.parse_capture_clause()?;
|
||||
let (attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
let kind = ExprKind::Gen(capture_clause, body, kind);
|
||||
|
14
tests/ui/coroutine/async-gen-deduce-yield.rs
Normal file
14
tests/ui/coroutine/async-gen-deduce-yield.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// compile-flags: --edition 2024 -Zunstable-options
|
||||
// check-pass
|
||||
|
||||
#![feature(async_iterator, gen_blocks)]
|
||||
|
||||
use std::async_iter::AsyncIterator;
|
||||
|
||||
fn deduce() -> impl AsyncIterator<Item = ()> {
|
||||
async gen {
|
||||
yield Default::default();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -2,16 +2,34 @@ error[E0658]: gen blocks are experimental
|
||||
--> $DIR/feature-gate-gen_blocks.rs:5:5
|
||||
|
|
||||
LL | gen {};
|
||||
| ^^^^^
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
|
||||
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: gen blocks are experimental
|
||||
--> $DIR/feature-gate-gen_blocks.rs:13:5
|
||||
--> $DIR/feature-gate-gen_blocks.rs:12:5
|
||||
|
|
||||
LL | async gen {};
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
|
||||
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: gen blocks are experimental
|
||||
--> $DIR/feature-gate-gen_blocks.rs:22:5
|
||||
|
|
||||
LL | gen {};
|
||||
| ^^^^^
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
|
||||
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: gen blocks are experimental
|
||||
--> $DIR/feature-gate-gen_blocks.rs:25:5
|
||||
|
|
||||
LL | async gen {};
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
|
||||
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
|
||||
@ -22,7 +40,13 @@ error[E0282]: type annotations needed
|
||||
LL | gen {};
|
||||
| ^^ cannot infer type
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/feature-gate-gen_blocks.rs:12:15
|
||||
|
|
||||
LL | async gen {};
|
||||
| ^^ cannot infer type
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0658.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
|
@ -1,9 +1,21 @@
|
||||
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
|
||||
--> $DIR/feature-gate-gen_blocks.rs:12:11
|
||||
|
|
||||
LL | async gen {};
|
||||
| ^^^ expected one of 8 possible tokens
|
||||
|
||||
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
|
||||
--> $DIR/feature-gate-gen_blocks.rs:25:11
|
||||
|
|
||||
LL | async gen {};
|
||||
| ^^^ expected one of 8 possible tokens
|
||||
|
||||
error[E0422]: cannot find struct, variant or union type `gen` in this scope
|
||||
--> $DIR/feature-gate-gen_blocks.rs:5:5
|
||||
|
|
||||
LL | gen {};
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0422`.
|
||||
|
@ -1,15 +1,28 @@
|
||||
// revisions: e2024 none
|
||||
//[e2024] compile-flags: --edition 2024 -Zunstable-options
|
||||
|
||||
fn main() {
|
||||
fn test_gen() {
|
||||
gen {};
|
||||
//[none]~^ ERROR: cannot find struct, variant or union type `gen`
|
||||
//[e2024]~^^ ERROR: gen blocks are experimental
|
||||
//[e2024]~| ERROR: type annotations needed
|
||||
}
|
||||
|
||||
fn test_async_gen() {
|
||||
async gen {};
|
||||
//[none]~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
|
||||
//[e2024]~^^ ERROR: gen blocks are experimental
|
||||
//[e2024]~| ERROR: type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn foo() {
|
||||
gen {};
|
||||
//[e2024]~^ ERROR: gen blocks are experimental
|
||||
|
||||
async gen {};
|
||||
//[e2024]~^ ERROR: gen blocks are experimental
|
||||
//[none]~^^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user