Rollup merge of #118891 - compiler-errors:async-gen-blocks, r=eholk
Actually parse async gen blocks correctly 1. I got the control flow in `parse_expr_bottom` messed up, and obviously forgot a test for `async gen`, so we weren't actually ever parsing it correctly. 2. I forgot to gate the span for `async gen {}`, so even if we did parse it, we wouldn't have correctly denied it in `cfg(FALSE)`. r? eholk
This commit is contained in:
commit
f9078a40ee
5 changed files with 87 additions and 15 deletions
|
@ -1440,21 +1440,23 @@ impl<'a> Parser<'a> {
|
||||||
} else if this.eat_keyword(kw::Underscore) {
|
} else if this.eat_keyword(kw::Underscore) {
|
||||||
Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
|
Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
|
||||||
} else if this.token.uninterpolated_span().at_least_rust_2018() {
|
} else if this.token.uninterpolated_span().at_least_rust_2018() {
|
||||||
// `Span:.at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
|
// `Span::at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
|
||||||
if this.check_keyword(kw::Async) {
|
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
|
// FIXME(gen_blocks): Parse `gen async` and suggest swap
|
||||||
if this.is_gen_block(kw::Async, 0) {
|
if this.is_gen_block(kw::Async, 0) {
|
||||||
// Check for `async {` and `async move {`,
|
// Check for `async {` and `async move {`,
|
||||||
// or `async gen {` and `async gen move {`.
|
|
||||||
this.parse_gen_block()
|
this.parse_gen_block()
|
||||||
} else {
|
} else {
|
||||||
this.parse_expr_closure()
|
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) {
|
} else if this.eat_keyword_noexpect(kw::Await) {
|
||||||
this.recover_incorrect_await_syntax(lo, this.prev_token.span)
|
this.recover_incorrect_await_syntax(lo, this.prev_token.span)
|
||||||
} else {
|
} else {
|
||||||
|
@ -3227,9 +3229,16 @@ impl<'a> Parser<'a> {
|
||||||
if self.eat_keyword(kw::Gen) { GenBlockKind::AsyncGen } else { GenBlockKind::Async }
|
if self.eat_keyword(kw::Gen) { GenBlockKind::AsyncGen } else { GenBlockKind::Async }
|
||||||
} else {
|
} else {
|
||||||
assert!(self.eat_keyword(kw::Gen));
|
assert!(self.eat_keyword(kw::Gen));
|
||||||
self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.token.span));
|
|
||||||
GenBlockKind::Gen
|
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 capture_clause = self.parse_capture_clause()?;
|
||||||
let (attrs, body) = self.parse_inner_attrs_and_block()?;
|
let (attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||||
let kind = ExprKind::Gen(capture_clause, body, kind);
|
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
|
--> $DIR/feature-gate-gen_blocks.rs:5:5
|
||||||
|
|
|
|
||||||
LL | gen {};
|
LL | gen {};
|
||||||
| ^^^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
|
= 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
|
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: gen blocks are experimental
|
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 {};
|
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
|
= 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
|
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
|
||||||
|
@ -22,7 +40,13 @@ error[E0282]: type annotations needed
|
||||||
LL | gen {};
|
LL | gen {};
|
||||||
| ^^ cannot infer type
|
| ^^ 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.
|
Some errors have detailed explanations: E0282, E0658.
|
||||||
For more information about an error, try `rustc --explain E0282`.
|
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
|
error[E0422]: cannot find struct, variant or union type `gen` in this scope
|
||||||
--> $DIR/feature-gate-gen_blocks.rs:5:5
|
--> $DIR/feature-gate-gen_blocks.rs:5:5
|
||||||
|
|
|
|
||||||
LL | gen {};
|
LL | gen {};
|
||||||
| ^^^ not found in this scope
|
| ^^^ 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`.
|
For more information about this error, try `rustc --explain E0422`.
|
||||||
|
|
|
@ -1,15 +1,28 @@
|
||||||
// revisions: e2024 none
|
// revisions: e2024 none
|
||||||
//[e2024] compile-flags: --edition 2024 -Zunstable-options
|
//[e2024] compile-flags: --edition 2024 -Zunstable-options
|
||||||
|
|
||||||
fn main() {
|
fn test_gen() {
|
||||||
gen {};
|
gen {};
|
||||||
//[none]~^ ERROR: cannot find struct, variant or union type `gen`
|
//[none]~^ ERROR: cannot find struct, variant or union type `gen`
|
||||||
//[e2024]~^^ ERROR: gen blocks are experimental
|
//[e2024]~^^ ERROR: gen blocks are experimental
|
||||||
//[e2024]~| ERROR: type annotations needed
|
//[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)]
|
#[cfg(FALSE)]
|
||||||
fn foo() {
|
fn foo() {
|
||||||
gen {};
|
gen {};
|
||||||
//[e2024]~^ ERROR: gen blocks are experimental
|
//[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…
Add table
Add a link
Reference in a new issue