diff options
| author | Jubilee <46493976+workingjubilee@users.noreply.github.com> | 2023-12-12 18:48:55 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-12 18:48:55 -0800 |
| commit | f9078a40ee265222c08a6373aa1a87ba647ee45d (patch) | |
| tree | 91ef09d02d0b8da25fcbea2fac379e4040310874 /compiler/rustc_parse/src/parser/expr.rs | |
| parent | 4583a0134fdf8757eaa831f8c1537f23dd2435d3 (diff) | |
| parent | 1d78ce681e4bf0c0259fc97e422298d68635dc4f (diff) | |
| download | rust-f9078a40ee265222c08a6373aa1a87ba647ee45d.tar.gz rust-f9078a40ee265222c08a6373aa1a87ba647ee45d.zip | |
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
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5b0011e9f70..509cef9826b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1440,21 +1440,23 @@ impl<'a> Parser<'a> { } 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 { @@ -3227,9 +3229,16 @@ impl<'a> Parser<'a> { 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); |
