Option<CoroutineKind>
This commit is contained in:
parent
48d5f1f0f2
commit
f9d1f922dc
22 changed files with 117 additions and 122 deletions
|
@ -1311,7 +1311,7 @@ pub struct Closure {
|
||||||
pub binder: ClosureBinder,
|
pub binder: ClosureBinder,
|
||||||
pub capture_clause: CaptureBy,
|
pub capture_clause: CaptureBy,
|
||||||
pub constness: Const,
|
pub constness: Const,
|
||||||
pub coro_kind: CoroutineKind,
|
pub coro_kind: Option<CoroutineKind>,
|
||||||
pub movability: Movability,
|
pub movability: Movability,
|
||||||
pub fn_decl: P<FnDecl>,
|
pub fn_decl: P<FnDecl>,
|
||||||
pub body: P<Expr>,
|
pub body: P<Expr>,
|
||||||
|
@ -2417,8 +2417,6 @@ pub enum CoroutineKind {
|
||||||
Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
||||||
/// `gen`, which evaluates to `impl Iterator`
|
/// `gen`, which evaluates to `impl Iterator`
|
||||||
Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
|
||||||
/// Neither `async` nor `gen`
|
|
||||||
None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CoroutineKind {
|
impl CoroutineKind {
|
||||||
|
@ -2430,14 +2428,12 @@ impl CoroutineKind {
|
||||||
matches!(self, CoroutineKind::Gen { .. })
|
matches!(self, CoroutineKind::Gen { .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
|
/// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait`
|
||||||
pub fn opt_return_id(self) -> Option<(NodeId, Span)> {
|
/// item.
|
||||||
|
pub fn return_id(self) -> (NodeId, Span) {
|
||||||
match self {
|
match self {
|
||||||
CoroutineKind::Async { return_impl_trait_id, span, .. }
|
CoroutineKind::Async { return_impl_trait_id, span, .. }
|
||||||
| CoroutineKind::Gen { return_impl_trait_id, span, .. } => {
|
| CoroutineKind::Gen { return_impl_trait_id, span, .. } => (return_impl_trait_id, span),
|
||||||
Some((return_impl_trait_id, span))
|
|
||||||
}
|
|
||||||
CoroutineKind::None => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2842,7 +2838,7 @@ pub struct FnHeader {
|
||||||
/// The `unsafe` keyword, if any
|
/// The `unsafe` keyword, if any
|
||||||
pub unsafety: Unsafe,
|
pub unsafety: Unsafe,
|
||||||
/// Whether this is `async`, `gen`, or nothing.
|
/// Whether this is `async`, `gen`, or nothing.
|
||||||
pub coro_kind: CoroutineKind,
|
pub coro_kind: Option<CoroutineKind>,
|
||||||
/// The `const` keyword, if any
|
/// The `const` keyword, if any
|
||||||
pub constness: Const,
|
pub constness: Const,
|
||||||
/// The `extern` keyword and corresponding ABI string, if any
|
/// The `extern` keyword and corresponding ABI string, if any
|
||||||
|
@ -2854,7 +2850,7 @@ impl FnHeader {
|
||||||
pub fn has_qualifiers(&self) -> bool {
|
pub fn has_qualifiers(&self) -> bool {
|
||||||
let Self { unsafety, coro_kind, constness, ext } = self;
|
let Self { unsafety, coro_kind, constness, ext } = self;
|
||||||
matches!(unsafety, Unsafe::Yes(_))
|
matches!(unsafety, Unsafe::Yes(_))
|
||||||
|| !matches!(coro_kind, CoroutineKind::None)
|
|| coro_kind.is_some()
|
||||||
|| matches!(constness, Const::Yes(_))
|
|| matches!(constness, Const::Yes(_))
|
||||||
|| !matches!(ext, Extern::None)
|
|| !matches!(ext, Extern::None)
|
||||||
}
|
}
|
||||||
|
@ -2862,12 +2858,7 @@ impl FnHeader {
|
||||||
|
|
||||||
impl Default for FnHeader {
|
impl Default for FnHeader {
|
||||||
fn default() -> FnHeader {
|
fn default() -> FnHeader {
|
||||||
FnHeader {
|
FnHeader { unsafety: Unsafe::No, coro_kind: None, constness: Const::No, ext: Extern::None }
|
||||||
unsafety: Unsafe::No,
|
|
||||||
coro_kind: CoroutineKind::None,
|
|
||||||
constness: Const::No,
|
|
||||||
ext: Extern::None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(closure_id);
|
||||||
vis.visit_id(return_impl_trait_id);
|
vis.visit_id(return_impl_trait_id);
|
||||||
}
|
}
|
||||||
CoroutineKind::None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,7 +1172,7 @@ fn visit_const_item<T: MutVisitor>(
|
||||||
pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
|
pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
|
||||||
let FnHeader { unsafety, coro_kind, constness, ext: _ } = header;
|
let FnHeader { unsafety, coro_kind, constness, ext: _ } = header;
|
||||||
visit_constness(constness, vis);
|
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);
|
visit_unsafety(unsafety, vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,7 +1415,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||||
}) => {
|
}) => {
|
||||||
vis.visit_closure_binder(binder);
|
vis.visit_closure_binder(binder);
|
||||||
visit_constness(constness, vis);
|
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_capture_by(capture_clause);
|
||||||
vis.visit_fn_decl(fn_decl);
|
vis.visit_fn_decl(fn_decl);
|
||||||
vis.visit_expr(body);
|
vis.visit_expr(body);
|
||||||
|
|
|
@ -202,8 +202,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
fn_decl_span,
|
fn_decl_span,
|
||||||
fn_arg_span,
|
fn_arg_span,
|
||||||
}) => match coro_kind {
|
}) => match coro_kind {
|
||||||
CoroutineKind::Async { closure_id, .. }
|
Some(
|
||||||
| CoroutineKind::Gen { closure_id, .. } => self.lower_expr_async_closure(
|
CoroutineKind::Async { closure_id, .. }
|
||||||
|
| CoroutineKind::Gen { closure_id, .. },
|
||||||
|
) => self.lower_expr_async_closure(
|
||||||
binder,
|
binder,
|
||||||
*capture_clause,
|
*capture_clause,
|
||||||
e.id,
|
e.id,
|
||||||
|
@ -214,7 +216,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
*fn_decl_span,
|
*fn_decl_span,
|
||||||
*fn_arg_span,
|
*fn_arg_span,
|
||||||
),
|
),
|
||||||
CoroutineKind::None => self.lower_expr_closure(
|
None => self.lower_expr_closure(
|
||||||
binder,
|
binder,
|
||||||
*capture_clause,
|
*capture_clause,
|
||||||
e.id,
|
e.id,
|
||||||
|
@ -933,13 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
|
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
|
||||||
// Lower outside new scope to preserve `is_in_loop_condition`.
|
// Lower outside new scope to preserve `is_in_loop_condition`.
|
||||||
let fn_decl = self.lower_fn_decl(
|
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
|
||||||
decl,
|
|
||||||
closure_id,
|
|
||||||
fn_decl_span,
|
|
||||||
FnDeclKind::Closure,
|
|
||||||
CoroutineKind::None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let c = self.arena.alloc(hir::Closure {
|
let c = self.arena.alloc(hir::Closure {
|
||||||
def_id: self.local_def_id(closure_id),
|
def_id: self.local_def_id(closure_id),
|
||||||
|
@ -1054,13 +1050,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// We need to lower the declaration outside the new scope, because we
|
// 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
|
// have to conserve the state of being inside a loop condition for the
|
||||||
// closure argument types.
|
// closure argument types.
|
||||||
let fn_decl = self.lower_fn_decl(
|
let fn_decl =
|
||||||
&outer_decl,
|
self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
|
||||||
closure_id,
|
|
||||||
fn_decl_span,
|
|
||||||
FnDeclKind::Closure,
|
|
||||||
CoroutineKind::None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let c = self.arena.alloc(hir::Closure {
|
let c = self.arena.alloc(hir::Closure {
|
||||||
def_id: self.local_def_id(closure_id),
|
def_id: self.local_def_id(closure_id),
|
||||||
|
|
|
@ -602,7 +602,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
i.id,
|
i.id,
|
||||||
sig.span,
|
sig.span,
|
||||||
FnDeclKind::ExternFn,
|
FnDeclKind::ExternFn,
|
||||||
CoroutineKind::None,
|
None,
|
||||||
),
|
),
|
||||||
this.lower_fn_params_to_names(fdec),
|
this.lower_fn_params_to_names(fdec),
|
||||||
)
|
)
|
||||||
|
@ -841,7 +841,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
||||||
self.current_item = Some(i.span);
|
|
||||||
let body_id = self.lower_maybe_coroutine_body(
|
let body_id = self.lower_maybe_coroutine_body(
|
||||||
i.span,
|
i.span,
|
||||||
hir_id,
|
hir_id,
|
||||||
|
@ -1025,15 +1024,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_id: hir::HirId,
|
fn_id: hir::HirId,
|
||||||
decl: &FnDecl,
|
decl: &FnDecl,
|
||||||
coro_kind: CoroutineKind,
|
coro_kind: Option<CoroutineKind>,
|
||||||
body: Option<&Block>,
|
body: Option<&Block>,
|
||||||
) -> hir::BodyId {
|
) -> hir::BodyId {
|
||||||
let (closure_id, body) = match (coro_kind, body) {
|
let (Some(coro_kind), Some(body)) = (coro_kind, body) else {
|
||||||
(
|
return self.lower_fn_body_block(span, decl, body);
|
||||||
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. },
|
};
|
||||||
Some(body),
|
let closure_id = match coro_kind {
|
||||||
) => (closure_id, body),
|
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. } => {
|
||||||
_ => return self.lower_fn_body_block(span, decl, body),
|
closure_id
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.lower_body(|this| {
|
self.lower_body(|this| {
|
||||||
|
@ -1218,7 +1218,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::CoroutineSource::Fn,
|
hir::CoroutineSource::Fn,
|
||||||
mkbody,
|
mkbody,
|
||||||
),
|
),
|
||||||
CoroutineKind::None => unreachable!("we must have either an async fn or a gen fn"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let hir_id = this.lower_node_id(closure_id);
|
let hir_id = this.lower_node_id(closure_id);
|
||||||
|
@ -1235,7 +1234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
sig: &FnSig,
|
sig: &FnSig,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
kind: FnDeclKind,
|
kind: FnDeclKind,
|
||||||
coro_kind: CoroutineKind,
|
coro_kind: Option<CoroutineKind>,
|
||||||
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
|
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
|
||||||
let header = self.lower_fn_header(sig.header);
|
let header = self.lower_fn_header(sig.header);
|
||||||
let itctx = ImplTraitContext::Universal;
|
let itctx = ImplTraitContext::Universal;
|
||||||
|
@ -1247,7 +1246,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
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)
|
hir::IsAsync::Async(span)
|
||||||
} else {
|
} else {
|
||||||
hir::IsAsync::NotAsync
|
hir::IsAsync::NotAsync
|
||||||
|
|
|
@ -1359,13 +1359,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
generic_params,
|
generic_params,
|
||||||
unsafety: self.lower_unsafety(f.unsafety),
|
unsafety: self.lower_unsafety(f.unsafety),
|
||||||
abi: self.lower_extern(f.ext),
|
abi: self.lower_extern(f.ext),
|
||||||
decl: self.lower_fn_decl(
|
decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
|
||||||
&f.decl,
|
|
||||||
t.id,
|
|
||||||
t.span,
|
|
||||||
FnDeclKind::Pointer,
|
|
||||||
CoroutineKind::None,
|
|
||||||
),
|
|
||||||
param_names: self.lower_fn_params_to_names(&f.decl),
|
param_names: self.lower_fn_params_to_names(&f.decl),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -1800,7 +1794,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
fn_node_id: NodeId,
|
fn_node_id: NodeId,
|
||||||
fn_span: Span,
|
fn_span: Span,
|
||||||
kind: FnDeclKind,
|
kind: FnDeclKind,
|
||||||
coro: CoroutineKind,
|
coro: Option<CoroutineKind>,
|
||||||
) -> &'hir hir::FnDecl<'hir> {
|
) -> &'hir hir::FnDecl<'hir> {
|
||||||
let c_variadic = decl.c_variadic();
|
let c_variadic = decl.c_variadic();
|
||||||
|
|
||||||
|
@ -1830,11 +1824,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let output = match coro {
|
let output = match coro {
|
||||||
CoroutineKind::Async { .. } | CoroutineKind::Gen { .. } => {
|
Some(coro) => {
|
||||||
let fn_def_id = self.local_def_id(fn_node_id);
|
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)
|
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) => {
|
FnRetTy::Ty(ty) => {
|
||||||
let context = if kind.return_impl_trait_allowed() {
|
let context = if kind.return_impl_trait_allowed() {
|
||||||
let fn_def_id = self.local_def_id(fn_node_id);
|
let fn_def_id = self.local_def_id(fn_node_id);
|
||||||
|
@ -1911,9 +1905,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let opaque_ty_node_id = match coro {
|
let opaque_ty_node_id = match coro {
|
||||||
CoroutineKind::Async { return_impl_trait_id, .. }
|
CoroutineKind::Async { return_impl_trait_id, .. }
|
||||||
| CoroutineKind::Gen { return_impl_trait_id, .. } => 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
|
let captured_lifetimes: Vec<_> = self
|
||||||
|
@ -1971,7 +1962,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let (symbol, lang_item) = match coro {
|
let (symbol, lang_item) = match coro {
|
||||||
CoroutineKind::Async { .. } => (hir::FN_OUTPUT_NAME, hir::LangItem::Future),
|
CoroutineKind::Async { .. } => (hir::FN_OUTPUT_NAME, hir::LangItem::Future),
|
||||||
CoroutineKind::Gen { .. } => (hir::ITERATOR_ITEM_NAME, hir::LangItem::Iterator),
|
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 {
|
let future_args = self.arena.alloc(hir::GenericArgs {
|
||||||
|
|
|
@ -1268,13 +1268,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
|
|
||||||
self.check_c_variadic_type(fk);
|
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 {
|
if let Some(&FnHeader {
|
||||||
constness: Const::Yes(cspan),
|
constness: Const::Yes(cspan),
|
||||||
coro_kind: CoroutineKind::Async { span: aspan, .. },
|
coro_kind:
|
||||||
|
Some(
|
||||||
|
CoroutineKind::Async { span: aspan, .. }
|
||||||
|
| CoroutineKind::Gen { span: aspan, .. },
|
||||||
|
),
|
||||||
..
|
..
|
||||||
}) = fk.header()
|
}) = fk.header()
|
||||||
{
|
{
|
||||||
|
// FIXME(eholk): Report a different error for `const gen`
|
||||||
self.err_handler().emit_err(errors::ConstAndAsync {
|
self.err_handler().emit_err(errors::ConstAndAsync {
|
||||||
spans: vec![cspan, aspan],
|
spans: vec![cspan, aspan],
|
||||||
cspan,
|
cspan,
|
||||||
|
|
|
@ -1492,7 +1492,6 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
fn print_coro_kind(&mut self, coro_kind: ast::CoroutineKind) {
|
fn print_coro_kind(&mut self, coro_kind: ast::CoroutineKind) {
|
||||||
match coro_kind {
|
match coro_kind {
|
||||||
ast::CoroutineKind::None => {}
|
|
||||||
ast::CoroutineKind::Gen { .. } => {
|
ast::CoroutineKind::Gen { .. } => {
|
||||||
self.word_nbsp("gen");
|
self.word_nbsp("gen");
|
||||||
}
|
}
|
||||||
|
@ -1691,7 +1690,7 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
fn print_fn_header_info(&mut self, header: ast::FnHeader) {
|
fn print_fn_header_info(&mut self, header: ast::FnHeader) {
|
||||||
self.print_constness(header.constness);
|
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);
|
self.print_unsafety(header.unsafety);
|
||||||
|
|
||||||
match header.ext {
|
match header.ext {
|
||||||
|
|
|
@ -423,7 +423,7 @@ impl<'a> State<'a> {
|
||||||
self.print_closure_binder(binder);
|
self.print_closure_binder(binder);
|
||||||
self.print_constness(*constness);
|
self.print_constness(*constness);
|
||||||
self.print_movability(*movability);
|
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_capture_clause(*capture_clause);
|
||||||
|
|
||||||
self.print_fn_params_and_ret(fn_decl, true);
|
self.print_fn_params_and_ret(fn_decl, true);
|
||||||
|
|
|
@ -541,7 +541,7 @@ fn check_test_signature(
|
||||||
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
|
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" }));
|
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,7 +547,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
binder: ast::ClosureBinder::NotPresent,
|
binder: ast::ClosureBinder::NotPresent,
|
||||||
capture_clause: ast::CaptureBy::Ref,
|
capture_clause: ast::CaptureBy::Ref,
|
||||||
constness: ast::Const::No,
|
constness: ast::Const::No,
|
||||||
coro_kind: ast::CoroutineKind::None,
|
coro_kind: None,
|
||||||
movability: ast::Movability::Movable,
|
movability: ast::Movability::Movable,
|
||||||
fn_decl,
|
fn_decl,
|
||||||
body,
|
body,
|
||||||
|
|
|
@ -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
|
// Explicitly check for lints associated with 'closure_id', since
|
||||||
// it does not have a corresponding AST node
|
// it does not have a corresponding AST node
|
||||||
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
|
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
|
||||||
if let ast::CoroutineKind::Async { closure_id, .. }
|
if let Some(
|
||||||
| ast::CoroutineKind::Gen { closure_id, .. } = sig.header.coro_kind
|
ast::CoroutineKind::Async { closure_id, .. }
|
||||||
|
| ast::CoroutineKind::Gen { closure_id, .. },
|
||||||
|
) = sig.header.coro_kind
|
||||||
{
|
{
|
||||||
self.check_id(closure_id);
|
self.check_id(closure_id);
|
||||||
}
|
}
|
||||||
|
@ -226,8 +228,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ast::ExprKind::Closure(box ast::Closure {
|
ast::ExprKind::Closure(box ast::Closure {
|
||||||
coro_kind:
|
coro_kind:
|
||||||
ast::CoroutineKind::Async { closure_id, .. }
|
Some(
|
||||||
| ast::CoroutineKind::Gen { closure_id, .. },
|
ast::CoroutineKind::Async { closure_id, .. }
|
||||||
|
| ast::CoroutineKind::Gen { closure_id, .. },
|
||||||
|
),
|
||||||
..
|
..
|
||||||
}) => self.check_id(closure_id),
|
}) => self.check_id(closure_id),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use super::{
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::maybe_recover_from_interpolated_ty_qpath;
|
use crate::maybe_recover_from_interpolated_ty_qpath;
|
||||||
use ast::mut_visit::{noop_visit_expr, MutVisitor};
|
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 core::mem;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||||
|
@ -21,9 +21,7 @@ use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
|
||||||
use rustc_ast::visit::Visitor;
|
use rustc_ast::visit::Visitor;
|
||||||
use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID};
|
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::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
|
||||||
use rustc_ast::{
|
use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
|
||||||
Arm, BlockCheckMode, CoroutineKind, Expr, ExprKind, Label, Movability, RangeLimits,
|
|
||||||
};
|
|
||||||
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
|
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
|
@ -2239,7 +2237,7 @@ impl<'a> Parser<'a> {
|
||||||
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() {
|
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() {
|
||||||
self.parse_asyncness(Case::Sensitive)
|
self.parse_asyncness(Case::Sensitive)
|
||||||
} else {
|
} else {
|
||||||
CoroutineKind::None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let capture_clause = self.parse_capture_clause()?;
|
let capture_clause = self.parse_capture_clause()?;
|
||||||
|
@ -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.
|
// Feature-gate `async ||` closures.
|
||||||
self.sess.gated_spans.gate(sym::async_closure, span);
|
self.sess.gated_spans.gate(sym::async_closure, span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2401,7 +2401,7 @@ impl<'a> Parser<'a> {
|
||||||
let ext_start_sp = self.token.span;
|
let ext_start_sp = self.token.span;
|
||||||
let ext = self.parse_extern(case);
|
let ext = self.parse_extern(case);
|
||||||
|
|
||||||
if let CoroutineKind::Async { span, .. } = asyncness {
|
if let Some(CoroutineKind::Async { span, .. }) = asyncness {
|
||||||
if span.is_rust_2015() {
|
if span.is_rust_2015() {
|
||||||
self.sess.emit_err(errors::AsyncFnIn2015 {
|
self.sess.emit_err(errors::AsyncFnIn2015 {
|
||||||
span,
|
span,
|
||||||
|
@ -2410,13 +2410,13 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let CoroutineKind::Gen { span, .. } = genness {
|
if let Some(CoroutineKind::Gen { span, .. }) = genness {
|
||||||
self.sess.gated_spans.gate(sym::gen_blocks, span);
|
self.sess.gated_spans.gate(sym::gen_blocks, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (
|
if let (
|
||||||
CoroutineKind::Async { span: async_span, .. },
|
Some(CoroutineKind::Async { span: async_span, .. }),
|
||||||
CoroutineKind::Gen { span: gen_span, .. },
|
Some(CoroutineKind::Gen { span: gen_span, .. }),
|
||||||
) = (asyncness, genness)
|
) = (asyncness, genness)
|
||||||
{
|
{
|
||||||
self.sess.emit_err(errors::AsyncGenFn { span: async_span.to(gen_span) });
|
self.sess.emit_err(errors::AsyncGenFn { span: async_span.to(gen_span) });
|
||||||
|
@ -2452,16 +2452,18 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
} else if self.check_keyword(kw::Async) {
|
} else if self.check_keyword(kw::Async) {
|
||||||
match asyncness {
|
match asyncness {
|
||||||
CoroutineKind::Async { span, .. } => Some(WrongKw::Duplicated(span)),
|
Some(CoroutineKind::Async { span, .. }) => {
|
||||||
CoroutineKind::Gen { .. } => {
|
Some(WrongKw::Duplicated(span))
|
||||||
|
}
|
||||||
|
Some(CoroutineKind::Gen { .. }) => {
|
||||||
panic!("not sure how to recover here")
|
panic!("not sure how to recover here")
|
||||||
}
|
}
|
||||||
CoroutineKind::None => {
|
None => {
|
||||||
recover_asyncness = CoroutineKind::Async {
|
recover_asyncness = Some(CoroutineKind::Async {
|
||||||
span: self.token.span,
|
span: self.token.span,
|
||||||
closure_id: DUMMY_NODE_ID,
|
closure_id: DUMMY_NODE_ID,
|
||||||
return_impl_trait_id: DUMMY_NODE_ID,
|
return_impl_trait_id: DUMMY_NODE_ID,
|
||||||
};
|
});
|
||||||
Some(WrongKw::Misplaced(unsafe_start_sp))
|
Some(WrongKw::Misplaced(unsafe_start_sp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2566,9 +2568,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let coro_kind = match asyncness {
|
let coro_kind = match asyncness {
|
||||||
CoroutineKind::Async { .. } => asyncness,
|
Some(CoroutineKind::Async { .. }) => asyncness,
|
||||||
CoroutineKind::Gen { .. } => unreachable!("asycness cannot be Gen"),
|
Some(CoroutineKind::Gen { .. }) => unreachable!("asycness cannot be Gen"),
|
||||||
CoroutineKind::None => genness,
|
None => genness,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(FnHeader { constness, unsafety, coro_kind, ext })
|
Ok(FnHeader { constness, unsafety, coro_kind, ext })
|
||||||
|
|
|
@ -1125,30 +1125,30 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses asyncness: `async` or nothing.
|
/// Parses asyncness: `async` or nothing.
|
||||||
fn parse_asyncness(&mut self, case: Case) -> CoroutineKind {
|
fn parse_asyncness(&mut self, case: Case) -> Option<CoroutineKind> {
|
||||||
if self.eat_keyword_case(kw::Async, case) {
|
if self.eat_keyword_case(kw::Async, case) {
|
||||||
let span = self.prev_token.uninterpolated_span();
|
let span = self.prev_token.uninterpolated_span();
|
||||||
CoroutineKind::Async {
|
Some(CoroutineKind::Async {
|
||||||
span,
|
span,
|
||||||
closure_id: DUMMY_NODE_ID,
|
closure_id: DUMMY_NODE_ID,
|
||||||
return_impl_trait_id: DUMMY_NODE_ID,
|
return_impl_trait_id: DUMMY_NODE_ID,
|
||||||
}
|
})
|
||||||
} else {
|
} else {
|
||||||
CoroutineKind::None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses genness: `gen` or nothing.
|
/// Parses genness: `gen` or nothing.
|
||||||
fn parse_genness(&mut self, case: Case) -> CoroutineKind {
|
fn parse_genness(&mut self, case: Case) -> Option<CoroutineKind> {
|
||||||
if self.token.span.at_least_rust_2024() && self.eat_keyword_case(kw::Gen, case) {
|
if self.token.span.at_least_rust_2024() && self.eat_keyword_case(kw::Gen, case) {
|
||||||
let span = self.prev_token.uninterpolated_span();
|
let span = self.prev_token.uninterpolated_span();
|
||||||
CoroutineKind::Gen {
|
Some(CoroutineKind::Gen {
|
||||||
span,
|
span,
|
||||||
closure_id: DUMMY_NODE_ID,
|
closure_id: DUMMY_NODE_ID,
|
||||||
return_impl_trait_id: DUMMY_NODE_ID,
|
return_impl_trait_id: DUMMY_NODE_ID,
|
||||||
}
|
})
|
||||||
} else {
|
} else {
|
||||||
CoroutineKind::None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -609,7 +609,7 @@ impl<'a> Parser<'a> {
|
||||||
// cover it.
|
// cover it.
|
||||||
self.sess.emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
|
self.sess.emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
|
||||||
}
|
}
|
||||||
if let ast::CoroutineKind::Async { span, .. } = coro_kind {
|
if let Some(ast::CoroutineKind::Async { span, .. }) = coro_kind {
|
||||||
self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
|
self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
|
||||||
}
|
}
|
||||||
// FIXME(eholk): emit a similar error for `gen fn()`
|
// FIXME(eholk): emit a similar error for `gen fn()`
|
||||||
|
|
|
@ -156,9 +156,9 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
||||||
|
|
||||||
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
||||||
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
|
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
|
||||||
// FIXME(eholk): handle `async gen fn`
|
if let Some(
|
||||||
if let CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. } =
|
CoroutineKind::Async { closure_id, .. } | CoroutineKind::Gen { closure_id, .. },
|
||||||
sig.header.coro_kind
|
) = sig.header.coro_kind
|
||||||
{
|
{
|
||||||
self.visit_generics(generics);
|
self.visit_generics(generics);
|
||||||
|
|
||||||
|
@ -285,11 +285,11 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
||||||
// we must create two defs.
|
// we must create two defs.
|
||||||
let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
|
let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
|
||||||
match closure.coro_kind {
|
match closure.coro_kind {
|
||||||
CoroutineKind::Async { closure_id, .. }
|
Some(
|
||||||
| CoroutineKind::Gen { closure_id, .. } => {
|
CoroutineKind::Async { closure_id, .. }
|
||||||
self.create_def(closure_id, kw::Empty, DefKind::Closure, expr.span)
|
| CoroutineKind::Gen { closure_id, .. },
|
||||||
}
|
) => self.create_def(closure_id, kw::Empty, DefKind::Closure, expr.span),
|
||||||
CoroutineKind::None => closure_def,
|
None => closure_def,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Gen(_, _, _) => {
|
ExprKind::Gen(_, _, _) => {
|
||||||
|
|
|
@ -916,7 +916,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||||
&sig.decl.output,
|
&sig.decl.output,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some((async_node_id, _)) = sig.header.coro_kind.opt_return_id() {
|
if let Some((async_node_id, _)) =
|
||||||
|
sig.header.coro_kind.map(|coro_kind| coro_kind.return_id())
|
||||||
|
{
|
||||||
this.record_lifetime_params_for_impl_trait(async_node_id);
|
this.record_lifetime_params_for_impl_trait(async_node_id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -940,7 +942,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
|
|
||||||
let declaration = &sig.decl;
|
let declaration = &sig.decl;
|
||||||
let async_node_id = sig.header.coro_kind.opt_return_id();
|
let async_node_id =
|
||||||
|
sig.header.coro_kind.map(|coro_kind| coro_kind.return_id());
|
||||||
|
|
||||||
this.with_lifetime_rib(
|
this.with_lifetime_rib(
|
||||||
LifetimeRibKind::AnonymousCreateParameter {
|
LifetimeRibKind::AnonymousCreateParameter {
|
||||||
|
@ -4289,7 +4292,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||||
// resolve the arguments within the proper scopes so that usages of them inside the
|
// resolve the arguments within the proper scopes so that usages of them inside the
|
||||||
// closure are detected as upvars rather than normal closure arg usages.
|
// closure are detected as upvars rather than normal closure arg usages.
|
||||||
ExprKind::Closure(box ast::Closure {
|
ExprKind::Closure(box ast::Closure {
|
||||||
coro_kind: CoroutineKind::Async { .. },
|
coro_kind: Some(CoroutineKind::Async { .. }),
|
||||||
ref fn_decl,
|
ref fn_decl,
|
||||||
ref body,
|
ref body,
|
||||||
..
|
..
|
||||||
|
|
|
@ -700,7 +700,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, range: Range<u
|
||||||
ItemKind::Fn(box Fn {
|
ItemKind::Fn(box Fn {
|
||||||
sig, body: Some(block), ..
|
sig, body: Some(block), ..
|
||||||
}) if item.ident.name == sym::main => {
|
}) if item.ident.name == sym::main => {
|
||||||
let is_async = sig.header.coro_kind.is_async();
|
let is_async = sig.header.coro_kind.map_or(false, |coro| coro.is_async());
|
||||||
let returns_nothing = match &sig.decl.output {
|
let returns_nothing = match &sig.decl.output {
|
||||||
FnRetTy::Default(..) => true,
|
FnRetTy::Default(..) => true,
|
||||||
FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
|
FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
|
||||||
|
|
|
@ -206,7 +206,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
||||||
) => {
|
) => {
|
||||||
eq_closure_binder(lb, rb)
|
eq_closure_binder(lb, rb)
|
||||||
&& lc == rc
|
&& lc == rc
|
||||||
&& la.is_async() == ra.is_async()
|
&& la.map_or(false, |la| la.is_async()) == ra.map_or(false, |ra| ra.is_async())
|
||||||
&& lm == rm
|
&& lm == rm
|
||||||
&& eq_fn_decl(lf, rf)
|
&& eq_fn_decl(lf, rf)
|
||||||
&& eq_expr(le, re)
|
&& eq_expr(le, re)
|
||||||
|
@ -563,9 +563,18 @@ pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {
|
||||||
eq_fn_decl(&l.decl, &r.decl) && eq_fn_header(&l.header, &r.header)
|
eq_fn_decl(&l.decl, &r.decl) && eq_fn_header(&l.header, &r.header)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eq_opt_coro_kind(l: Option<CoroutineKind>, r: Option<CoroutineKind>) -> bool {
|
||||||
|
match (l, r) {
|
||||||
|
(Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
|
||||||
|
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. })) => true,
|
||||||
|
(None, None) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
|
pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
|
||||||
matches!(l.unsafety, Unsafe::No) == matches!(r.unsafety, Unsafe::No)
|
matches!(l.unsafety, Unsafe::No) == matches!(r.unsafety, Unsafe::No)
|
||||||
&& (l.coro_kind.is_async() == r.coro_kind.is_async() || l.coro_kind.is_gen() == r.coro_kind.is_gen())
|
&& eq_opt_coro_kind(l.coro_kind, r.coro_kind)
|
||||||
&& matches!(l.constness, Const::No) == matches!(r.constness, Const::No)
|
&& matches!(l.constness, Const::No) == matches!(r.constness, Const::No)
|
||||||
&& eq_ext(&l.ext, &r.ext)
|
&& eq_ext(&l.ext, &r.ext)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub(crate) fn rewrite_closure(
|
||||||
binder: &ast::ClosureBinder,
|
binder: &ast::ClosureBinder,
|
||||||
constness: ast::Const,
|
constness: ast::Const,
|
||||||
capture: ast::CaptureBy,
|
capture: ast::CaptureBy,
|
||||||
coro_kind: &ast::CoroutineKind,
|
coro_kind: &Option<ast::CoroutineKind>,
|
||||||
movability: ast::Movability,
|
movability: ast::Movability,
|
||||||
fn_decl: &ast::FnDecl,
|
fn_decl: &ast::FnDecl,
|
||||||
body: &ast::Expr,
|
body: &ast::Expr,
|
||||||
|
@ -233,7 +233,7 @@ fn rewrite_closure_fn_decl(
|
||||||
binder: &ast::ClosureBinder,
|
binder: &ast::ClosureBinder,
|
||||||
constness: ast::Const,
|
constness: ast::Const,
|
||||||
capture: ast::CaptureBy,
|
capture: ast::CaptureBy,
|
||||||
coro_kind: &ast::CoroutineKind,
|
coro_kind: &Option<ast::CoroutineKind>,
|
||||||
movability: ast::Movability,
|
movability: ast::Movability,
|
||||||
fn_decl: &ast::FnDecl,
|
fn_decl: &ast::FnDecl,
|
||||||
body: &ast::Expr,
|
body: &ast::Expr,
|
||||||
|
@ -263,8 +263,13 @@ fn rewrite_closure_fn_decl(
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
let is_async = if coro_kind.is_async() { "async " } else { "" };
|
let (is_async, is_gen) = if let Some(coro_kind) = coro_kind {
|
||||||
let is_gen = if coro_kind.is_gen() { "gen " } else { "" };
|
let is_async = if coro_kind.is_async() { "async " } else { "" };
|
||||||
|
let is_gen = if coro_kind.is_gen() { "gen " } else { "" };
|
||||||
|
(is_async, is_gen)
|
||||||
|
} else {
|
||||||
|
("", "")
|
||||||
|
};
|
||||||
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {
|
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {
|
||||||
"move "
|
"move "
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -287,7 +287,7 @@ pub(crate) struct FnSig<'a> {
|
||||||
decl: &'a ast::FnDecl,
|
decl: &'a ast::FnDecl,
|
||||||
generics: &'a ast::Generics,
|
generics: &'a ast::Generics,
|
||||||
ext: ast::Extern,
|
ext: ast::Extern,
|
||||||
coro_kind: Cow<'a, ast::CoroutineKind>,
|
coro_kind: Cow<'a, Option<ast::CoroutineKind>>,
|
||||||
constness: ast::Const,
|
constness: ast::Const,
|
||||||
defaultness: ast::Defaultness,
|
defaultness: ast::Defaultness,
|
||||||
unsafety: ast::Unsafe,
|
unsafety: ast::Unsafe,
|
||||||
|
@ -343,7 +343,8 @@ impl<'a> FnSig<'a> {
|
||||||
result.push_str(&*format_visibility(context, self.visibility));
|
result.push_str(&*format_visibility(context, self.visibility));
|
||||||
result.push_str(format_defaultness(self.defaultness));
|
result.push_str(format_defaultness(self.defaultness));
|
||||||
result.push_str(format_constness(self.constness));
|
result.push_str(format_constness(self.constness));
|
||||||
result.push_str(format_coro(&self.coro_kind));
|
self.coro_kind
|
||||||
|
.map(|coro_kind| result.push_str(format_coro(&coro_kind)));
|
||||||
result.push_str(format_unsafety(self.unsafety));
|
result.push_str(format_unsafety(self.unsafety));
|
||||||
result.push_str(&format_extern(
|
result.push_str(&format_extern(
|
||||||
self.ext,
|
self.ext,
|
||||||
|
|
|
@ -79,7 +79,6 @@ pub(crate) fn format_coro(coro_kind: &ast::CoroutineKind) -> &'static str {
|
||||||
match coro_kind {
|
match coro_kind {
|
||||||
ast::CoroutineKind::Async { .. } => "async ",
|
ast::CoroutineKind::Async { .. } => "async ",
|
||||||
ast::CoroutineKind::Gen { .. } => "gen ",
|
ast::CoroutineKind::Gen { .. } => "gen ",
|
||||||
ast::CoroutineKind::None => "",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue