diff options
| author | Laurențiu Nicola <lnicola@users.noreply.github.com> | 2025-06-18 07:06:44 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-18 07:06:44 +0000 |
| commit | e7971e4a9b815968139b977ece9a76b62bf4fb10 (patch) | |
| tree | cffff70f378cd396603c7bf3054cbf6a02bb4735 /compiler/rustc_parse/src/parser/expr.rs | |
| parent | 20a62ab2a112fa973b4e891afd2358a23c5aef78 (diff) | |
| parent | 96e1d731ee0b8e6ba8520bf694e79953fffc5b98 (diff) | |
| download | rust-e7971e4a9b815968139b977ece9a76b62bf4fb10.tar.gz rust-e7971e4a9b815968139b977ece9a76b62bf4fb10.zip | |
Merge pull request #20032 from lnicola/sync-from-rust
minor: Sync from downstream
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a298c4d4dec..93c76c47f06 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1520,22 +1520,20 @@ impl<'a> Parser<'a> { 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. + let at_async = this.check_keyword(exp!(Async)); + // check for `gen {}` and `gen move {}` + // or `async gen {}` and `async gen move {}` + // FIXME: (async) gen closures aren't yet parsed. + // FIXME(gen_blocks): Parse `gen async` and suggest swap 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(exp!(Async)) && this.is_gen_block(kw::Gen, 1))) + && this.is_gen_block(kw::Gen, at_async as usize) { - // FIXME: (async) gen closures aren't yet parsed. this.parse_gen_block() - } else if this.check_keyword(exp!(Async)) { - // FIXME(gen_blocks): Parse `gen async` and suggest swap - if this.is_gen_block(kw::Async, 0) { - // Check for `async {` and `async move {`, - this.parse_gen_block() - } else { - this.parse_expr_closure() - } + // Check for `async {` and `async move {`, + } else if this.is_gen_block(kw::Async, 0) { + this.parse_gen_block() + } else if at_async { + this.parse_expr_closure() } else if this.eat_keyword_noexpect(kw::Await) { this.recover_incorrect_await_syntax(lo) } else { @@ -2407,6 +2405,14 @@ impl<'a> Parser<'a> { None }; + if let ClosureBinder::NotPresent = binder + && coroutine_kind.is_some() + { + // coroutine closures and generators can have the same qualifiers, so we might end up + // in here if there is a missing `|` but also no `{`. Adjust the expectations in that case. + self.expected_token_types.insert(TokenType::OpenBrace); + } + let capture_clause = self.parse_capture_clause()?; let (fn_decl, fn_arg_span) = self.parse_fn_block_decl()?; let decl_hi = self.prev_token.span; @@ -4081,7 +4087,7 @@ impl<'a> CondChecker<'a> { } impl MutVisitor for CondChecker<'_> { - fn visit_expr(&mut self, e: &mut P<Expr>) { + fn visit_expr(&mut self, e: &mut Expr) { self.depth += 1; use ForbiddenLetReason::*; |
