Adjust error yield/await lowering
This commit is contained in:
parent
fc3800f657
commit
e0a726ca4b
@ -764,10 +764,28 @@ fn make_lowered_await(
|
|||||||
Some(hir::CoroutineKind::Coroutine(_))
|
Some(hir::CoroutineKind::Coroutine(_))
|
||||||
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
|
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
|
||||||
| None => {
|
| None => {
|
||||||
return hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
|
||||||
await_kw_span,
|
// is not accidentally orphaned.
|
||||||
item_span: self.current_item,
|
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 @@ fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'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 {
|
let is_async_gen = match self.coroutine_kind {
|
||||||
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
|
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
|
||||||
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
|
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
|
||||||
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
|
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
|
||||||
return hir::ExprKind::Err(
|
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
|
||||||
self.dcx().emit_err(AsyncCoroutinesNotSupported { span }),
|
// 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(_)) => {
|
Some(hir::CoroutineKind::Coroutine(_)) => {
|
||||||
@ -1535,9 +1572,6 @@ fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::Expr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let yielded =
|
|
||||||
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
|
|
||||||
|
|
||||||
if is_async_gen {
|
if is_async_gen {
|
||||||
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
|
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
|
||||||
// This ensures that we store our resumed `ResumeContext` correctly, and also that
|
// This ensures that we store our resumed `ResumeContext` correctly, and also that
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
//@ edition:2021
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
async {
|
||||||
|
use std::ops::Add;
|
||||||
|
let _ = 1.add(3);
|
||||||
|
}.await
|
||||||
|
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
|
--> $DIR/async-outside-of-await-issue-121096.rs:7:7
|
||||||
|
|
|
||||||
|
LL | fn main() {
|
||||||
|
| ---- this is not `async`
|
||||||
|
...
|
||||||
|
LL | }.await
|
||||||
|
| ^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0728`.
|
Loading…
Reference in New Issue
Block a user