diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index e93cddf57990..f604a66aebc0 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -125,14 +125,25 @@ macro_rules! arena_types { // HIR types [few] hir_forest: rustc::hir::map::Forest<$tcx>, + [] arm: rustc::hir::Arm<$tcx>, [] attribute: syntax::ast::Attribute, + [] block: rustc::hir::Block<$tcx>, [few] global_asm: rustc::hir::GlobalAsm, + [] expr: rustc::hir::Expr<$tcx>, + [] field: rustc::hir::Field<$tcx>, + [] field_pat: rustc::hir::FieldPat<$tcx>, [] fn_decl: rustc::hir::FnDecl, [] foreign_item: rustc::hir::ForeignItem<$tcx>, [] impl_item_ref: rustc::hir::ImplItemRef, + [] inline_asm: rustc::hir::InlineAsm<$tcx>, + [] local: rustc::hir::Local<$tcx>, [few] macro_def: rustc::hir::MacroDef<$tcx>, [] param: rustc::hir::Param<$tcx>, + [] pat: rustc::hir::Pat<$tcx>, [] path: rustc::hir::Path, + [] path_segment: rustc::hir::PathSegment, + [] qpath: rustc::hir::QPath, + [] stmt: rustc::hir::Stmt<$tcx>, [] struct_field: rustc::hir::StructField<$tcx>, [] trait_item_ref: rustc::hir::TraitItemRef, [] ty: rustc::hir::Ty, diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4bc41c444e62..cb9f08c76001 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -921,7 +921,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn with_new_scopes(&mut self, f: F) -> T where - F: FnOnce(&mut LoweringContext<'_, '_>) -> T, + F: FnOnce(&mut Self) -> T, { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; @@ -2031,21 +2031,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0); + let ty = l.ty.as_ref().map(|t| { + self.lower_ty( + t, + if self.sess.features_untracked().impl_trait_in_bindings { + ImplTraitContext::OpaqueTy(Some(parent_def_id)) + } else { + ImplTraitContext::Disallowed(ImplTraitPosition::Binding) + }, + ) + }); + let ty = ty.map(|ty| -> &'hir hir::Ty { self.arena.alloc(ty.into_inner()) }); + let init = l + .init + .as_ref() + .map(|e| -> &'hir hir::Expr<'hir> { self.arena.alloc(self.lower_expr(e)) }); ( hir::Local { hir_id: self.lower_node_id(l.id), - ty: l.ty.as_ref().map(|t| { - self.lower_ty( - t, - if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitContext::OpaqueTy(Some(parent_def_id)) - } else { - ImplTraitContext::Disallowed(ImplTraitPosition::Binding) - }, - ) - }), + ty, pat: self.lower_pat(&l.pat), - init: l.init.as_ref().map(|e| P(self.lower_expr(e))), + init, span: l.span, attrs: l.attrs.clone(), source: hir::LocalSource::Normal, @@ -2586,14 +2592,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect() } - fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P> { + fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> &'hir hir::Block<'hir> { + self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break)) + } + + fn lower_block_noalloc(&mut self, b: &Block, targeted_by_break: bool) -> hir::Block<'hir> { let mut stmts = vec![]; - let mut expr = None; + let mut expr: Option<&'hir _> = None; for (index, stmt) in b.stmts.iter().enumerate() { if index == b.stmts.len() - 1 { if let StmtKind::Expr(ref e) = stmt.kind { - expr = Some(P(self.lower_expr(e))); + expr = Some(self.arena.alloc(self.lower_expr(e))); } else { stmts.extend(self.lower_stmt(stmt)); } @@ -2602,14 +2612,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - P(hir::Block { + hir::Block { hir_id: self.lower_node_id(b.id), - stmts: stmts.into(), + stmts: self.arena.alloc_from_iter(stmts), expr, rules: self.lower_block_check_mode(&b.rules), span: b.span, targeted_by_break, - }) + } } /// Lowers a block directly to an expression, presuming that it @@ -2619,7 +2629,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.expr_block(block, AttrVec::new()) } - fn lower_pat(&mut self, p: &Pat) -> P> { + fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { let node = match p.kind { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, ident, ref sub) => { @@ -2627,7 +2637,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub); node } - PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))), + PatKind::Lit(ref e) => hir::PatKind::Lit(self.arena.alloc(self.lower_expr(e))), PatKind::TupleStruct(ref path, ref pats) => { let qpath = self.lower_qpath( p.id, @@ -2640,7 +2650,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::PatKind::TupleStruct(qpath, pats, ddpos) } PatKind::Or(ref pats) => { - hir::PatKind::Or(pats.iter().map(|x| self.lower_pat(x)).collect()) + hir::PatKind::Or(self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x)))) } PatKind::Path(ref qself, ref path) => { let qpath = self.lower_qpath( @@ -2661,16 +2671,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::disallowed(), ); - let fs = fields - .iter() - .map(|f| hir::FieldPat { - hir_id: self.next_id(), - ident: f.ident, - pat: self.lower_pat(&f.pat), - is_shorthand: f.is_shorthand, - span: f.span, - }) - .collect(); + let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat { + hir_id: self.next_id(), + ident: f.ident, + pat: self.lower_pat(&f.pat), + is_shorthand: f.is_shorthand, + span: f.span, + })); hir::PatKind::Struct(qpath, fs, etc) } PatKind::Tuple(ref pats) => { @@ -2680,8 +2687,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl), PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range( - P(self.lower_expr(e1)), - P(self.lower_expr(e2)), + self.arena.alloc(self.lower_expr(e1)), + self.arena.alloc(self.lower_expr(e2)), self.lower_range_end(end), ), PatKind::Slice(ref pats) => self.lower_pat_slice(pats), @@ -2700,7 +2707,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, pats: &[AstP], ctx: &str, - ) -> (HirVec>>, Option) { + ) -> (&'hir [&'hir hir::Pat<'hir>], Option) { let mut elems = Vec::with_capacity(pats.len()); let mut rest = None; @@ -2728,7 +2735,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - (elems.into(), rest.map(|(ddpos, _)| ddpos)) + (self.arena.alloc_from_iter(elems), rest.map(|(ddpos, _)| ddpos)) } /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into @@ -2788,7 +2795,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - hir::PatKind::Slice(before.into(), slice, after.into()) + hir::PatKind::Slice( + self.arena.alloc_from_iter(before), + slice, + self.arena.alloc_from_iter(after), + ) } fn lower_pat_ident( @@ -2796,7 +2807,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &Pat, binding_mode: &BindingMode, ident: Ident, - lower_sub: impl FnOnce(&mut Self) -> Option>>, + lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>, ) -> hir::PatKind<'hir> { match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) { // `None` can occur in body-less function signatures @@ -2824,13 +2835,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> P> { + fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { self.pat_with_node_id_of(p, hir::PatKind::Wild) } /// Construct a `Pat` with the `HirId` of `p.id` lowered. - fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> P> { - P(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span }) + fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { + self.arena.alloc(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span }) } /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. @@ -2883,7 +2894,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ids.push({ hir::Stmt { hir_id: self.lower_node_id(s.id), - kind: hir::StmtKind::Local(P(l)), + kind: hir::StmtKind::Local(self.arena.alloc(l)), span: s.span, } }); @@ -2905,8 +2916,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) .collect(); } - StmtKind::Expr(ref e) => hir::StmtKind::Expr(P(self.lower_expr(e))), - StmtKind::Semi(ref e) => hir::StmtKind::Semi(P(self.lower_expr(e))), + StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.arena.alloc(self.lower_expr(e))), + StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.arena.alloc(self.lower_expr(e))), StmtKind::Mac(..) => panic!("shouldn't exist here"), }; smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }] @@ -2949,30 +2960,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> { - self.stmt(span, hir::StmtKind::Expr(P(expr))) + self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr))) } fn stmt_let_pat( &mut self, attrs: AttrVec, span: Span, - init: Option>>, - pat: P>, + init: Option<&'hir hir::Expr<'hir>>, + pat: &'hir hir::Pat<'hir>, source: hir::LocalSource, ) -> hir::Stmt<'hir> { let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None }; - self.stmt(span, hir::StmtKind::Local(P(local))) + self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local))) } - fn block_expr(&mut self, expr: P>) -> hir::Block<'hir> { - self.block_all(expr.span, hir::HirVec::new(), Some(expr)) + fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Block<'hir> { + self.block_all(expr.span, &[], Some(expr)) } fn block_all( &mut self, span: Span, - stmts: hir::HirVec>, - expr: Option>>, + stmts: &'hir [hir::Stmt<'hir>], + expr: Option<&'hir hir::Expr<'hir>>, ) -> hir::Block<'hir> { hir::Block { stmts, @@ -2985,33 +2996,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } /// Constructs a `true` or `false` literal pattern. - fn pat_bool(&mut self, span: Span, val: bool) -> P> { + fn pat_bool(&mut self, span: Span, val: bool) -> &'hir hir::Pat<'hir> { let expr = self.expr_bool(span, val); - self.pat(span, hir::PatKind::Lit(P(expr))) + self.pat(span, hir::PatKind::Lit(self.arena.alloc(expr))) } - fn pat_ok(&mut self, span: Span, pat: P>) -> P> { - self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat]) + fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> { + self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], arena_vec![self; pat]) } - fn pat_err(&mut self, span: Span, pat: P>) -> P> { - self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat]) + fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> { + self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], arena_vec![self; pat]) } - fn pat_some(&mut self, span: Span, pat: P>) -> P> { - self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat]) + fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> { + self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], arena_vec![self; pat]) } - fn pat_none(&mut self, span: Span) -> P> { - self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![]) + fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> { + self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], &[]) } fn pat_std_enum( &mut self, span: Span, components: &[Symbol], - subpats: hir::HirVec>>, - ) -> P> { + subpats: &'hir [&'hir hir::Pat<'hir>], + ) -> &'hir hir::Pat<'hir> { let path = self.std_path(span, components, None, true); let qpath = hir::QPath::Resolved(None, P(path)); let pt = if subpats.is_empty() { @@ -3022,7 +3033,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.pat(span, pt) } - fn pat_ident(&mut self, span: Span, ident: Ident) -> (P>, hir::HirId) { + fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) { self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated) } @@ -3031,11 +3042,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, ident: Ident, bm: hir::BindingAnnotation, - ) -> (P>, hir::HirId) { + ) -> (&'hir hir::Pat<'hir>, hir::HirId) { let hir_id = self.next_id(); ( - P(hir::Pat { + self.arena.alloc(hir::Pat { hir_id, kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None), span, @@ -3044,12 +3055,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } - fn pat_wild(&mut self, span: Span) -> P> { + fn pat_wild(&mut self, span: Span) -> &'hir hir::Pat<'hir> { self.pat(span, hir::PatKind::Wild) } - fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> P> { - P(hir::Pat { hir_id: self.next_id(), kind, span }) + fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> { + self.arena.alloc(hir::Pat { hir_id: self.next_id(), kind, span }) } /// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs index 19a732a864a6..bc8a475e8a9d 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc/hir/lowering/expr.rs @@ -1,7 +1,7 @@ use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; +use crate::hir; use crate::hir::def::Res; use crate::hir::ptr::P; -use crate::hir::{self, HirVec}; use rustc_data_structures::thin_vec::ThinVec; @@ -14,26 +14,28 @@ use syntax::symbol::{sym, Symbol}; use rustc_error_codes::*; impl<'hir> LoweringContext<'_, 'hir> { - fn lower_exprs(&mut self, exprs: &[AstP]) -> HirVec> { - exprs.iter().map(|x| self.lower_expr(x)).collect() + fn lower_exprs(&mut self, exprs: &[AstP]) -> &'hir [hir::Expr<'hir>] { + self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr(x))) } pub(super) fn lower_expr(&mut self, e: &Expr) -> hir::Expr<'hir> { let kind = match e.kind { - ExprKind::Box(ref inner) => hir::ExprKind::Box(P(self.lower_expr(inner))), + ExprKind::Box(ref inner) => { + hir::ExprKind::Box(self.arena.alloc(self.lower_expr(inner))) + } ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), ExprKind::Repeat(ref expr, ref count) => { - let expr = P(self.lower_expr(expr)); + let expr = self.arena.alloc(self.lower_expr(expr)); let count = self.lower_anon_const(count); hir::ExprKind::Repeat(expr, count) } ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), ExprKind::Call(ref f, ref args) => { - let f = P(self.lower_expr(f)); + let f = self.arena.alloc(self.lower_expr(f)); hir::ExprKind::Call(f, self.lower_exprs(args)) } ExprKind::MethodCall(ref seg, ref args) => { - let hir_seg = P(self.lower_path_segment( + let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, ParamMode::Optional, @@ -47,26 +49,28 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Binary(binop, ref lhs, ref rhs) => { let binop = self.lower_binop(binop); - let lhs = P(self.lower_expr(lhs)); - let rhs = P(self.lower_expr(rhs)); + let lhs = self.arena.alloc(self.lower_expr(lhs)); + let rhs = self.arena.alloc(self.lower_expr(rhs)); hir::ExprKind::Binary(binop, lhs, rhs) } ExprKind::Unary(op, ref ohs) => { let op = self.lower_unop(op); - let ohs = P(self.lower_expr(ohs)); + let ohs = self.arena.alloc(self.lower_expr(ohs)); hir::ExprKind::Unary(op, ohs) } ExprKind::Lit(ref l) => hir::ExprKind::Lit(respan(l.span, l.kind.clone())), ExprKind::Cast(ref expr, ref ty) => { - let expr = P(self.lower_expr(expr)); - hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed())) + let expr = self.arena.alloc(self.lower_expr(expr)); + let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); + hir::ExprKind::Cast(expr, self.arena.alloc(ty.into_inner())) } ExprKind::Type(ref expr, ref ty) => { - let expr = P(self.lower_expr(expr)); - hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed())) + let expr = self.arena.alloc(self.lower_expr(expr)); + let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); + hir::ExprKind::Type(expr, self.arena.alloc(ty.into_inner())) } ExprKind::AddrOf(k, m, ref ohs) => { - let ohs = P(self.lower_expr(ohs)); + let ohs = self.arena.alloc(self.lower_expr(ohs)); hir::ExprKind::AddrOf(k, m, ohs) } ExprKind::Let(ref pat, ref scrutinee) => self.lower_expr_let(e.span, pat, scrutinee), @@ -85,8 +89,8 @@ impl<'hir> LoweringContext<'_, 'hir> { }), ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body), ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match( - P(self.lower_expr(expr)), - arms.iter().map(|x| self.lower_arm(x)).collect(), + self.arena.alloc(self.lower_expr(expr)), + self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), hir::MatchSource::Normal, ), ExprKind::Async(capture_clause, closure_node_id, ref block) => self.make_async_expr( @@ -122,18 +126,23 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_block(blk, opt_label.is_some()), self.lower_label(opt_label), ), - ExprKind::Assign(ref el, ref er, span) => { - hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)), span) - } + ExprKind::Assign(ref el, ref er, span) => hir::ExprKind::Assign( + self.arena.alloc(self.lower_expr(el)), + self.arena.alloc(self.lower_expr(er)), + span, + ), ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp( self.lower_binop(op), - P(self.lower_expr(el)), - P(self.lower_expr(er)), + self.arena.alloc(self.lower_expr(el)), + self.arena.alloc(self.lower_expr(er)), ), - ExprKind::Field(ref el, ident) => hir::ExprKind::Field(P(self.lower_expr(el)), ident), - ExprKind::Index(ref el, ref er) => { - hir::ExprKind::Index(P(self.lower_expr(el)), P(self.lower_expr(er))) + ExprKind::Field(ref el, ident) => { + hir::ExprKind::Field(self.arena.alloc(self.lower_expr(el)), ident) } + ExprKind::Index(ref el, ref er) => hir::ExprKind::Index( + self.arena.alloc(self.lower_expr(el)), + self.arena.alloc(self.lower_expr(er)), + ), ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => { self.lower_expr_range_closed(e.span, e1, e2) } @@ -150,26 +159,38 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ExprKind::Path(qpath) } - ExprKind::Break(opt_label, ref opt_expr) => hir::ExprKind::Break( - self.lower_jump_destination(e.id, opt_label), - opt_expr.as_ref().map(|x| P(self.lower_expr(x))), - ), + ExprKind::Break(opt_label, ref opt_expr) => { + let opt_expr = opt_expr + .as_ref() + .map(|x| -> &'hir hir::Expr<'hir> { self.arena.alloc(self.lower_expr(x)) }); + hir::ExprKind::Break(self.lower_jump_destination(e.id, opt_label), opt_expr) + } ExprKind::Continue(opt_label) => { hir::ExprKind::Continue(self.lower_jump_destination(e.id, opt_label)) } - ExprKind::Ret(ref e) => hir::ExprKind::Ret(e.as_ref().map(|x| P(self.lower_expr(x)))), + ExprKind::Ret(ref e) => { + let e = e + .as_ref() + .map(|x| -> &'hir hir::Expr<'hir> { self.arena.alloc(self.lower_expr(x)) }); + hir::ExprKind::Ret(e) + } ExprKind::InlineAsm(ref asm) => self.lower_expr_asm(asm), - ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprKind::Struct( - P(self.lower_qpath( - e.id, - &None, - path, - ParamMode::Optional, - ImplTraitContext::disallowed(), - )), - fields.iter().map(|x| self.lower_field(x)).collect(), - maybe_expr.as_ref().map(|x| P(self.lower_expr(x))), - ), + ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { + let maybe_expr = maybe_expr + .as_ref() + .map(|x| -> &'hir hir::Expr<'hir> { self.arena.alloc(self.lower_expr(x)) }); + hir::ExprKind::Struct( + self.arena.alloc(self.lower_qpath( + e.id, + &None, + path, + ParamMode::Optional, + ImplTraitContext::disallowed(), + )), + self.arena.alloc_from_iter(fields.iter().map(|x| self.lower_field(x))), + maybe_expr, + ) + } ExprKind::Paren(ref ex) => { let mut ex = self.lower_expr(ex); // Include parens in span, but only if it is a super-span. @@ -266,16 +287,16 @@ impl<'hir> LoweringContext<'_, 'hir> { let then_arm = { let pat = self.lower_pat(pat); let expr = self.expr_bool(span, true); - self.arm(pat, P(expr)) + self.arm(pat, self.arena.alloc(expr)) }; let else_arm = { let pat = self.pat_wild(span); let expr = self.expr_bool(span, false); - self.arm(pat, P(expr)) + self.arm(pat, self.arena.alloc(expr)) }; hir::ExprKind::Match( - P(scrutinee), - vec![then_arm, else_arm].into(), + self.arena.alloc(scrutinee), + arena_vec![self; then_arm, else_arm], hir::MatchSource::Normal, ) } @@ -295,7 +316,7 @@ impl<'hir> LoweringContext<'_, 'hir> { None => (self.expr_block_empty(span), false), Some(els) => (self.lower_expr(els), true), }; - let else_arm = self.arm(else_pat, P(else_expr)); + let else_arm = self.arm(else_pat, self.arena.alloc(else_expr)); // Handle then + scrutinee: let then_expr = self.lower_block_expr(then); @@ -315,14 +336,18 @@ impl<'hir> LoweringContext<'_, 'hir> { // Wrap in a construct equivalent to `{ let _t = $cond; _t }` // to preserve drop semantics since `if cond { ... }` does not // let temporaries live outside of `cond`. - let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); + let cond = self.expr_drop_temps(span_block, self.arena.alloc(cond), ThinVec::new()); let pat = self.pat_bool(span, true); (pat, cond, hir::MatchSource::IfDesugar { contains_else_clause }) } }; - let then_arm = self.arm(then_pat, P(then_expr)); + let then_arm = self.arm(then_pat, self.arena.alloc(then_expr)); - hir::ExprKind::Match(P(scrutinee), vec![then_arm, else_arm].into(), desugar) + hir::ExprKind::Match( + self.arena.alloc(scrutinee), + arena_vec![self; then_arm, else_arm], + desugar, + ) } fn lower_expr_while_in_loop_scope( @@ -379,20 +404,28 @@ impl<'hir> LoweringContext<'_, 'hir> { // Wrap in a construct equivalent to `{ let _t = $cond; _t }` // to preserve drop semantics since `while cond { ... }` does not // let temporaries live outside of `cond`. - let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new()); + let cond = self.expr_drop_temps(span_block, self.arena.alloc(cond), ThinVec::new()); // `true => `: let pat = self.pat_bool(span, true); (pat, cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While) } }; - let then_arm = self.arm(then_pat, P(then_expr)); + let then_arm = self.arm(then_pat, self.arena.alloc(then_expr)); // `match { ... }` - let match_expr = - self.expr_match(scrutinee.span, P(scrutinee), hir_vec![then_arm, else_arm], desugar); + let match_expr = self.expr_match( + scrutinee.span, + self.arena.alloc(scrutinee), + arena_vec![self; then_arm, else_arm], + desugar, + ); // `[opt_ident]: loop { ... }` - hir::ExprKind::Loop(P(self.block_expr(P(match_expr))), self.lower_label(opt_label), source) + hir::ExprKind::Loop( + self.arena.alloc(self.block_expr(self.arena.alloc(match_expr))), + self.lower_label(opt_label), + source, + ) } /// Desugar `try { ; }` into `{ ; ::std::ops::Try::from_ok() }`, @@ -400,7 +433,7 @@ impl<'hir> LoweringContext<'_, 'hir> { /// and save the block id to use it as a break target for desugaring of the `?` operator. fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> { self.with_catch_scope(body.id, |this| { - let mut block = this.lower_block(body, true).into_inner(); + let mut block = this.lower_block_noalloc(body, true); let try_span = this.mark_span_with_reason( DesugaringKind::TryBlock, @@ -410,8 +443,10 @@ impl<'hir> LoweringContext<'_, 'hir> { // Final expression of the block (if present) or `()` with span at the end of block let tail_expr = block.expr.take().map_or_else( - || this.expr_unit(this.sess.source_map().end_point(try_span)), - |x: P>| x.into_inner(), + || -> &'hir hir::Expr<'hir> { + this.arena.alloc(this.expr_unit(this.sess.source_map().end_point(try_span))) + }, + |x: &'hir hir::Expr<'hir>| x, ); let ok_wrapped_span = @@ -425,7 +460,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ok_wrapped_span, )); - hir::ExprKind::Block(P(block), None) + hir::ExprKind::Block(this.arena.alloc(block), None) }) } @@ -433,24 +468,25 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, method: Symbol, method_span: Span, - expr: hir::Expr<'hir>, + expr: &'hir hir::Expr<'hir>, overall_span: Span, - ) -> P> { + ) -> &'hir hir::Expr<'hir> { let path = &[sym::ops, sym::Try, method]; - let constructor = P(self.expr_std_path(method_span, path, None, ThinVec::new())); - P(self.expr_call(overall_span, constructor, hir_vec![expr])) + let constructor = + self.arena.alloc(self.expr_std_path(method_span, path, None, ThinVec::new())); + self.arena.alloc(self.expr_call(overall_span, constructor, std::slice::from_ref(expr))) } fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { hir::Arm { hir_id: self.next_id(), - attrs: self.lower_attrs(&arm.attrs), + attrs: self.lower_attrs_arena(&arm.attrs), pat: self.lower_pat(&arm.pat), guard: match arm.guard { - Some(ref x) => Some(hir::Guard::If(P(self.lower_expr(x)))), + Some(ref x) => Some(hir::Guard::If(self.arena.alloc(self.lower_expr(x)))), _ => None, }, - body: P(self.lower_expr(&arm.body)), + body: self.arena.alloc(self.lower_expr(&arm.body)), span: arm.span, } } @@ -469,7 +505,9 @@ impl<'hir> LoweringContext<'_, 'hir> { None => FunctionRetTy::Default(span), }; let ast_decl = FnDecl { inputs: vec![], output }; - let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None); + let decl = self.arena.alloc( + self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None).into_inner(), + ); let body_id = self.lower_fn_body(&ast_decl, |this| { this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind)); body(this) @@ -501,7 +539,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); // `future::from_generator(generator)`: - hir::ExprKind::Call(P(gen_future), hir_vec![generator]) + hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator]) } /// Desugar `.await` into: @@ -550,7 +588,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // ::std::pin::Pin::new_unchecked(&mut pinned) // })` let poll_expr = { - let pinned = P(self.expr_ident(span, pinned_ident, pinned_pat_hid)); + let pinned = self.arena.alloc(self.expr_ident(span, pinned_ident, pinned_pat_hid)); let ref_mut_pinned = self.expr_mut_addr_of(span, pinned); let pin_ty_id = self.next_id(); let new_unchecked_expr_kind = self.expr_call_std_assoc_fn( @@ -558,14 +596,15 @@ impl<'hir> LoweringContext<'_, 'hir> { span, &[sym::pin, sym::Pin], "new_unchecked", - hir_vec![ref_mut_pinned], + arena_vec![self; ref_mut_pinned], ); - let new_unchecked = P(self.expr(span, new_unchecked_expr_kind, ThinVec::new())); + let new_unchecked = + self.arena.alloc(self.expr(span, new_unchecked_expr_kind, ThinVec::new())); let unsafe_expr = self.expr_unsafe(new_unchecked); - P(self.expr_call_std_path( + self.arena.alloc(self.expr_call_std_path( gen_future_span, &[sym::future, sym::poll_with_tls_context], - hir_vec![unsafe_expr], + arena_vec![self; unsafe_expr], )) }; @@ -575,22 +614,24 @@ impl<'hir> LoweringContext<'_, 'hir> { let ready_arm = { let x_ident = Ident::with_dummy_span(sym::result); let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident); - let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid)); - let ready_pat = - self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Ready], hir_vec![x_pat]); - let break_x = self.with_loop_scope(loop_node_id, |this| { + let x_expr = self.arena.alloc(self.expr_ident(span, x_ident, x_pat_hid)); + let ready_pat = self.pat_std_enum( + span, + &[sym::task, sym::Poll, sym::Ready], + arena_vec![self; x_pat], + ); + 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)); - P(this.expr(await_span, expr_break, ThinVec::new())) + this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new())) }); self.arm(ready_pat, break_x) }; // `::std::task::Poll::Pending => {}` let pending_arm = { - let pending_pat = - self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Pending], hir_vec![]); - let empty_block = P(self.expr_block_empty(span)); + let pending_pat = self.pat_std_enum(span, &[sym::task, sym::Poll, sym::Pending], &[]); + let empty_block = self.arena.alloc(self.expr_block_empty(span)); self.arm(pending_pat, empty_block) }; @@ -598,7 +639,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let match_expr = self.expr_match( span, poll_expr, - hir_vec![ready_arm, pending_arm], + arena_vec![self; ready_arm, pending_arm], hir::MatchSource::AwaitDesugar, ); self.stmt_expr(span, match_expr) @@ -608,16 +649,20 @@ impl<'hir> LoweringContext<'_, 'hir> { let unit = self.expr_unit(span); let yield_expr = self.expr( span, - hir::ExprKind::Yield(P(unit), hir::YieldSource::Await), + hir::ExprKind::Yield(self.arena.alloc(unit), hir::YieldSource::Await), ThinVec::new(), ); self.stmt_expr(span, yield_expr) }; - let loop_block = P(self.block_all(span, hir_vec![inner_match_stmt, yield_stmt], None)); + let loop_block = self.arena.alloc(self.block_all( + span, + arena_vec![self; inner_match_stmt, yield_stmt], + None, + )); // loop { .. } - let loop_expr = P(hir::Expr { + let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop), span, @@ -630,8 +675,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // match { // mut pinned => loop { .. } // } - let expr = P(self.lower_expr(expr)); - hir::ExprKind::Match(expr, hir_vec![pinned_arm], hir::MatchSource::AwaitDesugar) + let expr = self.arena.alloc(self.lower_expr(expr)); + hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar) } fn lower_expr_closure( @@ -644,8 +689,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ExprKind<'hir> { // Lower outside new scope to preserve `is_in_loop_condition`. let fn_decl = self.lower_fn_decl(decl, None, false, None); + let fn_decl = self.arena.alloc(fn_decl.into_inner()); - self.with_new_scopes(|this| { + self.with_new_scopes(move |this| { let prev = this.current_item; this.current_item = Some(fn_decl_span); let mut generator_kind = None; @@ -706,8 +752,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // have to conserve the state of being inside a loop condition for the // closure argument types. let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None); + let fn_decl = self.arena.alloc(fn_decl.into_inner()); - self.with_new_scopes(|this| { + self.with_new_scopes(move |this| { // FIXME(cramertj): allow `async` non-`move` closures with arguments. if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() { struct_span_err!( @@ -752,7 +799,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span, &[sym::ops, sym::RangeInclusive], "new", - hir_vec![e1, e2], + arena_vec![self; e1, e2], ) } @@ -777,16 +824,13 @@ impl<'hir> LoweringContext<'_, 'hir> { } }; - let fields = e1 - .iter() - .map(|e| ("start", e)) - .chain(e2.iter().map(|e| ("end", e))) - .map(|(s, e)| { - let expr = P(self.lower_expr(&e)); + let fields = self.arena.alloc_from_iter( + e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e))).map(|(s, e)| { + let expr = self.arena.alloc(self.lower_expr(&e)); let ident = Ident::new(Symbol::intern(s), e.span); self.field(ident, expr, e.span) - }) - .collect::]>>(); + }), + ); let is_unit = fields.is_empty(); let struct_path = [sym::ops, path]; @@ -796,7 +840,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if is_unit { hir::ExprKind::Path(struct_path) } else { - hir::ExprKind::Struct(P(struct_path), fields, None) + hir::ExprKind::Struct(self.arena.alloc(struct_path), fields, None) } } @@ -837,7 +881,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn with_catch_scope(&mut self, catch_id: NodeId, f: F) -> T where - F: FnOnce(&mut LoweringContext<'_, '_>) -> T, + F: FnOnce(&mut Self) -> T, { let len = self.catch_scopes.len(); self.catch_scopes.push(catch_id); @@ -856,7 +900,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn with_loop_scope(&mut self, loop_id: NodeId, f: F) -> T where - F: FnOnce(&mut LoweringContext<'_, '_>) -> T, + F: FnOnce(&mut Self) -> T, { // We're no longer in the base loop's condition; we're in another loop. let was_in_loop_condition = self.is_in_loop_condition; @@ -881,7 +925,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn with_loop_condition_scope(&mut self, f: F) -> T where - F: FnOnce(&mut LoweringContext<'_, '_>) -> T, + F: FnOnce(&mut Self) -> T, { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = true; @@ -915,17 +959,21 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let hir_asm = hir::InlineAsm { inner, - inputs_exprs: asm.inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect(), - outputs_exprs: asm.outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(), + inputs_exprs: self + .arena + .alloc_from_iter(asm.inputs.iter().map(|&(_, ref input)| self.lower_expr(input))), + outputs_exprs: self + .arena + .alloc_from_iter(asm.outputs.iter().map(|out| self.lower_expr(&out.expr))), }; - hir::ExprKind::InlineAsm(P(hir_asm)) + hir::ExprKind::InlineAsm(self.arena.alloc(hir_asm)) } fn lower_field(&mut self, f: &Field) -> hir::Field<'hir> { hir::Field { hir_id: self.next_id(), ident: f.ident, - expr: P(self.lower_expr(&f.expr)), + expr: self.arena.alloc(self.lower_expr(&f.expr)), span: f.span, is_shorthand: f.is_shorthand, } @@ -944,7 +992,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let expr = opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span)); - hir::ExprKind::Yield(P(expr), hir::YieldSource::Yield) + hir::ExprKind::Yield(self.arena.alloc(expr), hir::YieldSource::Yield) } /// Desugar `ExprForLoop` from: `[opt_ident]: for in ` into: @@ -992,9 +1040,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let pat_arm = { let val_ident = Ident::with_dummy_span(sym::val); let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident); - let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid)); - let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid)); - let assign = P(self.expr( + let val_expr = self.arena.alloc(self.expr_ident(pat.span, val_ident, val_pat_hid)); + let next_expr = self.arena.alloc(self.expr_ident(pat.span, next_ident, next_pat_hid)); + let assign = self.arena.alloc(self.expr( pat.span, hir::ExprKind::Assign(next_expr, val_expr, pat.span), ThinVec::new(), @@ -1017,18 +1065,21 @@ impl<'hir> LoweringContext<'_, 'hir> { // `match ::std::iter::Iterator::next(&mut iter) { ... }` let match_expr = { - let iter = P(self.expr_ident(desugared_span, iter, iter_pat_nid)); + let iter = self.arena.alloc(self.expr_ident(desugared_span, iter, iter_pat_nid)); let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter); let next_path = &[sym::iter, sym::Iterator, sym::next]; - let next_expr = - P(self.expr_call_std_path(desugared_span, next_path, hir_vec![ref_mut_iter])); - let arms = hir_vec![pat_arm, break_arm]; + let next_expr = self.arena.alloc(self.expr_call_std_path( + desugared_span, + next_path, + arena_vec![self; ref_mut_iter], + )); + let arms = arena_vec![self; pat_arm, break_arm]; self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar) }; let match_stmt = self.stmt_expr(desugared_span, match_expr); - let next_expr = P(self.expr_ident(desugared_span, next_ident, next_pat_hid)); + let next_expr = self.arena.alloc(self.expr_ident(desugared_span, next_ident, next_pat_hid)); // `let mut __next` let next_let = self.stmt_let_pat( @@ -1053,13 +1104,16 @@ impl<'hir> LoweringContext<'_, 'hir> { let body_expr = self.expr_block(body_block, ThinVec::new()); let body_stmt = self.stmt_expr(body.span, body_expr); - let loop_block = - P(self.block_all(e.span, hir_vec![next_let, match_stmt, pat_let, body_stmt], None)); + let loop_block = self.arena.alloc(self.block_all( + e.span, + arena_vec![self; next_let, match_stmt, pat_let, body_stmt], + None, + )); // `[opt_ident]: loop { ... }` let kind = hir::ExprKind::Loop(loop_block, self.lower_label(opt_label), hir::LoopSource::ForLoop); - let loop_expr = P(hir::Expr { + let loop_expr = self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span, @@ -1072,13 +1126,17 @@ impl<'hir> LoweringContext<'_, 'hir> { // `match ::std::iter::IntoIterator::into_iter() { ... }` let into_iter_expr = { let into_iter_path = &[sym::iter, sym::IntoIterator, sym::into_iter]; - P(self.expr_call_std_path(desugared_span, into_iter_path, hir_vec![head])) + self.arena.alloc(self.expr_call_std_path( + desugared_span, + into_iter_path, + arena_vec![self; head], + )) }; - let match_expr = P(self.expr_match( + let match_expr = self.arena.alloc(self.expr_match( desugared_span, into_iter_expr, - hir_vec![iter_arm], + arena_vec![self; iter_arm], hir::MatchSource::ForLoopDesugar, )); @@ -1121,7 +1179,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let sub_expr = self.lower_expr(sub_expr); let path = &[sym::ops, sym::Try, sym::into_result]; - P(self.expr_call_std_path(unstable_span, path, hir_vec![sub_expr])) + self.arena.alloc(self.expr_call_std_path( + unstable_span, + path, + arena_vec![self; sub_expr], + )) }; // `#[allow(unreachable_code)]` @@ -1141,7 +1203,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ok_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 = P(self.expr_ident_with_attrs( + let val_expr = self.arena.alloc(self.expr_ident_with_attrs( span, val_ident, val_pat_nid, @@ -1159,7 +1221,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let from_expr = { let from_path = &[sym::convert, sym::From, sym::from]; let err_expr = self.expr_ident(try_span, err_ident, err_local_nid); - self.expr_call_std_path(try_span, from_path, hir_vec![err_expr]) + self.arena.alloc(self.expr_call_std_path( + try_span, + from_path, + arena_vec![self; err_expr], + )) }; let from_err_expr = self.wrap_in_try_constructor(sym::from_error, unstable_span, from_expr, try_span); @@ -1167,7 +1233,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let catch_scope = self.catch_scopes.last().map(|x| *x); let ret_expr = if let Some(catch_node) = catch_scope { let target_id = Ok(self.lower_node_id(catch_node)); - P(self.expr( + self.arena.alloc(self.expr( try_span, hir::ExprKind::Break( hir::Destination { label: None, target_id }, @@ -1176,14 +1242,22 @@ impl<'hir> LoweringContext<'_, 'hir> { thin_attrs, )) } else { - P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs)) + self.arena.alloc(self.expr( + try_span, + hir::ExprKind::Ret(Some(from_err_expr)), + thin_attrs, + )) }; let err_pat = self.pat_err(try_span, err_local); self.arm(err_pat, ret_expr) }; - hir::ExprKind::Match(scrutinee, hir_vec![err_arm, ok_arm], hir::MatchSource::TryDesugar) + hir::ExprKind::Match( + scrutinee, + arena_vec![self; err_arm, ok_arm], + hir::MatchSource::TryDesugar, + ) } // ========================================================================= @@ -1205,7 +1279,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn expr_drop_temps( &mut self, span: Span, - expr: P>, + expr: &'hir hir::Expr<'hir>, attrs: AttrVec, ) -> hir::Expr<'hir> { self.expr(span, hir::ExprKind::DropTemps(expr), attrs) @@ -1214,19 +1288,19 @@ impl<'hir> LoweringContext<'_, 'hir> { fn expr_match( &mut self, span: Span, - arg: P>, - arms: hir::HirVec>, + arg: &'hir hir::Expr<'hir>, + arms: &'hir [hir::Arm<'hir>], source: hir::MatchSource, ) -> hir::Expr<'hir> { self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new()) } - fn expr_break(&mut self, span: Span, attrs: AttrVec) -> P> { + fn expr_break(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> { let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None); - P(self.expr(span, expr_break, attrs)) + self.arena.alloc(self.expr(span, expr_break, attrs)) } - fn expr_mut_addr_of(&mut self, span: Span, e: P>) -> hir::Expr<'_> { + 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), @@ -1235,18 +1309,18 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn expr_unit(&mut self, sp: Span) -> hir::Expr<'hir> { - self.expr_tuple(sp, hir_vec![]) + self.expr_tuple(sp, &[]) } - fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec>) -> hir::Expr<'hir> { + fn expr_tuple(&mut self, sp: Span, exprs: &'hir [hir::Expr<'hir>]) -> hir::Expr<'hir> { self.expr(sp, hir::ExprKind::Tup(exprs), ThinVec::new()) } fn expr_call( &mut self, span: Span, - e: P>, - args: hir::HirVec>, + e: &'hir hir::Expr<'hir>, + args: &'hir [hir::Expr<'hir>], ) -> hir::Expr<'hir> { self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()) } @@ -1256,9 +1330,10 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, path_components: &[Symbol], - args: hir::HirVec>, + args: &'hir [hir::Expr<'hir>], ) -> hir::Expr<'hir> { - let path = P(self.expr_std_path(span, path_components, None, ThinVec::new())); + let path = + self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new())); self.expr_call(span, path, args) } @@ -1277,13 +1352,14 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, ty_path_components: &[Symbol], assoc_fn_name: &str, - args: hir::HirVec>, + args: &'hir [hir::Expr<'hir>], ) -> hir::ExprKind<'hir> { let ty_path = P(self.std_path(span, ty_path_components, None, false)); let ty = P(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path))); let fn_seg = P(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name))); let fn_path = hir::QPath::TypeRelative(ty, fn_seg); - let fn_expr = P(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new())); + let fn_expr = + self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new())); hir::ExprKind::Call(fn_expr, args) } @@ -1326,14 +1402,14 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, expr_path, attrs) } - fn expr_unsafe(&mut self, expr: P>) -> hir::Expr<'hir> { + fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> { let hir_id = self.next_id(); let span = expr.span; self.expr( span, hir::ExprKind::Block( - P(hir::Block { - stmts: hir_vec![], + self.arena.alloc(hir::Block { + stmts: &[], expr: Some(expr), hir_id, rules: hir::UnsafeBlock(hir::CompilerGenerated), @@ -1347,11 +1423,15 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn expr_block_empty(&mut self, span: Span) -> hir::Expr<'hir> { - let blk = self.block_all(span, hir_vec![], None); - self.expr_block(P(blk), ThinVec::new()) + let blk = self.block_all(span, &[], None); + self.expr_block(self.arena.alloc(blk), ThinVec::new()) } - pub(super) fn expr_block(&mut self, b: P>, attrs: AttrVec) -> hir::Expr<'hir> { + 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) } @@ -1364,14 +1444,14 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::Expr { hir_id: self.next_id(), kind, span, attrs } } - fn field(&mut self, ident: Ident, expr: P>, span: Span) -> hir::Field<'hir> { + fn field(&mut self, ident: Ident, expr: &'hir hir::Expr<'hir>, span: Span) -> hir::Field<'hir> { hir::Field { hir_id: self.next_id(), ident, span, expr, is_shorthand: false } } - fn arm(&mut self, pat: P>, expr: P>) -> hir::Arm<'hir> { + fn arm(&mut self, pat: &'hir hir::Pat<'hir>, expr: &'hir hir::Expr<'hir>) -> hir::Arm<'hir> { hir::Arm { hir_id: self.next_id(), - attrs: hir_vec![], + attrs: &[], pat, guard: None, span: expr.span, diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs index 8016ab5c592c..19ef106b9bd8 100644 --- a/src/librustc/hir/lowering/item.rs +++ b/src/librustc/hir/lowering/item.rs @@ -1005,7 +1005,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> { hir::Param { - attrs: self.lower_attrs(¶m.attrs), + attrs: self.lower_attrs_arena(¶m.attrs), hir_id: self.lower_node_id(param.id), pat: self.lower_pat(¶m.pat), span: param.span, @@ -1066,8 +1066,8 @@ impl<'hir> LoweringContext<'_, 'hir> { }; self.lower_body(|this| { - let mut parameters: Vec> = Vec::new(); - let mut statements: Vec> = Vec::new(); + let mut parameters: Vec> = Vec::new(); + let mut statements: Vec> = Vec::new(); // Async function parameters are lowered into the closure body so that they are // captured and so that the drop order matches the equivalent non-async functions. @@ -1145,7 +1145,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let stmt = this.stmt_let_pat( stmt_attrs, desugared_span, - Some(P(expr)), + Some(this.arena.alloc(expr)), parameter.pat, hir::LocalSource::AsyncFn, ); @@ -1175,7 +1175,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let move_stmt = this.stmt_let_pat( AttrVec::new(), desugared_span, - Some(P(move_expr)), + Some(this.arena.alloc(move_expr)), move_pat, hir::LocalSource::AsyncFn, ); @@ -1186,7 +1186,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let pattern_stmt = this.stmt_let_pat( stmt_attrs, desugared_span, - Some(P(pattern_expr)), + Some(this.arena.alloc(pattern_expr)), parameter.pat, hir::LocalSource::AsyncFn, ); @@ -1212,8 +1212,11 @@ impl<'hir> LoweringContext<'_, 'hir> { // Transform into `drop-temps { }`, an expression: let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None); - let user_body = - this.expr_drop_temps(desugared_span, P(user_body), AttrVec::new()); + let user_body = this.expr_drop_temps( + desugared_span, + this.arena.alloc(user_body), + AttrVec::new(), + ); // As noted above, create the final block like // @@ -1224,9 +1227,13 @@ impl<'hir> LoweringContext<'_, 'hir> { // drop-temps { } // } // ``` - let body = - this.block_all(desugared_span, statements.into(), Some(P(user_body))); - this.expr_block(P(body), AttrVec::new()) + let body = this.block_all( + desugared_span, + this.arena.alloc_from_iter(statements), + Some(this.arena.alloc(user_body)), + ); + + this.expr_block(this.arena.alloc(body), AttrVec::new()) }, ); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 8a450cf167a3..003917ee1e1b 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -50,6 +50,15 @@ macro_rules! hir_vec { ); } +macro_rules! arena_vec { + () => ( + &[] + ); + ($this:expr; $($x:expr),*) => ( + $this.arena.alloc_from_iter(vec![$($x),*]) + ); +} + pub mod check_attr; pub mod def; pub mod def_id;