Add explicit syntax for coroutines instead of relying on closures having yield expressions

This commit is contained in:
Oli Scherer 2024-04-11 12:48:32 +00:00
parent 29a56a3b1c
commit a589632dad
3 changed files with 19 additions and 3 deletions

View File

@ -217,6 +217,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
binder, binder,
*capture_clause, *capture_clause,
e.id, e.id,
hir_id,
*constness, *constness,
*movability, *movability,
fn_decl, fn_decl,
@ -955,6 +956,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
binder: &ClosureBinder, binder: &ClosureBinder,
capture_clause: CaptureBy, capture_clause: CaptureBy,
closure_id: NodeId, closure_id: NodeId,
closure_hir_id: hir::HirId,
constness: Const, constness: Const,
movability: Movability, movability: Movability,
decl: &FnDecl, decl: &FnDecl,
@ -965,7 +967,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (binder_clause, generic_params) = self.lower_closure_binder(binder); let (binder_clause, generic_params) = self.lower_closure_binder(binder);
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| { let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
let mut coroutine_kind = None; let mut coroutine_kind = if this
.attrs
.get(&closure_hir_id.local_id)
.is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine)))
{
Some(hir::CoroutineKind::Coroutine(Movability::Movable))
} else {
None
};
let body_id = this.lower_fn_body(decl, |this| { let body_id = this.lower_fn_body(decl, |this| {
let e = this.lower_expr_mut(body); let e = this.lower_expr_mut(body);
coroutine_kind = this.coroutine_kind; coroutine_kind = this.coroutine_kind;

View File

@ -534,6 +534,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::Yes, experimental!(cfi_encoding) EncodeCrossCrate::Yes, experimental!(cfi_encoding)
), ),
// `#[coroutine]` attribute to be applied to closures to make them coroutines instead
gated!(
coroutine, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
),
// ========================================================================== // ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe: // Internal attributes: Stability, deprecation, and unsafe:
// ========================================================================== // ==========================================================================

View File

@ -10,7 +10,7 @@ pub struct Client { pub nickname: String }
fn main() { fn main() {
let g = move || match drop(Client { ..Client::default() }) { let g = move || match drop(Client { ..Client::default() }) {
_status => yield, _status => yield,
}; };
assert_send(g); assert_send(g);
} }