]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_ast_lowering/src/expr.rs
Rollup merge of #105343 - nbdd0121:hir, r=fee1-dead
[rust.git] / compiler / rustc_ast_lowering / src / expr.rs
index 4260805f1dd1fdfed90cdc8cce97aa605b2f8965..24e2985cf567a3838ee13e168d5d944c7078e6f5 100644 (file)
@@ -16,7 +16,7 @@
 use rustc_hir::definitions::DefPathData;
 use rustc_session::errors::report_lit_error;
 use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
-use rustc_span::symbol::{sym, Ident};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::DUMMY_SP;
 use thin_vec::thin_vec;
 
@@ -147,6 +147,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                 ),
                 ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr(
                     *capture_clause,
+                    None,
                     *closure_node_id,
                     None,
                     e.span,
@@ -435,18 +436,14 @@ fn has_let_expr(expr: &Expr) -> bool {
                 let lhs = self.lower_cond(lhs);
                 let rhs = self.lower_cond(rhs);
 
-                self.arena.alloc(self.expr(
-                    cond.span,
-                    hir::ExprKind::Binary(op, lhs, rhs),
-                    AttrVec::new(),
-                ))
+                self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs)))
             }
             ExprKind::Let(..) => self.lower_expr(cond),
             _ => {
                 let cond = self.lower_expr(cond);
                 let reason = DesugaringKind::CondTemporary;
                 let span_block = self.mark_span_with_reason(reason, cond.span, None);
-                self.expr_drop_temps(span_block, cond, AttrVec::new())
+                self.expr_drop_temps(span_block, cond)
             }
         }
     }
@@ -476,12 +473,12 @@ fn lower_expr_while_in_loop_scope(
     ) -> hir::ExprKind<'hir> {
         let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
         let then = self.lower_block_expr(body);
-        let expr_break = self.expr_break(span, AttrVec::new());
+        let expr_break = self.expr_break(span);
         let stmt_break = self.stmt_expr(span, expr_break);
         let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
-        let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
+        let else_expr = self.arena.alloc(self.expr_block(else_blk));
         let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr));
-        let if_expr = self.expr(span, if_kind, AttrVec::new());
+        let if_expr = self.expr(span, if_kind);
         let block = self.block_expr(self.arena.alloc(if_expr));
         let span = self.lower_span(span.with_hi(cond.span.hi()));
         let opt_label = self.lower_label(opt_label);
@@ -537,12 +534,7 @@ fn wrap_in_try_constructor(
         expr: &'hir hir::Expr<'hir>,
         overall_span: Span,
     ) -> &'hir hir::Expr<'hir> {
-        let constructor = self.arena.alloc(self.expr_lang_item_path(
-            method_span,
-            lang_item,
-            AttrVec::new(),
-            None,
-        ));
+        let constructor = self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, None));
         self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
     }
 
@@ -584,6 +576,7 @@ fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
     pub(super) fn make_async_expr(
         &mut self,
         capture_clause: CaptureBy,
+        outer_hir_id: Option<hir::HirId>,
         closure_node_id: NodeId,
         ret_ty: Option<hir::FnRetTy<'hir>>,
         span: Span,
@@ -592,14 +585,38 @@ pub(super) fn make_async_expr(
     ) -> hir::ExprKind<'hir> {
         let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
 
-        // Resume argument type: `ResumeTy`
-        let unstable_span =
-            self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
-        let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None);
+        // Resume argument type, which should be `&mut Context<'_>`.
+        // NOTE: Using the `'static` lifetime here is technically cheating.
+        // The `Future::poll` argument really is `&'a mut Context<'b>`, but we cannot
+        // express the fact that we are not storing it across yield-points yet,
+        // and we would thus run into lifetime errors.
+        // See <https://github.com/rust-lang/rust/issues/68923>.
+        // Our lowering makes sure we are not mis-using the `_task_context` input type
+        // in the sense that we are indeed not using it across yield points. We
+        // get a fresh `&mut Context` for each resume / call of `Future::poll`.
+        // This "cheating" was previously done with a `ResumeTy` that contained a raw
+        // pointer, and a `get_context` accessor that pulled the `Context` lifetimes
+        // out of thin air.
+        let context_lifetime_ident = Ident::with_dummy_span(kw::StaticLifetime);
+        let context_lifetime = self.arena.alloc(hir::Lifetime {
+            hir_id: self.next_id(),
+            ident: context_lifetime_ident,
+            res: hir::LifetimeName::Static,
+        });
+        let context_path =
+            hir::QPath::LangItem(hir::LangItem::Context, self.lower_span(span), None);
+        let context_ty = hir::MutTy {
+            ty: self.arena.alloc(hir::Ty {
+                hir_id: self.next_id(),
+                kind: hir::TyKind::Path(context_path),
+                span: self.lower_span(span),
+            }),
+            mutbl: hir::Mutability::Mut,
+        };
         let input_ty = hir::Ty {
             hir_id: self.next_id(),
-            kind: hir::TyKind::Path(resume_ty),
-            span: unstable_span,
+            kind: hir::TyKind::Rptr(context_lifetime, context_ty),
+            span: self.lower_span(span),
         };
 
         // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
@@ -651,18 +668,17 @@ pub(super) fn make_async_expr(
 
             hir::ExprKind::Closure(c)
         };
-        let parent_has_track_caller = self
-            .attrs
-            .values()
-            .find(|attrs| attrs.into_iter().find(|attr| attr.has_name(sym::track_caller)).is_some())
-            .is_some();
+
+        let track_caller = outer_hir_id
+            .and_then(|id| self.attrs.get(&id.local_id))
+            .map_or(false, |attrs| attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)));
+
+        let hir_id = self.lower_node_id(closure_node_id);
         let unstable_span =
             self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
-
-        let hir_id = if parent_has_track_caller {
-            let generator_hir_id = self.lower_node_id(closure_node_id);
+        if track_caller {
             self.lower_attrs(
-                generator_hir_id,
+                hir_id,
                 &[Attribute {
                     kind: AttrKind::Normal(ptr::P(NormalAttr {
                         item: AttrItem {
@@ -677,10 +693,7 @@ pub(super) fn make_async_expr(
                     span: unstable_span,
                 }],
             );
-            generator_hir_id
-        } else {
-            self.lower_node_id(closure_node_id)
-        };
+        }
 
         let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };
 
@@ -693,12 +706,8 @@ pub(super) fn make_async_expr(
         // E0700 in src/test/ui/self/self_lifetime-async.rs
 
         // `future::identity_future`:
-        let identity_future = self.expr_lang_item_path(
-            unstable_span,
-            hir::LangItem::IdentityFuture,
-            AttrVec::new(),
-            None,
-        );
+        let identity_future =
+            self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None);
 
         // `future::identity_future(generator)`:
         hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator])
@@ -710,7 +719,7 @@ pub(super) fn make_async_expr(
     ///     mut __awaitee => loop {
     ///         match unsafe { ::std::future::Future::poll(
     ///             <::std::pin::Pin>::new_unchecked(&mut __awaitee),
-    ///             ::std::future::get_context(task_context),
+    ///             task_context,
     ///         ) } {
     ///             ::std::task::Poll::Ready(result) => break result,
     ///             ::std::task::Poll::Pending => {}
@@ -751,7 +760,7 @@ fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKi
         // unsafe {
         //     ::std::future::Future::poll(
         //         ::std::pin::Pin::new_unchecked(&mut __awaitee),
-        //         ::std::future::get_context(task_context),
+        //         task_context,
         //     )
         // }
         let poll_expr = {
@@ -769,16 +778,10 @@ fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKi
                 arena_vec![self; ref_mut_awaitee],
                 Some(expr_hir_id),
             );
-            let get_context = self.expr_call_lang_item_fn_mut(
-                gen_future_span,
-                hir::LangItem::GetContext,
-                arena_vec![self; task_context],
-                Some(expr_hir_id),
-            );
             let call = self.expr_call_lang_item_fn(
                 span,
                 hir::LangItem::FuturePoll,
-                arena_vec![self; new_unchecked, get_context],
+                arena_vec![self; new_unchecked, task_context],
                 Some(expr_hir_id),
             );
             self.arena.alloc(self.expr_unsafe(call))
@@ -801,7 +804,7 @@ fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKi
             let break_x = self.with_loop_scope(loop_node_id, move |this| {
                 let expr_break =
                     hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
-                this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new()))
+                this.arena.alloc(this.expr(gen_future_span, expr_break))
             });
             self.arm(ready_pat, break_x)
         };
@@ -834,17 +837,13 @@ fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKi
             let yield_expr = self.expr(
                 span,
                 hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
-                AttrVec::new(),
             );
             let yield_expr = self.arena.alloc(yield_expr);
 
             if let Some(task_context_hid) = self.task_context {
                 let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
-                let assign = self.expr(
-                    span,
-                    hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)),
-                    AttrVec::new(),
-                );
+                let assign =
+                    self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)));
                 self.stmt_expr(span, assign)
             } else {
                 // Use of `await` outside of an async context. Return `yield_expr` so that we can
@@ -1019,13 +1018,16 @@ fn lower_expr_async_closure(
 
                 let async_body = this.make_async_expr(
                     capture_clause,
+                    // FIXME(nbdd0121): This should also use a proper HIR id so `#[track_caller]`
+                    // can be applied on async closures as well.
+                    None,
                     inner_closure_id,
                     async_ret_ty,
                     body.span,
                     hir::AsyncGeneratorKind::Closure,
                     |this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
                 );
-                this.expr(fn_decl_span, async_body, AttrVec::new())
+                this.expr(fn_decl_span, async_body)
             });
             body_id
         });
@@ -1285,7 +1287,7 @@ fn destructure_assign_mut(
         let ident = self.expr_ident(lhs.span, ident, binding);
         let assign =
             hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
-        let expr = self.expr(lhs.span, assign, AttrVec::new());
+        let expr = self.expr(lhs.span, assign);
         assignments.push(self.stmt_expr(lhs.span, expr));
         pat
     }
@@ -1326,8 +1328,7 @@ fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::
         let e2 = self.lower_expr_mut(e2);
         let fn_path =
             hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
-        let fn_expr =
-            self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
+        let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path)));
         hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
     }
 
@@ -1499,8 +1500,7 @@ fn lower_expr_for(
 
         // `None => break`
         let none_arm = {
-            let break_expr =
-                self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
+            let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span));
             let pat = self.pat_none(for_span);
             self.arm(pat, break_expr)
         };
@@ -1509,7 +1509,7 @@ fn lower_expr_for(
         let some_arm = {
             let some_pat = self.pat_some(pat_span, pat);
             let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
-            let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new()));
+            let body_expr = self.arena.alloc(self.expr_block(body_block));
             self.arm(some_pat, body_expr)
         };
 
@@ -1572,7 +1572,9 @@ fn lower_expr_for(
         // surrounding scope of the `match` since the `match` is not a terminating scope.
         //
         // Also, add the attributes to the outer returned expr node.
-        self.expr_drop_temps_mut(for_span, match_expr, e.attrs.clone())
+        let expr = self.expr_drop_temps_mut(for_span, match_expr);
+        self.lower_attrs(expr.hir_id, &e.attrs);
+        expr
     }
 
     /// Desugar `ExprKind::Try` from: `<expr>?` into:
@@ -1627,12 +1629,8 @@ fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir>
         let continue_arm = {
             let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
-            let val_expr = self.arena.alloc(self.expr_ident_with_attrs(
-                span,
-                val_ident,
-                val_pat_nid,
-                attrs.clone(),
-            ));
+            let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
+            self.lower_attrs(val_expr.hir_id, &attrs);
             let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
             self.arm(continue_pat, val_expr)
         };
@@ -1658,15 +1656,11 @@ fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir>
                         hir::Destination { label: None, target_id },
                         Some(from_residual_expr),
                     ),
-                    attrs,
                 ))
             } else {
-                self.arena.alloc(self.expr(
-                    try_span,
-                    hir::ExprKind::Ret(Some(from_residual_expr)),
-                    attrs,
-                ))
+                self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
             };
+            self.lower_attrs(ret_expr.hir_id, &attrs);
 
             let break_pat = self.pat_cf_break(try_span, residual_local);
             self.arm(break_pat, ret_expr)
@@ -1731,18 +1725,16 @@ pub(super) fn expr_drop_temps(
         &mut self,
         span: Span,
         expr: &'hir hir::Expr<'hir>,
-        attrs: AttrVec,
     ) -> &'hir hir::Expr<'hir> {
-        self.arena.alloc(self.expr_drop_temps_mut(span, expr, attrs))
+        self.arena.alloc(self.expr_drop_temps_mut(span, expr))
     }
 
     pub(super) fn expr_drop_temps_mut(
         &mut self,
         span: Span,
         expr: &'hir hir::Expr<'hir>,
-        attrs: AttrVec,
     ) -> hir::Expr<'hir> {
-        self.expr(span, hir::ExprKind::DropTemps(expr), attrs)
+        self.expr(span, hir::ExprKind::DropTemps(expr))
     }
 
     fn expr_match(
@@ -1752,29 +1744,25 @@ fn expr_match(
         arms: &'hir [hir::Arm<'hir>],
         source: hir::MatchSource,
     ) -> hir::Expr<'hir> {
-        self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new())
+        self.expr(span, hir::ExprKind::Match(arg, arms, source))
     }
 
-    fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> {
+    fn expr_break(&mut self, span: Span) -> hir::Expr<'hir> {
         let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
-        self.expr(span, expr_break, attrs)
+        self.expr(span, expr_break)
     }
 
-    fn expr_break_alloc(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> {
-        let expr_break = self.expr_break(span, attrs);
+    fn expr_break_alloc(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
+        let expr_break = self.expr_break(span);
         self.arena.alloc(expr_break)
     }
 
     fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
-        self.expr(
-            span,
-            hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
-            AttrVec::new(),
-        )
+        self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e))
     }
 
     fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
-        self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new()))
+        self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[])))
     }
 
     fn expr_call_mut(
@@ -1783,7 +1771,7 @@ fn expr_call_mut(
         e: &'hir hir::Expr<'hir>,
         args: &'hir [hir::Expr<'hir>],
     ) -> hir::Expr<'hir> {
-        self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new())
+        self.expr(span, hir::ExprKind::Call(e, args))
     }
 
     fn expr_call(
@@ -1802,8 +1790,7 @@ fn expr_call_lang_item_fn_mut(
         args: &'hir [hir::Expr<'hir>],
         hir_id: Option<hir::HirId>,
     ) -> hir::Expr<'hir> {
-        let path =
-            self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
+        let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, hir_id));
         self.expr_call_mut(span, path, args)
     }
 
@@ -1821,13 +1808,11 @@ fn expr_lang_item_path(
         &mut self,
         span: Span,
         lang_item: hir::LangItem,
-        attrs: AttrVec,
         hir_id: Option<hir::HirId>,
     ) -> hir::Expr<'hir> {
         self.expr(
             span,
             hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
-            attrs,
         )
     }
 
@@ -1841,20 +1826,10 @@ pub(super) fn expr_ident(
     }
 
     pub(super) fn expr_ident_mut(
-        &mut self,
-        sp: Span,
-        ident: Ident,
-        binding: hir::HirId,
-    ) -> hir::Expr<'hir> {
-        self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new())
-    }
-
-    fn expr_ident_with_attrs(
         &mut self,
         span: Span,
         ident: Ident,
         binding: hir::HirId,
-        attrs: AttrVec,
     ) -> hir::Expr<'hir> {
         let hir_id = self.next_id();
         let res = Res::Local(binding);
@@ -1867,7 +1842,7 @@ fn expr_ident_with_attrs(
             }),
         ));
 
-        self.expr(span, expr_path, attrs)
+        self.expr(span, expr_path)
     }
 
     fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
@@ -1886,32 +1861,21 @@ fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
                 }),
                 None,
             ),
-            AttrVec::new(),
         )
     }
 
     fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
         let blk = self.block_all(span, &[], None);
-        let expr = self.expr_block(blk, AttrVec::new());
+        let expr = self.expr_block(blk);
         self.arena.alloc(expr)
     }
 
-    pub(super) fn expr_block(
-        &mut self,
-        b: &'hir hir::Block<'hir>,
-        attrs: AttrVec,
-    ) -> hir::Expr<'hir> {
-        self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
+    pub(super) fn expr_block(&mut self, b: &'hir hir::Block<'hir>) -> hir::Expr<'hir> {
+        self.expr(b.span, hir::ExprKind::Block(b, None))
     }
 
-    pub(super) fn expr(
-        &mut self,
-        span: Span,
-        kind: hir::ExprKind<'hir>,
-        attrs: AttrVec,
-    ) -> hir::Expr<'hir> {
+    pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> {
         let hir_id = self.next_id();
-        self.lower_attrs(hir_id, &attrs);
         hir::Expr { hir_id, kind, span: self.lower_span(span) }
     }