about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src/expr.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-05 08:02:07 +0000
committerbors <bors@rust-lang.org>2024-03-05 08:02:07 +0000
commit41d97c8a5dea2731b0e56fe97cd7cb79e21cff79 (patch)
tree561848a9472e347915a069f2ff991d57cbbeca87 /compiler/rustc_ast_lowering/src/expr.rs
parent5a1e5449c8f4cb6b12b4f64238e3c058767ebf02 (diff)
parent92ff43d87bded06013903c5d44e3397589523a59 (diff)
downloadrust-41d97c8a5dea2731b0e56fe97cd7cb79e21cff79.tar.gz
rust-41d97c8a5dea2731b0e56fe97cd7cb79e21cff79.zip
Auto merge of #122012 - matthiaskrgr:rollup-bzqjj2n, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #121213 (Add an example to demonstrate how Rc::into_inner works)
 - #121262 (Add vector time complexity)
 - #121287 (Clarify/add `must_use` message for Rc/Arc/Weak::into_raw.)
 - #121664 (Adjust error `yield`/`await` lowering)
 - #121826 (Use root obligation on E0277 for some cases)
 - #121838 (Use the correct logic for nested impl trait in assoc types)
 - #121913 (Don't panic when waiting on poisoned queries)
 - #121987 (pattern analysis: abort on arity mismatch)
 - #121993 (Avoid using unnecessary queries when printing the query stack in panics)
 - #121997 (interpret/cast: make more matches on FloatTy properly exhaustive)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_ast_lowering/src/expr.rs')
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs52
1 files changed, 43 insertions, 9 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 0b1cb124080..85b599902b9 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -760,10 +760,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,
+                );
             }
         };
 
@@ -1496,12 +1514,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(_)) => {
@@ -1531,9 +1568,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