Reserve gen
keyword for gen {}
blocks and gen fn
in 2024 edition
This commit is contained in:
parent
ccb160d343
commit
a61cf673cd
14 changed files with 138 additions and 4 deletions
|
@ -520,6 +520,14 @@ pub(crate) struct CatchAfterTry {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_gen_block)]
|
||||
#[help]
|
||||
pub(crate) struct GenBlock {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_comma_after_base_struct)]
|
||||
#[note]
|
||||
|
|
|
@ -1422,6 +1422,9 @@ impl<'a> Parser<'a> {
|
|||
} else if this.is_try_block() {
|
||||
this.expect_keyword(kw::Try)?;
|
||||
this.parse_try_block(lo)
|
||||
} else if this.is_gen_block() {
|
||||
this.expect_keyword(kw::Gen)?;
|
||||
this.parse_gen_block(lo)
|
||||
} else if this.eat_keyword(kw::Return) {
|
||||
this.parse_expr_return()
|
||||
} else if this.eat_keyword(kw::Continue) {
|
||||
|
@ -3040,6 +3043,14 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses a `gen {...}` expression (`gen` token already eaten).
|
||||
fn parse_gen_block(&mut self, _span_lo: Span) -> PResult<'a, P<Expr>> {
|
||||
let (_attrs, _body) = self.parse_inner_attrs_and_block()?;
|
||||
|
||||
Err(errors::GenBlock { span: self.prev_token.span }
|
||||
.into_diagnostic(&self.sess.span_diagnostic))
|
||||
}
|
||||
|
||||
fn is_do_catch_block(&self) -> bool {
|
||||
self.token.is_keyword(kw::Do)
|
||||
&& self.is_keyword_ahead(1, &[kw::Catch])
|
||||
|
@ -3059,6 +3070,13 @@ impl<'a> Parser<'a> {
|
|||
&& self.token.uninterpolated_span().at_least_rust_2018()
|
||||
}
|
||||
|
||||
fn is_gen_block(&self) -> bool {
|
||||
self.token.is_keyword(kw::Gen)
|
||||
&& self
|
||||
.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace) || t.is_whole_block())
|
||||
&& self.token.uninterpolated_span().at_least_rust_2024()
|
||||
}
|
||||
|
||||
/// Parses an `async move? {...}` expression.
|
||||
fn parse_async_block(&mut self) -> PResult<'a, P<Expr>> {
|
||||
let lo = self.token.span;
|
||||
|
|
|
@ -2297,9 +2297,9 @@ impl<'a> Parser<'a> {
|
|||
// `pub` is added in case users got confused with the ordering like `async pub fn`,
|
||||
// only if it wasn't preceded by `default` as `default pub` is invalid.
|
||||
let quals: &[Symbol] = if check_pub {
|
||||
&[kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
|
||||
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
|
||||
} else {
|
||||
&[kw::Const, kw::Async, kw::Unsafe, kw::Extern]
|
||||
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
|
||||
};
|
||||
self.check_keyword_case(kw::Fn, case) // Definitely an `fn`.
|
||||
// `$qual fn` or `$qual $qual`:
|
||||
|
@ -2353,6 +2353,9 @@ impl<'a> Parser<'a> {
|
|||
let async_start_sp = self.token.span;
|
||||
let asyncness = self.parse_asyncness(case);
|
||||
|
||||
let _gen_start_sp = self.token.span;
|
||||
let genness = self.parse_genness(case);
|
||||
|
||||
let unsafe_start_sp = self.token.span;
|
||||
let unsafety = self.parse_unsafety(case);
|
||||
|
||||
|
@ -2368,6 +2371,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Gen::Yes { span, .. } = genness {
|
||||
self.sess.emit_err(errors::GenBlock { span });
|
||||
}
|
||||
|
||||
if !self.eat_keyword_case(kw::Fn, case) {
|
||||
// It is possible for `expect_one_of` to recover given the contents of
|
||||
// `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
|
||||
|
|
|
@ -11,6 +11,7 @@ mod stmt;
|
|||
mod ty;
|
||||
|
||||
use crate::lexer::UnmatchedDelim;
|
||||
use ast::Gen;
|
||||
pub use attr_wrapper::AttrWrapper;
|
||||
pub use diagnostics::AttemptLocalParseRecovery;
|
||||
pub(crate) use expr::ForbiddenLetReason;
|
||||
|
@ -1126,6 +1127,16 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses genness: `gen` or nothing.
|
||||
fn parse_genness(&mut self, case: Case) -> Gen {
|
||||
if self.token.span.at_least_rust_2024() && self.eat_keyword_case(kw::Gen, case) {
|
||||
let span = self.prev_token.uninterpolated_span();
|
||||
Gen::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
|
||||
} else {
|
||||
Gen::No
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses unsafety: `unsafe` or nothing.
|
||||
fn parse_unsafety(&mut self, case: Case) -> Unsafe {
|
||||
if self.eat_keyword_case(kw::Unsafe, case) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue