Merge Async and Gen into CoroutineKind
This commit is contained in:
parent
3887b1645a
commit
48d5f1f0f2
25 changed files with 442 additions and 238 deletions
|
@ -21,7 +21,9 @@ use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
|
|||
use rustc_ast::visit::Visitor;
|
||||
use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID};
|
||||
use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
|
||||
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
|
||||
use rustc_ast::{
|
||||
Arm, BlockCheckMode, CoroutineKind, Expr, ExprKind, Label, Movability, RangeLimits,
|
||||
};
|
||||
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
|
@ -2237,7 +2239,7 @@ impl<'a> Parser<'a> {
|
|||
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() {
|
||||
self.parse_asyncness(Case::Sensitive)
|
||||
} else {
|
||||
Async::No
|
||||
CoroutineKind::None
|
||||
};
|
||||
|
||||
let capture_clause = self.parse_capture_clause()?;
|
||||
|
@ -2261,7 +2263,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
if let Async::Yes { span, .. } = asyncness {
|
||||
if let CoroutineKind::Async { span, .. } = asyncness {
|
||||
// Feature-gate `async ||` closures.
|
||||
self.sess.gated_spans.gate(sym::async_closure, span);
|
||||
}
|
||||
|
@ -2284,7 +2286,7 @@ impl<'a> Parser<'a> {
|
|||
binder,
|
||||
capture_clause,
|
||||
constness,
|
||||
asyncness,
|
||||
coro_kind: asyncness,
|
||||
movability,
|
||||
fn_decl,
|
||||
body,
|
||||
|
|
|
@ -11,8 +11,8 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
|||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::MacCall;
|
||||
use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID};
|
||||
use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
|
||||
use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind};
|
||||
use rustc_ast::{Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
|
||||
use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData};
|
||||
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
||||
use rustc_ast_pretty::pprust;
|
||||
|
@ -2401,7 +2401,7 @@ impl<'a> Parser<'a> {
|
|||
let ext_start_sp = self.token.span;
|
||||
let ext = self.parse_extern(case);
|
||||
|
||||
if let Async::Yes { span, .. } = asyncness {
|
||||
if let CoroutineKind::Async { span, .. } = asyncness {
|
||||
if span.is_rust_2015() {
|
||||
self.sess.emit_err(errors::AsyncFnIn2015 {
|
||||
span,
|
||||
|
@ -2410,12 +2410,14 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Gen::Yes { span, .. } = genness {
|
||||
if let CoroutineKind::Gen { span, .. } = genness {
|
||||
self.sess.gated_spans.gate(sym::gen_blocks, span);
|
||||
}
|
||||
|
||||
if let (Async::Yes { span: async_span, .. }, Gen::Yes { span: gen_span, .. }) =
|
||||
(asyncness, genness)
|
||||
if let (
|
||||
CoroutineKind::Async { span: async_span, .. },
|
||||
CoroutineKind::Gen { span: gen_span, .. },
|
||||
) = (asyncness, genness)
|
||||
{
|
||||
self.sess.emit_err(errors::AsyncGenFn { span: async_span.to(gen_span) });
|
||||
}
|
||||
|
@ -2450,9 +2452,12 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
} else if self.check_keyword(kw::Async) {
|
||||
match asyncness {
|
||||
Async::Yes { span, .. } => Some(WrongKw::Duplicated(span)),
|
||||
Async::No => {
|
||||
recover_asyncness = Async::Yes {
|
||||
CoroutineKind::Async { span, .. } => Some(WrongKw::Duplicated(span)),
|
||||
CoroutineKind::Gen { .. } => {
|
||||
panic!("not sure how to recover here")
|
||||
}
|
||||
CoroutineKind::None => {
|
||||
recover_asyncness = CoroutineKind::Async {
|
||||
span: self.token.span,
|
||||
closure_id: DUMMY_NODE_ID,
|
||||
return_impl_trait_id: DUMMY_NODE_ID,
|
||||
|
@ -2537,6 +2542,8 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(eholk): add keyword recovery logic for genness
|
||||
|
||||
if wrong_kw.is_some()
|
||||
&& self.may_recover()
|
||||
&& self.look_ahead(1, |tok| tok.is_keyword_case(kw::Fn, case))
|
||||
|
@ -2548,8 +2555,7 @@ impl<'a> Parser<'a> {
|
|||
return Ok(FnHeader {
|
||||
constness: recover_constness,
|
||||
unsafety: recover_unsafety,
|
||||
asyncness: recover_asyncness,
|
||||
genness, // FIXME(eholk): add keyword recovery logic here too.
|
||||
coro_kind: recover_asyncness,
|
||||
ext,
|
||||
});
|
||||
}
|
||||
|
@ -2559,7 +2565,13 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(FnHeader { constness, unsafety, asyncness, ext, genness })
|
||||
let coro_kind = match asyncness {
|
||||
CoroutineKind::Async { .. } => asyncness,
|
||||
CoroutineKind::Gen { .. } => unreachable!("asycness cannot be Gen"),
|
||||
CoroutineKind::None => genness,
|
||||
};
|
||||
|
||||
Ok(FnHeader { constness, unsafety, coro_kind, ext })
|
||||
}
|
||||
|
||||
/// Parses the parameter list and result type of a function declaration.
|
||||
|
|
|
@ -11,7 +11,6 @@ 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;
|
||||
|
@ -25,9 +24,10 @@ use rustc_ast::tokenstream::{AttributesData, DelimSpan, Spacing};
|
|||
use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor};
|
||||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::AttrId;
|
||||
use rustc_ast::CoroutineKind;
|
||||
use rustc_ast::DUMMY_NODE_ID;
|
||||
use rustc_ast::{self as ast, AnonConst, Const, DelimArgs, Extern};
|
||||
use rustc_ast::{Async, AttrArgs, AttrArgsEq, Expr, ExprKind, Mutability, StrLit};
|
||||
use rustc_ast::{AttrArgs, AttrArgsEq, Expr, ExprKind, Mutability, StrLit};
|
||||
use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -1125,22 +1125,30 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parses asyncness: `async` or nothing.
|
||||
fn parse_asyncness(&mut self, case: Case) -> Async {
|
||||
fn parse_asyncness(&mut self, case: Case) -> CoroutineKind {
|
||||
if self.eat_keyword_case(kw::Async, case) {
|
||||
let span = self.prev_token.uninterpolated_span();
|
||||
Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
|
||||
CoroutineKind::Async {
|
||||
span,
|
||||
closure_id: DUMMY_NODE_ID,
|
||||
return_impl_trait_id: DUMMY_NODE_ID,
|
||||
}
|
||||
} else {
|
||||
Async::No
|
||||
CoroutineKind::None
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses genness: `gen` or nothing.
|
||||
fn parse_genness(&mut self, case: Case) -> Gen {
|
||||
fn parse_genness(&mut self, case: Case) -> CoroutineKind {
|
||||
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 }
|
||||
CoroutineKind::Gen {
|
||||
span,
|
||||
closure_id: DUMMY_NODE_ID,
|
||||
return_impl_trait_id: DUMMY_NODE_ID,
|
||||
}
|
||||
} else {
|
||||
Gen::No
|
||||
CoroutineKind::None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -596,7 +596,7 @@ impl<'a> Parser<'a> {
|
|||
tokens: None,
|
||||
};
|
||||
let span_start = self.token.span;
|
||||
let ast::FnHeader { ext, unsafety, constness, asyncness, genness: _ } =
|
||||
let ast::FnHeader { ext, unsafety, constness, coro_kind } =
|
||||
self.parse_fn_front_matter(&inherited_vis, Case::Sensitive)?;
|
||||
if self.may_recover() && self.token.kind == TokenKind::Lt {
|
||||
self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
|
||||
|
@ -609,7 +609,7 @@ impl<'a> Parser<'a> {
|
|||
// cover it.
|
||||
self.sess.emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
|
||||
}
|
||||
if let ast::Async::Yes { span, .. } = asyncness {
|
||||
if let ast::CoroutineKind::Async { span, .. } = coro_kind {
|
||||
self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
|
||||
}
|
||||
// FIXME(eholk): emit a similar error for `gen fn()`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue