Skip to content

Commit

Permalink
Option<CoroutineKind>
Browse files Browse the repository at this point in the history
  • Loading branch information
eholk committed Dec 4, 2023
1 parent 48d5f1f commit f9d1f92
Show file tree
Hide file tree
Showing 22 changed files with 117 additions and 122 deletions.
25 changes: 8 additions & 17 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ pub struct Closure {
pub binder: ClosureBinder,
pub capture_clause: CaptureBy,
pub constness: Const,
pub coro_kind: CoroutineKind,
pub coro_kind: Option<CoroutineKind>,
pub movability: Movability,
pub fn_decl: P<FnDecl>,
pub body: P<Expr>,
Expand Down Expand Up @@ -2417,8 +2417,6 @@ pub enum CoroutineKind {
Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
/// `gen`, which evaluates to `impl Iterator`
Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
/// Neither `async` nor `gen`
None,
}

impl CoroutineKind {
Expand All @@ -2430,14 +2428,12 @@ impl CoroutineKind {
matches!(self, CoroutineKind::Gen { .. })
}

/// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
pub fn opt_return_id(self) -> Option<(NodeId, Span)> {
/// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait`
/// item.
pub fn return_id(self) -> (NodeId, Span) {
match self {
CoroutineKind::Async { return_impl_trait_id, span, .. }
| CoroutineKind::Gen { return_impl_trait_id, span, .. } => {
Some((return_impl_trait_id, span))
}
CoroutineKind::None => None,
| CoroutineKind::Gen { return_impl_trait_id, span, .. } => (return_impl_trait_id, span),
}
}
}
Expand Down Expand Up @@ -2842,7 +2838,7 @@ pub struct FnHeader {
/// The `unsafe` keyword, if any
pub unsafety: Unsafe,
/// Whether this is `async`, `gen`, or nothing.
pub coro_kind: CoroutineKind,
pub coro_kind: Option<CoroutineKind>,
/// The `const` keyword, if any
pub constness: Const,
/// The `extern` keyword and corresponding ABI string, if any
Expand All @@ -2854,20 +2850,15 @@ impl FnHeader {
pub fn has_qualifiers(&self) -> bool {
let Self { unsafety, coro_kind, constness, ext } = self;
matches!(unsafety, Unsafe::Yes(_))
|| !matches!(coro_kind, CoroutineKind::None)
|| coro_kind.is_some()
|| matches!(constness, Const::Yes(_))
|| !matches!(ext, Extern::None)
}
}

impl Default for FnHeader {
fn default() -> FnHeader {
FnHeader {
unsafety: Unsafe::No,
coro_kind: CoroutineKind::None,
constness: Const::No,
ext: Extern::None,
}
FnHeader { unsafety: Unsafe::No, coro_kind: None, constness: Const::No, ext: Extern::None }
}
}

Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,6 @@ pub fn noop_visit_coro_kind<T: MutVisitor>(coro_kind: &mut CoroutineKind, vis: &
vis.visit_id(closure_id);
vis.visit_id(return_impl_trait_id);
}
CoroutineKind::None => {}
}
}

Expand Down Expand Up @@ -1173,7 +1172,7 @@ fn visit_const_item<T: MutVisitor>(
pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
let FnHeader { unsafety, coro_kind, constness, ext: _ } = header;
visit_constness(constness, vis);
vis.visit_coro_kind(coro_kind);
coro_kind.as_mut().map(|coro_kind| vis.visit_coro_kind(coro_kind));
visit_unsafety(unsafety, vis);
}

Expand Down Expand Up @@ -1416,7 +1415,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
}) => {
vis.visit_closure_binder(binder);
visit_constness(constness, vis);
vis.visit_coro_kind(coro_kind);
coro_kind.as_mut().map(|coro_kind| vis.visit_coro_kind(coro_kind));
vis.visit_capture_by(capture_clause);
vis.visit_fn_decl(fn_decl);
vis.visit_expr(body);
Expand Down
25 changes: 8 additions & 17 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl_span,
fn_arg_span,
}) => match coro_kind {
CoroutineKind::Async { closure_id, .. }
| CoroutineKind::Gen { closure_id, .. } => self.lower_expr_async_closure(
Some(
CoroutineKind::Async { closure_id, .. }
| CoroutineKind::Gen { closure_id, .. },
) => self.lower_expr_async_closure(
binder,
*capture_clause,
e.id,
Expand All @@ -214,7 +216,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
*fn_decl_span,
*fn_arg_span,
),
CoroutineKind::None => self.lower_expr_closure(
None => self.lower_expr_closure(
binder,
*capture_clause,
e.id,
Expand Down Expand Up @@ -933,13 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
// Lower outside new scope to preserve `is_in_loop_condition`.
let fn_decl = self.lower_fn_decl(
decl,
closure_id,
fn_decl_span,
FnDeclKind::Closure,
CoroutineKind::None,
);
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);

let c = self.arena.alloc(hir::Closure {
def_id: self.local_def_id(closure_id),
Expand Down Expand Up @@ -1054,13 +1050,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
// We need to lower the declaration outside the new scope, because we
// have to conserve the state of being inside a loop condition for the
// closure argument types.
let fn_decl = self.lower_fn_decl(
&outer_decl,
closure_id,
fn_decl_span,
FnDeclKind::Closure,
CoroutineKind::None,
);
let fn_decl =
self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);

let c = self.arena.alloc(hir::Closure {
def_id: self.local_def_id(closure_id),
Expand Down
23 changes: 11 additions & 12 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
i.id,
sig.span,
FnDeclKind::ExternFn,
CoroutineKind::None,
None,
),
this.lower_fn_params_to_names(fdec),
)
Expand Down Expand Up @@ -841,7 +841,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
),
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
self.current_item = Some(i.span);
let body_id = self.lower_maybe_coroutine_body(
i.span,
hir_id,
Expand Down Expand Up @@ -1025,15 +1024,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
fn_id: hir::HirId,
decl: &FnDecl,
coro_kind: CoroutineKind,
coro_kind: Option<CoroutineKind>,
body: Option<&Block>,
) -> hir::BodyId {
let (closure_id, body) = match (coro_kind, body) {
(
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. },
Some(body),
) => (closure_id, body),
_ => return self.lower_fn_body_block(span, decl, body),
let (Some(coro_kind), Some(body)) = (coro_kind, body) else {
return self.lower_fn_body_block(span, decl, body);
};
let closure_id = match coro_kind {
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. } => {
closure_id
}
};

self.lower_body(|this| {
Expand Down Expand Up @@ -1218,7 +1218,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::CoroutineSource::Fn,
mkbody,
),
CoroutineKind::None => unreachable!("we must have either an async fn or a gen fn"),
};

let hir_id = this.lower_node_id(closure_id);
Expand All @@ -1235,7 +1234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
sig: &FnSig,
id: NodeId,
kind: FnDeclKind,
coro_kind: CoroutineKind,
coro_kind: Option<CoroutineKind>,
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
let header = self.lower_fn_header(sig.header);
let itctx = ImplTraitContext::Universal;
Expand All @@ -1247,7 +1246,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
let asyncness = if let CoroutineKind::Async { span, .. } = h.coro_kind {
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coro_kind {
hir::IsAsync::Async(span)
} else {
hir::IsAsync::NotAsync
Expand Down
18 changes: 4 additions & 14 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1359,13 +1359,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
generic_params,
unsafety: self.lower_unsafety(f.unsafety),
abi: self.lower_extern(f.ext),
decl: self.lower_fn_decl(
&f.decl,
t.id,
t.span,
FnDeclKind::Pointer,
CoroutineKind::None,
),
decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
param_names: self.lower_fn_params_to_names(&f.decl),
}))
}
Expand Down Expand Up @@ -1800,7 +1794,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn_node_id: NodeId,
fn_span: Span,
kind: FnDeclKind,
coro: CoroutineKind,
coro: Option<CoroutineKind>,
) -> &'hir hir::FnDecl<'hir> {
let c_variadic = decl.c_variadic();

Expand Down Expand Up @@ -1830,11 +1824,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}));

