Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f9078a4

Browse files
authoredDec 13, 2023
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
2 parents 4583a01 + 1d78ce6 commit f9078a4

File tree

5 files changed

+87
-15
lines changed

5 files changed

+87
-15
lines changed
 

‎compiler/rustc_parse/src/parser/expr.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -1440,21 +1440,23 @@ impl<'a> Parser<'a> {
14401440
} else if this.eat_keyword(kw::Underscore) {
14411441
Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
14421442
} else if this.token.uninterpolated_span().at_least_rust_2018() {
1443-
// `Span:.at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
1444-
if this.check_keyword(kw::Async) {
1443+
// `Span::at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
1444+
if this.token.uninterpolated_span().at_least_rust_2024()
1445+
// check for `gen {}` and `gen move {}`
1446+
// or `async gen {}` and `async gen move {}`
1447+
&& (this.is_gen_block(kw::Gen, 0)
1448+
|| (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1)))
1449+
{
1450+
// FIXME: (async) gen closures aren't yet parsed.
1451+
this.parse_gen_block()
1452+
} else if this.check_keyword(kw::Async) {
14451453
// FIXME(gen_blocks): Parse `gen async` and suggest swap
14461454
if this.is_gen_block(kw::Async, 0) {
14471455
// Check for `async {` and `async move {`,
1448-
// or `async gen {` and `async gen move {`.
14491456
this.parse_gen_block()
14501457
} else {
14511458
this.parse_expr_closure()
14521459
}
1453-
} else if this.token.uninterpolated_span().at_least_rust_2024()
1454-
&& (this.is_gen_block(kw::Gen, 0)
1455-
|| (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1)))
1456-
{
1457-
this.parse_gen_block()
14581460
} else if this.eat_keyword_noexpect(kw::Await) {
14591461
this.recover_incorrect_await_syntax(lo, this.prev_token.span)
14601462
} else {
@@ -3227,9 +3229,16 @@ impl<'a> Parser<'a> {
32273229
if self.eat_keyword(kw::Gen) { GenBlockKind::AsyncGen } else { GenBlockKind::Async }
32283230
} else {
32293231
assert!(self.eat_keyword(kw::Gen));
3230-
self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.token.span));
32313232
GenBlockKind::Gen
32323233
};
3234+
match kind {
3235+
GenBlockKind::Async => {
3236+
// `async` blocks are stable
3237+
}
3238+
GenBlockKind::Gen | GenBlockKind::AsyncGen => {
3239+
self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.prev_token.span));
3240+
}
3241+
}
32333242
let capture_clause = self.parse_capture_clause()?;
32343243
let (attrs, body) = self.parse_inner_attrs_and_block()?;
32353244
let kind = ExprKind::Gen(capture_clause, body, kind);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// compile-flags: --edition 2024 -Zunstable-options
2+
// check-pass
3+
4+
#![feature(async_iterator, gen_blocks)]
5+
6+
use std::async_iter::AsyncIterator;
7+
8+
fn deduce() -> impl AsyncIterator<Item = ()> {
9+
async gen {
10+
yield Default::default();
11+
}
12+
}
13+
14+
fn main() {}

‎tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr

+28-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,34 @@ error[E0658]: gen blocks are experimental
22
--> $DIR/feature-gate-gen_blocks.rs:5:5
33
|
44
LL | gen {};
5-
| ^^^^^
5+
| ^^^
66
|
77
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
88
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
99

1010
error[E0658]: gen blocks are experimental
11-
--> $DIR/feature-gate-gen_blocks.rs:13:5
11+
--> $DIR/feature-gate-gen_blocks.rs:12:5
12+
|
13+
LL | async gen {};
14+
| ^^^^^^^^^
15+
|
16+
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
17+
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
18+
19+
error[E0658]: gen blocks are experimental
20+
--> $DIR/feature-gate-gen_blocks.rs:22:5
1221
|
1322
LL | gen {};
14-
| ^^^^^
23+
| ^^^
24+
|
25+
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
26+
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
27+
28+
error[E0658]: gen blocks are experimental
29+
--> $DIR/feature-gate-gen_blocks.rs:25:5
30+
|
31+
LL | async gen {};
32+
| ^^^^^^^^^
1533
|
1634
= note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information
1735
= help: add `#![feature(gen_blocks)]` to the crate attributes to enable
@@ -22,7 +40,13 @@ error[E0282]: type annotations needed
2240
LL | gen {};
2341
| ^^ cannot infer type
2442

25-
error: aborting due to 3 previous errors
43+
error[E0282]: type annotations needed
44+
--> $DIR/feature-gate-gen_blocks.rs:12:15
45+
|
46+
LL | async gen {};
47+
| ^^ cannot infer type
48+
49+
error: aborting due to 6 previous errors
2650

2751
Some errors have detailed explanations: E0282, E0658.
2852
For more information about an error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
2+
--> $DIR/feature-gate-gen_blocks.rs:12:11
3+
|
4+
LL | async gen {};
5+
| ^^^ expected one of 8 possible tokens
6+
7+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
8+
--> $DIR/feature-gate-gen_blocks.rs:25:11
9+
|
10+
LL | async gen {};
11+
| ^^^ expected one of 8 possible tokens
12+
113
error[E0422]: cannot find struct, variant or union type `gen` in this scope
214
--> $DIR/feature-gate-gen_blocks.rs:5:5
315
|
416
LL | gen {};
517
| ^^^ not found in this scope
618

7-
error: aborting due to 1 previous error
19+
error: aborting due to 3 previous errors
820

921
For more information about this error, try `rustc --explain E0422`.
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
// revisions: e2024 none
22
//[e2024] compile-flags: --edition 2024 -Zunstable-options
33

4-
fn main() {
4+
fn test_gen() {
55
gen {};
66
//[none]~^ ERROR: cannot find struct, variant or union type `gen`
77
//[e2024]~^^ ERROR: gen blocks are experimental
88
//[e2024]~| ERROR: type annotations needed
99
}
1010

11+
fn test_async_gen() {
12+
async gen {};
13+
//[none]~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
14+
//[e2024]~^^ ERROR: gen blocks are experimental
15+
//[e2024]~| ERROR: type annotations needed
16+
}
17+
18+
fn main() {}
19+
1120
#[cfg(FALSE)]
1221
fn foo() {
1322
gen {};
1423
//[e2024]~^ ERROR: gen blocks are experimental
24+
25+
async gen {};
26+
//[e2024]~^ ERROR: gen blocks are experimental
27+
//[none]~^^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen`
1528
}

0 commit comments

Comments
 (0)
Failed to load comments.