Skip to content

Commit e0a726c

Browse files
Adjust error yield/await lowering
1 parent fc3800f commit e0a726c

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -764,10 +764,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
764764
Some(hir::CoroutineKind::Coroutine(_))
765765
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
766766
| None => {
767-
return hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
768-
await_kw_span,
769-
item_span: self.current_item,
770-
}));
767+
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
768+
// is not accidentally orphaned.
769+
let stmt_id = self.next_id();
770+
let expr_err = self.expr(
771+
expr.span,
772+
hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
773+
await_kw_span,
774+
item_span: self.current_item,
775+
})),
776+
);
777+
return hir::ExprKind::Block(
778+
self.block_all(
779+
expr.span,
780+
arena_vec![self; hir::Stmt {
781+
hir_id: stmt_id,
782+
kind: hir::StmtKind::Semi(expr),
783+
span: expr.span,
784+
}],
785+
Some(self.arena.alloc(expr_err)),
786+
),
787+
None,
788+
);
771789
}
772790
};
773791

@@ -1500,12 +1518,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
15001518
}
15011519

15021520
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
1521+
let yielded =
1522+
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
1523+
15031524
let is_async_gen = match self.coroutine_kind {
15041525
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
15051526
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
15061527
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
1507-
return hir::ExprKind::Err(
1508-
self.dcx().emit_err(AsyncCoroutinesNotSupported { span }),
1528+
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
1529+
// is not accidentally orphaned.
1530+
let stmt_id = self.next_id();
1531+
let expr_err = self.expr(
1532+
yielded.span,
1533+
hir::ExprKind::Err(self.dcx().emit_err(AsyncCoroutinesNotSupported { span })),
1534+
);
1535+
return hir::ExprKind::Block(
1536+
self.block_all(
1537+
yielded.span,
1538+
arena_vec![self; hir::Stmt {
1539+
hir_id: stmt_id,
1540+
kind: hir::StmtKind::Semi(yielded),
1541+
span: yielded.span,
1542+
}],
1543+
Some(self.arena.alloc(expr_err)),
1544+
),
1545+
None,
15091546
);
15101547
}
15111548
Some(hir::CoroutineKind::Coroutine(_)) => {
@@ -1535,9 +1572,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
15351572
}
15361573
};
15371574

1538-
let yielded =
1539-
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
1540-
15411575
if is_async_gen {
15421576
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
15431577
// This ensures that we store our resumed `ResumeContext` correctly, and also that
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@ edition:2021
2+
3+
fn main() {
4+
async {
5+
use std::ops::Add;
6+
let _ = 1.add(3);
7+
}.await
8+
//~^ ERROR `await` is only allowed inside `async` functions and blocks
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0728]: `await` is only allowed inside `async` functions and blocks
2+
--> $DIR/async-outside-of-await-issue-121096.rs:7:7
3+
|
4+
LL | fn main() {
5+
| ---- this is not `async`
6+
...
7+
LL | }.await
8+
| ^^^^^ only allowed inside `async` functions and blocks
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0728`.

0 commit comments

Comments
 (0)