Adjust error yield/await lowering
This commit is contained in:
@@ -764,10 +764,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
Some(hir::CoroutineKind::Coroutine(_))
|
||||
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
|
||||
| None => {
|
||||
return hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||
await_kw_span,
|
||||
item_span: self.current_item,
|
||||
}));
|
||||
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
|
||||
// is not accidentally orphaned.
|
||||
let stmt_id = self.next_id();
|
||||
let expr_err = self.expr(
|
||||
expr.span,
|
||||
hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||
await_kw_span,
|
||||
item_span: self.current_item,
|
||||
})),
|
||||
);
|
||||
return hir::ExprKind::Block(
|
||||
self.block_all(
|
||||
expr.span,
|
||||
arena_vec![self; hir::Stmt {
|
||||
hir_id: stmt_id,
|
||||
kind: hir::StmtKind::Semi(expr),
|
||||
span: expr.span,
|
||||
}],
|
||||
Some(self.arena.alloc(expr_err)),
|
||||
),
|
||||
None,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1500,12 +1518,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
|
||||
let yielded =
|
||||
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
|
||||
|
||||
let is_async_gen = match self.coroutine_kind {
|
||||
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
|
||||
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
|
||||
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
|
||||
return hir::ExprKind::Err(
|
||||
self.dcx().emit_err(AsyncCoroutinesNotSupported { span }),
|
||||
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
|
||||
// is not accidentally orphaned.
|
||||
let stmt_id = self.next_id();
|
||||
let expr_err = self.expr(
|
||||
yielded.span,
|
||||
hir::ExprKind::Err(self.dcx().emit_err(AsyncCoroutinesNotSupported { span })),
|
||||
);
|
||||
return hir::ExprKind::Block(
|
||||
self.block_all(
|
||||
yielded.span,
|
||||
arena_vec![self; hir::Stmt {
|
||||
hir_id: stmt_id,
|
||||
kind: hir::StmtKind::Semi(yielded),
|
||||
span: yielded.span,
|
||||
}],
|
||||
Some(self.arena.alloc(expr_err)),
|
||||
),
|
||||
None,
|
||||
);
|
||||
}
|
||||
Some(hir::CoroutineKind::Coroutine(_)) => {
|
||||
@@ -1535,9 +1572,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
};
|
||||
|
||||
let yielded =
|
||||
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
|
||||
|
||||
if is_async_gen {
|
||||
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
|
||||
// This ensures that we store our resumed `ResumeContext` correctly, and also that
|
||||
|
||||
Reference in New Issue
Block a user