diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 3d5bd313f8838..f604a66aebc01 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, + [] 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/check_attr.rs b/src/librustc/hir/check_attr.rs index 5918ff03d585d..511244ca516f5 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -458,7 +458,7 @@ impl CheckAttrVisitor<'tcx> { .emit(); } - fn check_stmt_attributes(&self, stmt: &hir::Stmt) { + fn check_stmt_attributes(&self, stmt: &hir::Stmt<'_>) { // When checking statements ignore expressions, they will be checked later if let hir::StmtKind::Local(ref l) = stmt.kind { for attr in l.attrs.iter() { @@ -477,7 +477,7 @@ impl CheckAttrVisitor<'tcx> { } } - fn check_expr_attributes(&self, expr: &hir::Expr) { + fn check_expr_attributes(&self, expr: &hir::Expr<'_>) { let target = match expr.kind { hir::ExprKind::Closure(..) => Target::Closure, _ => Target::Expression, @@ -537,12 +537,12 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { intravisit::walk_impl_item(self, impl_item) } - fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) { + fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { self.check_stmt_attributes(stmt); intravisit::walk_stmt(self, stmt) } - fn visit_expr(&mut self, expr: &'tcx hir::Expr) { + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { self.check_expr_attributes(expr); intravisit::walk_expr(self, expr) } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index a7a8673d49eb1..659bfc4e63c6b 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -212,7 +212,7 @@ pub trait Visitor<'v>: Sized { } } - fn visit_param(&mut self, param: &'v Param) { + fn visit_param(&mut self, param: &'v Param<'v>) { walk_param(self, param) } @@ -253,25 +253,25 @@ pub trait Visitor<'v>: Sized { fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) { walk_foreign_item(self, i) } - fn visit_local(&mut self, l: &'v Local) { + fn visit_local(&mut self, l: &'v Local<'v>) { walk_local(self, l) } - fn visit_block(&mut self, b: &'v Block) { + fn visit_block(&mut self, b: &'v Block<'v>) { walk_block(self, b) } - fn visit_stmt(&mut self, s: &'v Stmt) { + fn visit_stmt(&mut self, s: &'v Stmt<'v>) { walk_stmt(self, s) } - fn visit_arm(&mut self, a: &'v Arm) { + fn visit_arm(&mut self, a: &'v Arm<'v>) { walk_arm(self, a) } - fn visit_pat(&mut self, p: &'v Pat) { + fn visit_pat(&mut self, p: &'v Pat<'v>) { walk_pat(self, p) } fn visit_anon_const(&mut self, c: &'v AnonConst) { walk_anon_const(self, c) } - fn visit_expr(&mut self, ex: &'v Expr) { + fn visit_expr(&mut self, ex: &'v Expr<'v>) { walk_expr(self, ex) } fn visit_ty(&mut self, t: &'v Ty) { @@ -409,7 +409,7 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) { visitor.visit_expr(&body.value); } -pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { +pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) { // Intentionally visiting the expr first - the initialization expr // dominates the local's definition. walk_list!(visitor, visit_expr, &local.init); @@ -462,10 +462,10 @@ where visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id) } -pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param) { +pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) { visitor.visit_id(param.hir_id); visitor.visit_pat(¶m.pat); - walk_list!(visitor, visit_attribute, ¶m.attrs); + walk_list!(visitor, visit_attribute, param.attrs); } pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { @@ -684,17 +684,17 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, type_binding } } -pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { +pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) { visitor.visit_id(pattern.hir_id); match pattern.kind { - PatKind::TupleStruct(ref qpath, ref children, _) => { + PatKind::TupleStruct(ref qpath, children, _) => { visitor.visit_qpath(qpath, pattern.hir_id, pattern.span); walk_list!(visitor, visit_pat, children); } PatKind::Path(ref qpath) => { visitor.visit_qpath(qpath, pattern.hir_id, pattern.span); } - PatKind::Struct(ref qpath, ref fields, _) => { + PatKind::Struct(ref qpath, fields, _) => { visitor.visit_qpath(qpath, pattern.hir_id, pattern.span); for field in fields { visitor.visit_id(field.hir_id); @@ -702,8 +702,8 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { visitor.visit_pat(&field.pat) } } - PatKind::Or(ref pats) => walk_list!(visitor, visit_pat, pats), - PatKind::Tuple(ref tuple_elements, _) => { + PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats), + PatKind::Tuple(tuple_elements, _) => { walk_list!(visitor, visit_pat, tuple_elements); } PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) => { @@ -719,7 +719,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { visitor.visit_expr(upper_bound) } PatKind::Wild => (), - PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => { + PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => { walk_list!(visitor, visit_pat, prepatterns); walk_list!(visitor, visit_pat, slice_pattern); walk_list!(visitor, visit_pat, postpatterns); @@ -955,13 +955,13 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v walk_list!(visitor, visit_attribute, struct_field.attrs); } -pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { +pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) { visitor.visit_id(block.hir_id); - walk_list!(visitor, visit_stmt, &block.stmts); + walk_list!(visitor, visit_stmt, block.stmts); walk_list!(visitor, visit_expr, &block.expr); } -pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { +pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) { visitor.visit_id(statement.hir_id); match statement.kind { StmtKind::Local(ref local) => visitor.visit_local(local), @@ -977,19 +977,19 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo visitor.visit_nested_body(constant.body); } -pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { +pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) { visitor.visit_id(expression.hir_id); walk_list!(visitor, visit_attribute, expression.attrs.iter()); match expression.kind { ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::Array(ref subexpressions) => { + ExprKind::Array(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } ExprKind::Repeat(ref element, ref count) => { visitor.visit_expr(element); visitor.visit_anon_const(count) } - ExprKind::Struct(ref qpath, ref fields, ref optional_base) => { + ExprKind::Struct(ref qpath, fields, ref optional_base) => { visitor.visit_qpath(qpath, expression.hir_id, expression.span); for field in fields { visitor.visit_id(field.hir_id); @@ -998,14 +998,14 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { } walk_list!(visitor, visit_expr, optional_base); } - ExprKind::Tup(ref subexpressions) => { + ExprKind::Tup(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprKind::Call(ref callee_expression, ref arguments) => { + ExprKind::Call(ref callee_expression, arguments) => { visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); } - ExprKind::MethodCall(ref segment, _, ref arguments) => { + ExprKind::MethodCall(ref segment, _, arguments) => { visitor.visit_path_segment(expression.span, segment); walk_list!(visitor, visit_expr, arguments); } @@ -1027,7 +1027,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); } - ExprKind::Match(ref subexpression, ref arms, _) => { + ExprKind::Match(ref subexpression, arms, _) => { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } @@ -1077,8 +1077,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { walk_list!(visitor, visit_expr, optional_expression); } ExprKind::InlineAsm(ref asm) => { - walk_list!(visitor, visit_expr, &asm.outputs_exprs); - walk_list!(visitor, visit_expr, &asm.inputs_exprs); + walk_list!(visitor, visit_expr, asm.outputs_exprs); + walk_list!(visitor, visit_expr, asm.inputs_exprs); } ExprKind::Yield(ref subexpression, _) => { visitor.visit_expr(subexpression); @@ -1087,7 +1087,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { } } -pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { +pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) { visitor.visit_id(arm.hir_id); visitor.visit_pat(&arm.pat); if let Some(ref g) = arm.guard { @@ -1096,7 +1096,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { } } visitor.visit_expr(&arm.body); - walk_list!(visitor, visit_attribute, &arm.attrs); + walk_list!(visitor, visit_attribute, arm.attrs); } pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f6db451d57ead..ed84bd118f725 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -32,9 +32,6 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. -mod expr; -mod item; - use crate::arena::Arena; use crate::dep_graph::DepGraph; use crate::hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; @@ -76,6 +73,18 @@ use syntax_pos::Span; use rustc_error_codes::*; +macro_rules! arena_vec { + () => ( + &[] + ); + ($this:expr; $($x:expr),*) => ( + $this.arena.alloc_from_iter(vec![$($x),*]) + ); +} + +mod expr; +mod item; + const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; pub struct LoweringContext<'a, 'hir: 'a> { @@ -921,7 +930,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; @@ -2022,7 +2031,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) { + fn lower_local(&mut self, l: &Local) -> (hir::Local<'hir>, SmallVec<[NodeId; 1]>) { let mut ids = SmallVec::<[NodeId; 1]>::new(); if self.sess.features_untracked().impl_trait_in_bindings { if let Some(ref ty) = l.ty { @@ -2031,21 +2040,24 @@ 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| &*self.arena.alloc(ty.into_inner())); + let init = l.init.as_ref().map(|e| 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 +2598,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.lower_expr(e)); } else { stmts.extend(self.lower_stmt(stmt)); } @@ -2602,24 +2618,24 @@ 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 /// has no attributes and is not targeted by a `break`. - fn lower_block_expr(&mut self, b: &Block) -> hir::Expr { + fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> { let block = self.lower_block(b, false); 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 +2643,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.lower_expr(e)), PatKind::TupleStruct(ref path, ref pats) => { let qpath = self.lower_qpath( p.id, @@ -2640,7 +2656,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 +2677,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 +2693,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.lower_expr(e1), + self.lower_expr(e2), self.lower_range_end(end), ), PatKind::Slice(ref pats) => self.lower_pat_slice(pats), @@ -2700,7 +2713,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 +2741,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 @@ -2737,7 +2750,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// When encountering `($binding_mode $ident @)? ..` (`slice`), /// this is interpreted as a sub-slice pattern semantically. /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`. - fn lower_pat_slice(&mut self, pats: &[AstP]) -> hir::PatKind { + fn lower_pat_slice(&mut self, pats: &[AstP]) -> hir::PatKind<'hir> { let mut before = Vec::new(); let mut after = Vec::new(); let mut slice = None; @@ -2788,7 +2801,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,8 +2813,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &Pat, binding_mode: &BindingMode, ident: Ident, - lower_sub: impl FnOnce(&mut Self) -> Option>, - ) -> hir::PatKind { + 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 res @ None | res @ Some(Res::Local(_)) => { @@ -2824,13 +2841,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) -> 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. @@ -2843,7 +2860,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } /// Used to ban the `..` pattern in places it shouldn't be semantically. - fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind { + fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> { self.diagnostic() .struct_span_err(sp, "`..` patterns are not allowed here") .note("only allowed in tuple, tuple struct, and slice patterns") @@ -2869,11 +2886,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt; 1]> { + fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> { let kind = match s.kind { StmtKind::Local(ref l) => { let (l, item_ids) = self.lower_local(l); - let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids + let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids .into_iter() .map(|item_id| { let item_id = hir::ItemId { id: self.lower_node_id(item_id) }; @@ -2883,7 +2900,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 +2922,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.lower_expr(e)), + StmtKind::Semi(ref e) => hir::StmtKind::Semi(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 }] @@ -2944,74 +2961,75 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Helper methods for building HIR. - fn stmt(&mut self, span: Span, kind: hir::StmtKind) -> hir::Stmt { + fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> { hir::Stmt { span, kind, hir_id: self.next_id() } } - fn stmt_expr(&mut self, span: Span, expr: hir::Expr) -> hir::Stmt { - self.stmt(span, hir::StmtKind::Expr(P(expr))) + fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> { + 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::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 { - self.block_all(expr.span, hir::HirVec::new(), Some(expr)) + fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> { + self.block_all(expr.span, &[], Some(expr)) } fn block_all( &mut self, span: Span, - stmts: hir::HirVec, - expr: Option>, - ) -> hir::Block { - hir::Block { + stmts: &'hir [hir::Stmt<'hir>], + expr: Option<&'hir hir::Expr<'hir>>, + ) -> &'hir hir::Block<'hir> { + let blk = hir::Block { stmts, expr, hir_id: self.next_id(), rules: hir::DefaultBlock, span, targeted_by_break: false, - } + }; + self.arena.alloc(blk) } /// 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(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 +3040,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 +3049,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 +3062,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) -> 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 8311b9168e455..8a9614c6cb2c0 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; @@ -13,27 +13,31 @@ use syntax::symbol::{sym, Symbol}; use rustc_error_codes::*; -impl LoweringContext<'_, '_> { - fn lower_exprs(&mut self, exprs: &[AstP]) -> HirVec { - exprs.iter().map(|x| self.lower_expr(x)).collect() +impl<'hir> LoweringContext<'_, 'hir> { + fn lower_exprs(&mut self, exprs: &[AstP]) -> &'hir [hir::Expr<'hir>] { + self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x))) } - pub(super) fn lower_expr(&mut self, e: &Expr) -> hir::Expr { + pub(super) fn lower_expr(&mut self, e: &Expr) -> &'hir hir::Expr<'hir> { + self.arena.alloc(self.lower_expr_mut(e)) + } + + pub(super) fn lower_expr_mut(&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.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.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.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 +51,28 @@ impl LoweringContext<'_, '_> { } 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.lower_expr(lhs); + let rhs = 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.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.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.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.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 +91,8 @@ impl LoweringContext<'_, '_> { }), 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.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( @@ -123,16 +129,16 @@ impl LoweringContext<'_, '_> { 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) + hir::ExprKind::Assign(self.lower_expr(el), 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.lower_expr(el), + self.lower_expr(er), ), - ExprKind::Field(ref el, ident) => hir::ExprKind::Field(P(self.lower_expr(el)), ident), + ExprKind::Field(ref el, ident) => hir::ExprKind::Field(self.lower_expr(el), ident), ExprKind::Index(ref el, ref er) => { - hir::ExprKind::Index(P(self.lower_expr(el)), P(self.lower_expr(er))) + hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er)) } ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => { self.lower_expr_range_closed(e.span, e1, e2) @@ -150,28 +156,34 @@ impl LoweringContext<'_, '_> { ); 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| 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| 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| 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); + let mut ex = self.lower_expr_mut(ex); // Include parens in span, but only if it is a super-span. if e.span.contains(ex.span) { ex.span = e.span; @@ -237,7 +249,7 @@ impl LoweringContext<'_, '_> { /// ```rust /// match scrutinee { pats => true, _ => false } /// ``` - fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind { + fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind<'hir> { // If we got here, the `let` expression is not allowed. if self.sess.opts.unstable_features.is_nightly_build() { @@ -266,16 +278,16 @@ impl LoweringContext<'_, '_> { let then_arm = { let pat = self.lower_pat(pat); let expr = self.expr_bool(span, true); - self.arm(pat, P(expr)) + self.arm(pat, 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, expr) }; hir::ExprKind::Match( - P(scrutinee), - vec![then_arm, else_arm].into(), + scrutinee, + arena_vec![self; then_arm, else_arm], hir::MatchSource::Normal, ) } @@ -286,7 +298,7 @@ impl LoweringContext<'_, '_> { cond: &Expr, then: &Block, else_opt: Option<&Expr>, - ) -> hir::ExprKind { + ) -> hir::ExprKind<'hir> { // FIXME(#53667): handle lowering of && and parens. // `_ => else_block` where `else_block` is `{}` if there's `None`: @@ -295,7 +307,7 @@ impl LoweringContext<'_, '_> { 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, else_expr); // Handle then + scrutinee: let then_expr = self.lower_block_expr(then); @@ -315,14 +327,14 @@ impl LoweringContext<'_, '_> { // 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, 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(scrutinee, arena_vec![self; then_arm, else_arm], desugar) } fn lower_expr_while_in_loop_scope( @@ -331,7 +343,7 @@ impl LoweringContext<'_, '_> { cond: &Expr, body: &Block, opt_label: Option