Auto merge of #118420 - compiler-errors:async-gen, r=eholk
Introduce support for `async gen` blocks I'm delighted to demonstrate that `async gen` block are not very difficult to support. They're simply coroutines that yield `Poll<Option<T>>` and return `()`. **This PR is WIP and in draft mode for now** -- I'm mostly putting it up to show folks that it's possible. This PR needs a lang-team experiment associated with it or possible an RFC, since I don't think it falls under the jurisdiction of the `gen` RFC that was recently authored by oli (https://github.com/rust-lang/rfcs/pull/3513, https://github.com/rust-lang/rust/issues/117078). ### Technical note on the pre-generator-transform yield type: The reason that the underlying coroutines yield `Poll<Option<T>>` and not `Poll<T>` (which would make more sense, IMO, for the pre-transformed coroutine), is because the `TransformVisitor` that is used to turn coroutines into built-in state machine functions would have to destructure and reconstruct the latter into the former, which requires at least inserting a new basic block (for a `switchInt` terminator, to match on the `Poll` discriminant). This does mean that the desugaring (at the `rustc_ast_lowering` level) of `async gen` blocks is a bit more involved. However, since we already need to intercept both `.await` and `yield` operators, I don't consider it much of a technical burden. r? `@ghost`
This commit is contained in:
commit
f967532a47
61 changed files with 1120 additions and 357 deletions
|
@ -162,11 +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 Some(
|
||||
ast::CoroutineKind::Async { closure_id, .. }
|
||||
| ast::CoroutineKind::Gen { closure_id, .. },
|
||||
) = sig.header.coro_kind
|
||||
{
|
||||
if let Some(coro_kind) = sig.header.coroutine_kind {
|
||||
let (ast::CoroutineKind::Async { closure_id, .. }
|
||||
| ast::CoroutineKind::Gen { closure_id, .. }
|
||||
| ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind;
|
||||
self.check_id(closure_id);
|
||||
}
|
||||
}
|
||||
|
@ -227,13 +226,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
|||
// it does not have a corresponding AST node
|
||||
match e.kind {
|
||||
ast::ExprKind::Closure(box ast::Closure {
|
||||
coro_kind:
|
||||
Some(
|
||||
ast::CoroutineKind::Async { closure_id, .. }
|
||||
| ast::CoroutineKind::Gen { closure_id, .. },
|
||||
),
|
||||
..
|
||||
}) => self.check_id(closure_id),
|
||||
coroutine_kind: Some(coro_kind), ..
|
||||
}) => {
|
||||
let (ast::CoroutineKind::Async { closure_id, .. }
|
||||
| ast::CoroutineKind::Gen { closure_id, .. }
|
||||
| ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind;
|
||||
self.check_id(closure_id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
lint_callback!(self, check_expr_post, e);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue