]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #105343 - nbdd0121:hir, r=fee1-dead
authorMatthias Krüger <matthias.krueger@famsik.de>
Wed, 7 Dec 2022 14:39:07 +0000 (15:39 +0100)
committerGitHub <noreply@github.com>
Wed, 7 Dec 2022 14:39:07 +0000 (15:39 +0100)
Simplify attribute handling in rustc_ast_lowering

Given that attributes is stored in a separate BTreeMap, it's not necessary to pass it in when constructing `hir::Expr`. We can just construct `hir::Expr` and then call `self.lower_attrs` later if it needs attributes.

As most desugaring code don't use attributes, this allows some code cleanup.

1  2 
compiler/rustc_ast_lowering/src/expr.rs

index 9974ebff311fb8c536f140880172ab7f95c4b07f,77b7ee38bde0447d1961c6e1091297ba8f612044..24e2985cf567a3838ee13e168d5d944c7078e6f5
@@@ -16,7 -16,7 +16,7 @@@ use rustc_hir::def::Res
  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;
  
@@@ -436,18 -436,14 +436,14 @@@ impl<'hir> LoweringContext<'_, 'hir> 
                  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)
              }
          }
      }
      ) -> 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);
          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))
      }
  
      ) -> 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`.
              .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());
          if track_caller {
 -            let unstable_span = self.mark_span_with_reason(
 -                DesugaringKind::Async,
 -                span,
 -                self.allow_gen_future.clone(),
 -            );
              self.lower_attrs(
                  hir_id,
                  &[Attribute {
          // 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])
      ///     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 => {}
          // unsafe {
          //     ::std::future::Future::poll(
          //         ::std::pin::Pin::new_unchecked(&mut __awaitee),
 -        //         ::std::future::get_context(task_context),
 +        //         task_context,
          //     )
          // }
          let poll_expr = {
                  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))
              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)
          };
              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
                      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
          });
          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
      }
          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])
      }
  
  
          // `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)
          };
          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)
          };
  
          // 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:
          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)
          };
                          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)
          &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(
          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(
          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(
          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)
      }
  
          &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,
          )
      }
  
      }
  
      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);
              }),
          ));
  
-         self.expr(span, expr_path, attrs)
+         self.expr(span, expr_path)
      }
  
      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) }
      }