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
|
@ -541,12 +541,30 @@ fn check_test_signature(
|
|||
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
|
||||
}
|
||||
|
||||
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" }));
|
||||
}
|
||||
|
||||
if let Some(ast::CoroutineKind::Gen { span, .. }) = f.sig.header.coro_kind {
|
||||
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "gen" }));
|
||||
if let Some(coro_kind) = f.sig.header.coroutine_kind {
|
||||
match coro_kind {
|
||||
ast::CoroutineKind::Async { span, .. } => {
|
||||
return Err(sd.emit_err(errors::TestBadFn {
|
||||
span: i.span,
|
||||
cause: span,
|
||||
kind: "async",
|
||||
}));
|
||||
}
|
||||
ast::CoroutineKind::Gen { span, .. } => {
|
||||
return Err(sd.emit_err(errors::TestBadFn {
|
||||
span: i.span,
|
||||
cause: span,
|
||||
kind: "gen",
|
||||
}));
|
||||
}
|
||||
ast::CoroutineKind::AsyncGen { span, .. } => {
|
||||
return Err(sd.emit_err(errors::TestBadFn {
|
||||
span: i.span,
|
||||
cause: span,
|
||||
kind: "async gen",
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the termination trait is active, the compiler will check that the output
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue