-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Add expectation for {
when parsing lone coroutine qualifiers
#142362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... this feels like sth that we'd regularly hit elsewhere, too, because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was feeling the same about this actually, but I couldn't figure out a solution for this either for the time being. We would need to start consuming the qualifier list before dispatching into the actual coroutine / generator parsing routines I think given we can't build expectations for lookaheads. |
||
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; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shuffled this around while looking through the call path as I found the
{async} gen
condition a bit heavy on the eyes. Happy to undo this