let output = match coro {
CoroutineKind::Async { .. } | CoroutineKind::Gen { .. } => {
Some(coro) => {
let fn_def_id = self.local_def_id(fn_node_id);
self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
}
CoroutineKind::None => match &decl.output {
None => match &decl.output {
FnRetTy::Ty(ty) => {
let context = if kind.return_impl_trait_allowed() {
let fn_def_id = self.local_def_id(fn_node_id);
Expand Down Expand Up @@ -1911,9 +1905,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let opaque_ty_node_id = match coro {
CoroutineKind::Async { return_impl_trait_id, .. }
| CoroutineKind::Gen { return_impl_trait_id, .. } => return_impl_trait_id,
CoroutineKind::None => {
unreachable!("lower_coroutine_fn_ret_ty must be called with either Async or Gen")
}
};

let captured_lifetimes: Vec<_> = self
Expand Down Expand Up @@ -1971,7 +1962,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let (symbol, lang_item) = match coro {
CoroutineKind::Async { .. } => (hir::FN_OUTPUT_NAME, hir::LangItem::Future),
CoroutineKind::Gen { .. } => (hir::ITERATOR_ITEM_NAME, hir::LangItem::Iterator),
CoroutineKind::None => panic!("attemping to lower output type of non-coroutine fn"),
};

let future_args = self.arena.alloc(hir::GenericArgs {
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,13 +1268,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

self.check_c_variadic_type(fk);

// Functions cannot both be `const async`
// Functions cannot both be `const async` or `const gen`
if let Some(&FnHeader {
constness: Const::Yes(cspan),
coro_kind: CoroutineKind::Async { span: aspan, .. },
coro_kind:
Some(
CoroutineKind::Async { span: aspan, .. }
| CoroutineKind::Gen { span: aspan, .. },
),
..
}) = fk.header()
{
// FIXME(eholk): Report a different error for `const gen`
self.err_handler().emit_err(errors::ConstAndAsync {
spans: vec![cspan, aspan],
cspan,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,6 @@ impl<'a> State<'a> {

fn print_coro_kind(&mut self, coro_kind: ast::CoroutineKind) {
match coro_kind {
ast::CoroutineKind::None => {}
ast::CoroutineKind::Gen { .. } => {
self.word_nbsp("gen");
}
Expand Down Expand Up @@ -1691,7 +1690,7 @@ impl<'a> State<'a> {

fn print_fn_header_info(&mut self, header: ast::FnHeader) {
self.print_constness(header.constness);
self.print_coro_kind(header.coro_kind);
header.coro_kind.map(|coro_kind| self.print_coro_kind(coro_kind));
self.print_unsafety(header.unsafety);

match header.ext {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ impl<'a> State<'a> {
self.print_closure_binder(binder);
self.print_constness(*constness);
self.print_movability(*movability);
self.print_coro_kind(*coro_kind);
coro_kind.map(|coro_kind| self.print_coro_kind(coro_kind));
self.print_capture_clause(*capture_clause);

self.print_fn_params_and_ret(fn_decl, true);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ fn check_test_signature(
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
}

if let ast::CoroutineKind::Async { span, .. } = f.sig.header.coro_kind {
if let Some(ast::CoroutineKind::Async { span, .. }) = f.sig.header.coro_kind {
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" }));
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ impl<'a> ExtCtxt<'a> {
binder: ast::ClosureBinder::NotPresent,
capture_clause: ast::CaptureBy::Ref,
constness: ast::Const::No,
coro_kind: ast::CoroutineKind::None,
coro_kind: None,
movability: ast::Movability::Movable,
fn_decl,
body,
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
// Explicitly check for lints associated with 'closure_id', since
// it does not have a corresponding AST node
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
if let ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. } = sig.header.coro_kind
if let Some(
ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. },
) = sig.header.coro_kind
{
self.check_id(closure_id);
}
Expand Down Expand Up @@ -226,8 +228,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
match e.kind {
ast::ExprKind::Closure(box ast::Closure {
coro_kind:
ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. },
Some(
ast::CoroutineKind::Async { closure_id, .. }
| ast::CoroutineKind::Gen { closure_id, .. },
),
..
}) => self.check_id(closure_id),
_ => {}
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::{
use crate::errors;
use crate::maybe_recover_from_interpolated_ty_qpath;
use ast::mut_visit::{noop_visit_expr, MutVisitor};
use ast::{GenBlockKind, Pat, Path, PathSegment};
use ast::{CoroutineKind, GenBlockKind, Pat, Path, PathSegment};
use core::mem;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
Expand All @@ -21,9 +21,7 @@ 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, BlockCheckMode, CoroutineKind, Expr, ExprKind, Label, Movability, RangeLimits,
};
use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
use rustc_ast_pretty::pprust;
use rustc_data_structures::stack::ensure_sufficient_stack;
Expand Down Expand Up @@ -2239,7 +2237,7 @@ impl<'a> Parser<'a> {
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() {
self.parse_asyncness(Case::Sensitive)
} else {
CoroutineKind::None
None
};

let capture_clause = self.parse_capture_clause()?;
Expand All @@ -2263,7 +2261,7 @@ impl<'a> Parser<'a> {
}
};

if let CoroutineKind::Async { span, .. } = asyncness {
if let Some(CoroutineKind::Async { span, .. }) = asyncness {
// Feature-gate `async ||` closures.
self.sess.gated_spans.gate(sym::async_closure, span);
}
Expand Down
Loading

0 comments on commit f9d1f92

Please sign in to comment.