diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 7bb141058d22e..e93c796c97059 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -12,7 +12,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, destination: Place<'tcx>, block: BasicBlock, - ast_block: &Block<'tcx>, + ast_block: &Block<'_, 'tcx>, source_info: SourceInfo, ) -> BlockAnd<()> { let Block { @@ -56,8 +56,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: Place<'tcx>, mut block: BasicBlock, span: Span, - stmts: &[Stmt<'tcx>], - expr: Option<&Expr<'tcx>>, + stmts: &[Stmt<'_, 'tcx>], + expr: Option<&Expr<'_, 'tcx>>, safety_mode: BlockSafety, ) -> BlockAnd<()> { let this = self; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 1096d2eedfe21..ce341c0c06cdf 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::CanonicalUserTypeAnnotation; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! - crate fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> { + crate fn as_constant(&mut self, expr: &Expr<'_, 'tcx>) -> Constant<'tcx> { let this = self; let Expr { ty, temp_lifetime: _, span, kind } = expr; match kind { diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index 81428e098699d..28262287b6339 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -17,7 +17,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn as_local_operand( &mut self, block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { let local_scope = self.local_scope(); self.as_operand(block, Some(local_scope), expr) @@ -74,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn as_local_call_operand( &mut self, block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { let local_scope = self.local_scope(); self.as_call_operand(block, Some(local_scope), expr) @@ -93,7 +93,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, mut block: BasicBlock, scope: Option, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { debug!("as_operand(block={:?}, expr={:?})", block, expr); let this = self; @@ -123,7 +123,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, mut block: BasicBlock, scope: Option, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { debug!("as_call_operand(block={:?}, expr={:?})", block, expr); let this = self; diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 3581ca1ee5bd5..30262e164201b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -350,7 +350,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn as_place( &mut self, mut block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { let place_builder = unpack!(block = self.as_place_builder(block, expr)); block.and(place_builder.into_place(self.tcx, self.typeck_results)) @@ -361,7 +361,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn as_place_builder( &mut self, block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { self.expr_as_place(block, expr, Mutability::Mut, None) } @@ -374,7 +374,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn as_read_only_place( &mut self, mut block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr)); block.and(place_builder.into_place(self.tcx, self.typeck_results)) @@ -389,7 +389,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn as_read_only_place_builder( &mut self, block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { self.expr_as_place(block, expr, Mutability::Not, None) } @@ -397,7 +397,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn expr_as_place( &mut self, mut block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, mutability: Mutability, fake_borrow_temps: Option<&mut Vec>, ) -> BlockAnd> { @@ -584,8 +584,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn lower_index_expression( &mut self, mut block: BasicBlock, - base: &Expr<'tcx>, - index: &Expr<'tcx>, + base: &Expr<'_, 'tcx>, + index: &Expr<'_, 'tcx>, mutability: Mutability, fake_borrow_temps: Option<&mut Vec>, temp_lifetime: Option, diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 89a179bd4510d..335ea4dca6006 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -22,7 +22,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn as_local_rvalue( &mut self, block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { let local_scope = self.local_scope(); self.as_rvalue(block, Some(local_scope), expr) @@ -33,7 +33,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, mut block: BasicBlock, scope: Option, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd> { debug!("expr_as_rvalue(block={:?}, scope={:?}, expr={:?})", block, scope, expr); @@ -368,7 +368,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { upvar_ty: Ty<'tcx>, temp_lifetime: Option, mut block: BasicBlock, - arg: &Expr<'tcx>, + arg: &Expr<'_, 'tcx>, ) -> BlockAnd> { let this = self; diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs index 8b032032bfc43..12029b04a08f3 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs @@ -14,7 +14,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, block: BasicBlock, temp_lifetime: Option, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, mutability: Mutability, ) -> BlockAnd { // this is the only place in mir building that we need to truly need to worry about @@ -27,7 +27,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, mut block: BasicBlock, temp_lifetime: Option, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, mutability: Mutability, ) -> BlockAnd { debug!( diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs index 9320b5810e396..0cadfa2f0a1af 100644 --- a/compiler/rustc_mir_build/src/build/expr/category.rs +++ b/compiler/rustc_mir_build/src/build/expr/category.rs @@ -31,7 +31,7 @@ crate enum RvalueFunc { /// Determines the category for a given expression. Note that scope /// and paren expressions have no category. impl Category { - crate fn of(ek: &ExprKind<'_>) -> Option { + crate fn of(ek: &ExprKind<'_, '_>) -> Option { match *ek { ExprKind::Scope { .. } => None, diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 83a09a005084a..4baf26dce6ad5 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -18,7 +18,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, destination: Place<'tcx>, mut block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd<()> { debug!("expr_into_dest(destination={:?}, block={:?}, expr={:?})", destination, block, expr); diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 470a3eaaa3c87..23e23f0885b77 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -13,7 +13,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn stmt_expr( &mut self, mut block: BasicBlock, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, statement_scope: Option, ) -> BlockAnd<()> { let this = self; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index d93fc6149c213..098ed8b3eb8ce 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -89,8 +89,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: Place<'tcx>, span: Span, mut block: BasicBlock, - scrutinee: &Expr<'tcx>, - arms: &[Arm<'tcx>], + scrutinee: &Expr<'_, 'tcx>, + arms: &[Arm<'_, 'tcx>], ) -> BlockAnd<()> { let scrutinee_span = scrutinee.span; let scrutinee_place = @@ -119,7 +119,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn lower_scrutinee( &mut self, mut block: BasicBlock, - scrutinee: &Expr<'tcx>, + scrutinee: &Expr<'_, 'tcx>, scrutinee_span: Span, ) -> BlockAnd> { let scrutinee_place = unpack!(block = self.as_place(block, scrutinee)); @@ -149,8 +149,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn create_match_candidates<'pat>( &mut self, scrutinee: Place<'tcx>, - arms: &'pat [Arm<'tcx>], - ) -> Vec<(&'pat Arm<'tcx>, Candidate<'pat, 'tcx>)> { + arms: &'pat [Arm<'pat, 'tcx>], + ) -> Vec<(&'pat Arm<'pat, 'tcx>, Candidate<'pat, 'tcx>)> { // Assemble a list of candidates: there is one candidate per pattern, // which means there may be more than one candidate *per arm*. arms.iter() @@ -224,7 +224,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: Place<'tcx>, scrutinee_place: Place<'tcx>, scrutinee_span: Span, - arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>, + arm_candidates: Vec<(&'_ Arm<'_, 'tcx>, Candidate<'_, 'tcx>)>, outer_source_info: SourceInfo, fake_borrow_temps: Vec<(Place<'tcx>, Local)>, ) -> BlockAnd<()> { @@ -285,7 +285,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, outer_source_info: SourceInfo, candidate: Candidate<'_, 'tcx>, - guard: Option<&Guard<'tcx>>, + guard: Option<&Guard<'_, 'tcx>>, fake_borrow_temps: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, arm_span: Option, @@ -361,7 +361,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, mut block: BasicBlock, irrefutable_pat: Pat<'tcx>, - initializer: &Expr<'tcx>, + initializer: &Expr<'_, 'tcx>, ) -> BlockAnd<()> { match *irrefutable_pat.kind { // Optimize the case of `let x = ...` to write directly into `x` @@ -1612,7 +1612,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, candidate: Candidate<'pat, 'tcx>, parent_bindings: &[(Vec>, Vec>)], - guard: Option<&Guard<'tcx>>, + guard: Option<&Guard<'_, 'tcx>>, fake_borrows: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, arm_span: Option, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index ecc5f2f260e7d..ef531a2392183 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,7 +1,7 @@ use crate::build; use crate::build::scope::DropKind; -use crate::thir::cx::Cx; -use crate::thir::{BindingMode, Expr, LintLevel, Pat, PatKind}; +use crate::thir::cx::build_thir; +use crate::thir::{Arena, BindingMode, Expr, LintLevel, Pat, PatKind}; use rustc_attr::{self as attr, UnwindAttr}; use rustc_errors::ErrorReported; use rustc_hir as hir; @@ -43,6 +43,7 @@ crate fn mir_built<'tcx>( fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_> { let id = tcx.hir().local_def_id_to_hir_id(def.did); let body_owner_kind = tcx.hir().body_owner_kind(id); + let typeck_results = tcx.typeck_opt_const_arg(def); // Figure out what primary body this item has. let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) { @@ -87,15 +88,15 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ // If we don't have a specialized span for the body, just use the // normal def span. let span_with_body = span_with_body.unwrap_or_else(|| tcx.hir().span(id)); + let arena = Arena::default(); tcx.infer_ctxt().enter(|infcx| { - let mut cx = Cx::new(tcx, def); - let body = if let Some(ErrorReported) = cx.typeck_results.tainted_by_errors { + let body = if let Some(ErrorReported) = typeck_results.tainted_by_errors { build::construct_error(&infcx, def, id, body_id, body_owner_kind) } else if body_owner_kind.is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) - let fn_sig = cx.typeck_results.liberated_fn_sigs()[id]; + let fn_sig = typeck_results.liberated_fn_sigs()[id]; let fn_def_id = tcx.hir().local_def_id(id); let safety = match fn_sig.unsafety { @@ -104,7 +105,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ }; let body = tcx.hir().body(body_id); - let expr = cx.mirror_expr(&body.value); + let thir = build_thir(tcx, def, &arena, &body.value); let ty = tcx.type_of(fn_def_id); let mut abi = fn_sig.abi; let implicit_argument = match ty.kind() { @@ -189,7 +190,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ return_ty, return_ty_span, body, - expr, + thir, span_with_body, ); if yield_ty.is_some() { @@ -209,12 +210,12 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ // place to be the type of the constant because NLL typeck will // equate them. - let return_ty = cx.typeck_results.node_type(id); + let return_ty = typeck_results.node_type(id); let ast_expr = &tcx.hir().body(body_id).value; - let expr = cx.mirror_expr(ast_expr); + let thir = build_thir(tcx, def, &arena, ast_expr); - build::construct_const(&infcx, expr, def, id, return_ty, return_ty_span) + build::construct_const(&infcx, thir, def, id, return_ty, return_ty_span) }; lints::check(tcx, &body); @@ -601,7 +602,7 @@ fn construct_fn<'tcx, A>( return_ty: Ty<'tcx>, return_ty_span: Span, body: &'tcx hir::Body<'tcx>, - expr: Expr<'tcx>, + expr: &Expr<'_, 'tcx>, span_with_body: Span, ) -> Body<'tcx> where @@ -668,7 +669,7 @@ where fn construct_const<'a, 'tcx>( infcx: &'a InferCtxt<'a, 'tcx>, - expr: Expr<'tcx>, + expr: &Expr<'_, 'tcx>, def: ty::WithOptConstParam, hir_id: hir::HirId, const_ty: Ty<'tcx>, @@ -825,7 +826,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn_def_id: DefId, arguments: &[ArgInfo<'tcx>], argument_scope: region::Scope, - expr: &Expr<'tcx>, + expr: &Expr<'_, 'tcx>, ) -> BlockAnd<()> { // Allocate locals for the function arguments for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 6c58528a3c5c6..b637b9b70bdc6 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -574,7 +574,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn break_scope( &mut self, mut block: BasicBlock, - value: Option<&Expr<'tcx>>, + value: Option<&Expr<'_, 'tcx>>, target: BreakableTarget, source_info: SourceInfo, ) -> BlockAnd<()> { @@ -918,7 +918,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn test_bool( &mut self, mut block: BasicBlock, - condition: &Expr<'tcx>, + condition: &Expr<'_, 'tcx>, source_info: SourceInfo, ) -> (BasicBlock, BasicBlock) { let cond = unpack!(block = self.as_local_operand(block, condition)); diff --git a/compiler/rustc_mir_build/src/thir/arena.rs b/compiler/rustc_mir_build/src/thir/arena.rs new file mode 100644 index 0000000000000..aacc7b12a42f9 --- /dev/null +++ b/compiler/rustc_mir_build/src/thir/arena.rs @@ -0,0 +1,98 @@ +use crate::thir::*; + +macro_rules! declare_arena { + ([], [$($a:tt $name:ident: $ty:ty,)*]) => { + #[derive(Default)] + pub struct Arena<'thir, 'tcx> { + pub dropless: rustc_arena::DroplessArena, + drop: rustc_arena::DropArena, + $($name: rustc_arena::arena_for_type!($a[$ty]),)* + } + + pub trait ArenaAllocatable<'thir, 'tcx, T = Self>: Sized { + fn allocate_on(self, arena: &'thir Arena<'thir, 'tcx>) -> &'thir mut Self; + fn allocate_from_iter( + arena: &'thir Arena<'thir, 'tcx>, + iter: impl ::std::iter::IntoIterator, + ) -> &'thir mut [Self]; + } + + impl<'thir, 'tcx, T: Copy> ArenaAllocatable<'thir, 'tcx, ()> for T { + #[inline] + fn allocate_on(self, arena: &'thir Arena<'thir, 'tcx>) -> &'thir mut Self { + arena.dropless.alloc(self) + } + #[inline] + fn allocate_from_iter( + arena: &'thir Arena<'thir, 'tcx>, + iter: impl ::std::iter::IntoIterator, + ) -> &'thir mut [Self] { + arena.dropless.alloc_from_iter(iter) + } + + } + $( + impl<'thir, 'tcx> ArenaAllocatable<'thir, 'tcx, $ty> for $ty { + #[inline] + fn allocate_on(self, arena: &'thir Arena<'thir, 'tcx>) -> &'thir mut Self { + if !::std::mem::needs_drop::() { + return arena.dropless.alloc(self); + } + match rustc_arena::which_arena_for_type!($a[&arena.$name]) { + ::std::option::Option::<&rustc_arena::TypedArena>::Some(ty_arena) => { + ty_arena.alloc(self) + } + ::std::option::Option::None => unsafe { arena.drop.alloc(self) }, + } + } + + #[inline] + fn allocate_from_iter( + arena: &'thir Arena<'thir, 'tcx>, + iter: impl ::std::iter::IntoIterator, + ) -> &'thir mut [Self] { + if !::std::mem::needs_drop::() { + return arena.dropless.alloc_from_iter(iter); + } + match rustc_arena::which_arena_for_type!($a[&arena.$name]) { + ::std::option::Option::<&rustc_arena::TypedArena>::Some(ty_arena) => { + ty_arena.alloc_from_iter(iter) + } + ::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) }, + } + } + } + )* + + impl<'thir, 'tcx> Arena<'thir, 'tcx> { + #[inline] + pub fn alloc, U>(&'thir self, value: T) -> &'thir mut T { + value.allocate_on(self) + } + + #[allow(dead_code)] // function is never used + #[inline] + pub fn alloc_slice(&'thir self, value: &[T]) -> &'thir mut [T] { + if value.is_empty() { + return &mut []; + } + self.dropless.alloc_slice(value) + } + + pub fn alloc_from_iter, U>( + &'thir self, + iter: impl ::std::iter::IntoIterator, + ) -> &'thir mut [T] { + T::allocate_from_iter(self, iter) + } + } + } +} + +declare_arena!([], [ + [] arm: Arm<'thir, 'tcx>, + [] expr: Expr<'thir, 'tcx>, + [] field_expr: FieldExpr<'thir, 'tcx>, + [few] inline_asm_operand: InlineAsmOperand<'thir, 'tcx>, + [] stmt: Stmt<'thir, 'tcx>, +]); diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 25af65d1c6538..2ec102282c28e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -7,8 +7,8 @@ use rustc_middle::ty; use rustc_index::vec::Idx; -impl<'tcx> Cx<'tcx> { - crate fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block<'tcx> { +impl<'thir, 'tcx> Cx<'thir, 'tcx> { + crate fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block<'thir, 'tcx> { // We have to eagerly lower the "spine" of the statements // in order to get the lexical scoping correctly. let stmts = self.mirror_stmts(block.hir_id.local_id, &*block.stmts); @@ -23,7 +23,7 @@ impl<'tcx> Cx<'tcx> { opt_destruction_scope, span: block.span, stmts, - expr: block.expr.as_ref().map(|expr| self.mirror_expr_boxed(expr)), + expr: block.expr.as_ref().map(|expr| self.mirror_expr(expr)), safety_mode: match block.rules { hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe, hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(block.hir_id), @@ -37,26 +37,21 @@ impl<'tcx> Cx<'tcx> { &mut self, block_id: hir::ItemLocalId, stmts: &'tcx [hir::Stmt<'tcx>], - ) -> Vec> { - let mut result = vec![]; - for (index, stmt) in stmts.iter().enumerate() { + ) -> &'thir [Stmt<'thir, 'tcx>] { + self.arena.alloc_from_iter(stmts.iter().enumerate().filter_map(|(index, stmt)| { let hir_id = stmt.hir_id; let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id); match stmt.kind { - hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { - result.push(Stmt { - kind: StmtKind::Expr { - scope: region::Scope { - id: hir_id.local_id, - data: region::ScopeData::Node, - }, - expr: self.mirror_expr_boxed(expr), - }, - opt_destruction_scope: opt_dxn_ext, - }) - } + hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => Some(Stmt { + kind: StmtKind::Expr { + scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node }, + expr: self.mirror_expr(expr), + }, + opt_destruction_scope: opt_dxn_ext, + }), hir::StmtKind::Item(..) => { // ignore for purposes of the MIR + None } hir::StmtKind::Local(ref local) => { let remainder_scope = region::Scope { @@ -86,7 +81,7 @@ impl<'tcx> Cx<'tcx> { } } - result.push(Stmt { + Some(Stmt { kind: StmtKind::Let { remainder_scope, init_scope: region::Scope { @@ -94,14 +89,13 @@ impl<'tcx> Cx<'tcx> { data: region::ScopeData::Node, }, pattern, - initializer: local.init.map(|init| self.mirror_expr_boxed(init)), + initializer: local.init.map(|init| self.mirror_expr(init)), lint_level: LintLevel::Explicit(local.hir_id), }, opt_destruction_scope: opt_dxn_ext, - }); + }) } } - } - result + })) } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 2d1170ca3a89d..73ec9ac4dcf86 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -15,8 +15,33 @@ use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{self, AdtKind, Ty}; use rustc_span::Span; -impl<'tcx> Cx<'tcx> { - crate fn mirror_expr(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> { +use std::iter; + +impl<'thir, 'tcx> Cx<'thir, 'tcx> { + /// Mirrors and allocates a single [`hir::Expr`]. If you need to mirror a whole slice + /// of expressions, prefer using [`mirror_exprs`]. + /// + /// [`mirror_exprs`]: Self::mirror_exprs + crate fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> &'thir Expr<'thir, 'tcx> { + self.arena.alloc(self.mirror_expr_inner(expr)) + } + + /// Mirrors and allocates a slice of [`hir::Expr`]s. They will be allocated as a + /// contiguous sequence in memory. + crate fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> &'thir [Expr<'thir, 'tcx>] { + self.arena.alloc_from_iter(exprs.iter().map(|expr| self.mirror_expr_inner(expr))) + } + + /// Mirrors a [`hir::Expr`] without allocating it into the arena. + /// This is a separate, private function so that [`mirror_expr`] and [`mirror_exprs`] can + /// decide how to allocate this expression (alone or within a slice). + /// + /// [`mirror_expr`]: Self::mirror_expr + /// [`mirror_exprs`]: Self::mirror_exprs + pub(super) fn mirror_expr_inner( + &mut self, + hir_expr: &'tcx hir::Expr<'tcx>, + ) -> Expr<'thir, 'tcx> { let temp_lifetime = self.region_scope_tree.temporary_scope(hir_expr.hir_id.local_id); let expr_scope = region::Scope { id: hir_expr.hir_id.local_id, data: region::ScopeData::Node }; @@ -38,7 +63,7 @@ impl<'tcx> Cx<'tcx> { span: hir_expr.span, kind: ExprKind::Scope { region_scope: expr_scope, - value: Box::new(expr), + value: self.arena.alloc(expr), lint_level: LintLevel::Explicit(hir_expr.hir_id), }, }; @@ -53,7 +78,7 @@ impl<'tcx> Cx<'tcx> { span: hir_expr.span, kind: ExprKind::Scope { region_scope, - value: Box::new(expr), + value: self.arena.alloc(expr), lint_level: LintLevel::Inherited, }, }; @@ -63,20 +88,12 @@ impl<'tcx> Cx<'tcx> { expr } - crate fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Vec> { - exprs.iter().map(|expr| self.mirror_expr(expr)).collect() - } - - crate fn mirror_expr_boxed(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Box> { - Box::new(self.mirror_expr(expr)) - } - fn apply_adjustment( &mut self, hir_expr: &'tcx hir::Expr<'tcx>, - mut expr: Expr<'tcx>, + mut expr: Expr<'thir, 'tcx>, adjustment: &Adjustment<'tcx>, - ) -> Expr<'tcx> { + ) -> Expr<'thir, 'tcx> { let Expr { temp_lifetime, mut span, .. } = expr; // Adjust the span from the block, to the last expression of the @@ -89,7 +106,7 @@ impl<'tcx> Cx<'tcx> { // x // // ^ error message points at this expression. // } - let mut adjust_span = |expr: &mut Expr<'tcx>| { + let mut adjust_span = |expr: &mut Expr<'thir, 'tcx>| { if let ExprKind::Block { body } = &expr.kind { if let Some(ref last_expr) = body.expr { span = last_expr.span; @@ -101,13 +118,13 @@ impl<'tcx> Cx<'tcx> { let kind = match adjustment.kind { Adjust::Pointer(PointerCast::Unsize) => { adjust_span(&mut expr); - ExprKind::Pointer { cast: PointerCast::Unsize, source: Box::new(expr) } + ExprKind::Pointer { cast: PointerCast::Unsize, source: self.arena.alloc(expr) } } - Adjust::Pointer(cast) => ExprKind::Pointer { cast, source: Box::new(expr) }, - Adjust::NeverToAny => ExprKind::NeverToAny { source: Box::new(expr) }, + Adjust::Pointer(cast) => ExprKind::Pointer { cast, source: self.arena.alloc(expr) }, + Adjust::NeverToAny => ExprKind::NeverToAny { source: self.arena.alloc(expr) }, Adjust::Deref(None) => { adjust_span(&mut expr); - ExprKind::Deref { arg: Box::new(expr) } + ExprKind::Deref { arg: self.arena.alloc(expr) } } Adjust::Deref(Some(deref)) => { // We don't need to do call adjust_span here since @@ -122,7 +139,7 @@ impl<'tcx> Cx<'tcx> { span, kind: ExprKind::Borrow { borrow_kind: deref.mutbl.to_borrow_kind(), - arg: Box::new(expr), + arg: self.arena.alloc(expr), }, }; @@ -130,22 +147,22 @@ impl<'tcx> Cx<'tcx> { hir_expr, adjustment.target, Some(call), - vec![expr], + self.arena.alloc_from_iter(iter::once(expr)), deref.span, ) } Adjust::Borrow(AutoBorrow::Ref(_, m)) => { - ExprKind::Borrow { borrow_kind: m.to_borrow_kind(), arg: Box::new(expr) } + ExprKind::Borrow { borrow_kind: m.to_borrow_kind(), arg: self.arena.alloc(expr) } } Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { - ExprKind::AddressOf { mutability, arg: Box::new(expr) } + ExprKind::AddressOf { mutability, arg: self.arena.alloc(expr) } } }; Expr { temp_lifetime, ty: adjustment.target, span, kind } } - fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> { + fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'thir, 'tcx> { let expr_ty = self.typeck_results().expr_ty(expr); let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); @@ -157,7 +174,7 @@ impl<'tcx> Cx<'tcx> { let args = self.mirror_exprs(args); ExprKind::Call { ty: expr.ty, - fun: Box::new(expr), + fun: self.arena.alloc(expr), args, from_hir_call: true, fn_span, @@ -185,8 +202,10 @@ impl<'tcx> Cx<'tcx> { ExprKind::Call { ty: method.ty, - fun: Box::new(method), - args: vec![self.mirror_expr(fun), tupled_args], + fun: self.arena.alloc(method), + args: &*self + .arena + .alloc_from_iter(vec![self.mirror_expr_inner(fun), tupled_args]), from_hir_call: true, fn_span: expr.span, } @@ -216,26 +235,22 @@ impl<'tcx> Cx<'tcx> { }); debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty); - let field_refs = args - .iter() - .enumerate() - .map(|(idx, e)| FieldExpr { - name: Field::new(idx), - expr: self.mirror_expr(e), - }) - .collect(); + let field_refs = + self.arena.alloc_from_iter(args.iter().enumerate().map(|(idx, e)| { + FieldExpr { name: Field::new(idx), expr: self.mirror_expr(e) } + })); ExprKind::Adt { adt_def, substs, variant_index: index, - fields: field_refs, + fields: &*field_refs, user_ty, base: None, } } else { ExprKind::Call { ty: self.typeck_results().node_type(fun.hir_id), - fun: self.mirror_expr_boxed(fun), + fun: self.mirror_expr(fun), args: self.mirror_exprs(args), from_hir_call: true, fn_span: expr.span, @@ -244,32 +259,30 @@ impl<'tcx> Cx<'tcx> { } } - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, ref arg) => ExprKind::Borrow { - borrow_kind: mutbl.to_borrow_kind(), - arg: self.mirror_expr_boxed(arg), - }, + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, ref arg) => { + ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) } + } hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, ref arg) => { - ExprKind::AddressOf { mutability, arg: self.mirror_expr_boxed(arg) } + ExprKind::AddressOf { mutability, arg: self.mirror_expr(arg) } } hir::ExprKind::Block(ref blk, _) => ExprKind::Block { body: self.mirror_block(blk) }, - hir::ExprKind::Assign(ref lhs, ref rhs, _) => ExprKind::Assign { - lhs: self.mirror_expr_boxed(lhs), - rhs: self.mirror_expr_boxed(rhs), - }, + hir::ExprKind::Assign(ref lhs, ref rhs, _) => { + ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) } + } hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => { if self.typeck_results().is_method_call(expr) { - let lhs = self.mirror_expr(lhs); - let rhs = self.mirror_expr(rhs); - self.overloaded_operator(expr, vec![lhs, rhs]) + let lhs = self.mirror_expr_inner(lhs); + let rhs = self.mirror_expr_inner(rhs); + self.overloaded_operator(expr, &*self.arena.alloc_from_iter(vec![lhs, rhs])) } else { ExprKind::AssignOp { op: bin_op(op.node), - lhs: self.mirror_expr_boxed(lhs), - rhs: self.mirror_expr_boxed(rhs), + lhs: self.mirror_expr(lhs), + rhs: self.mirror_expr(rhs), } } } @@ -282,29 +295,29 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Binary(op, ref lhs, ref rhs) => { if self.typeck_results().is_method_call(expr) { - let lhs = self.mirror_expr(lhs); - let rhs = self.mirror_expr(rhs); - self.overloaded_operator(expr, vec![lhs, rhs]) + let lhs = self.mirror_expr_inner(lhs); + let rhs = self.mirror_expr_inner(rhs); + self.overloaded_operator(expr, &*self.arena.alloc_from_iter(vec![lhs, rhs])) } else { // FIXME overflow match op.node { hir::BinOpKind::And => ExprKind::LogicalOp { op: LogicalOp::And, - lhs: self.mirror_expr_boxed(lhs), - rhs: self.mirror_expr_boxed(rhs), + lhs: self.mirror_expr(lhs), + rhs: self.mirror_expr(rhs), }, hir::BinOpKind::Or => ExprKind::LogicalOp { op: LogicalOp::Or, - lhs: self.mirror_expr_boxed(lhs), - rhs: self.mirror_expr_boxed(rhs), + lhs: self.mirror_expr(lhs), + rhs: self.mirror_expr(rhs), }, _ => { let op = bin_op(op.node); ExprKind::Binary { op, - lhs: self.mirror_expr_boxed(lhs), - rhs: self.mirror_expr_boxed(rhs), + lhs: self.mirror_expr(lhs), + rhs: self.mirror_expr(rhs), } } } @@ -313,39 +326,48 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Index(ref lhs, ref index) => { if self.typeck_results().is_method_call(expr) { - let lhs = self.mirror_expr(lhs); - let index = self.mirror_expr(index); - self.overloaded_place(expr, expr_ty, None, vec![lhs, index], expr.span) + let lhs = self.mirror_expr_inner(lhs); + let index = self.mirror_expr_inner(index); + self.overloaded_place( + expr, + expr_ty, + None, + &*self.arena.alloc_from_iter(vec![lhs, index]), + expr.span, + ) } else { - ExprKind::Index { - lhs: self.mirror_expr_boxed(lhs), - index: self.mirror_expr_boxed(index), - } + ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) } } } hir::ExprKind::Unary(hir::UnOp::Deref, ref arg) => { if self.typeck_results().is_method_call(expr) { - let arg = self.mirror_expr(arg); - self.overloaded_place(expr, expr_ty, None, vec![arg], expr.span) + let arg = self.mirror_expr_inner(arg); + self.overloaded_place( + expr, + expr_ty, + None, + &*self.arena.alloc_from_iter(iter::once(arg)), + expr.span, + ) } else { - ExprKind::Deref { arg: self.mirror_expr_boxed(arg) } + ExprKind::Deref { arg: self.mirror_expr(arg) } } } hir::ExprKind::Unary(hir::UnOp::Not, ref arg) => { if self.typeck_results().is_method_call(expr) { - let arg = self.mirror_expr(arg); - self.overloaded_operator(expr, vec![arg]) + let arg = self.mirror_expr_inner(arg); + self.overloaded_operator(expr, &*self.arena.alloc_from_iter(iter::once(arg))) } else { - ExprKind::Unary { op: UnOp::Not, arg: self.mirror_expr_boxed(arg) } + ExprKind::Unary { op: UnOp::Not, arg: self.mirror_expr(arg) } } } hir::ExprKind::Unary(hir::UnOp::Neg, ref arg) => { if self.typeck_results().is_method_call(expr) { - let arg = self.mirror_expr(arg); - self.overloaded_operator(expr, vec![arg]) + let arg = self.mirror_expr_inner(arg); + self.overloaded_operator(expr, &*self.arena.alloc_from_iter(iter::once(arg))) } else if let hir::ExprKind::Lit(ref lit) = arg.kind { ExprKind::Literal { literal: self.const_eval_literal(&lit.node, expr_ty, lit.span, true), @@ -353,7 +375,7 @@ impl<'tcx> Cx<'tcx> { const_id: None, } } else { - ExprKind::Unary { op: UnOp::Neg, arg: self.mirror_expr_boxed(arg) } + ExprKind::Unary { op: UnOp::Neg, arg: self.mirror_expr(arg) } } } @@ -370,9 +392,12 @@ impl<'tcx> Cx<'tcx> { user_ty, fields: self.field_refs(fields), base: base.as_ref().map(|base| FruInfo { - base: self.mirror_expr_boxed(base), - field_types: self.typeck_results().fru_field_types()[expr.hir_id] - .clone(), + base: self.mirror_expr(base), + field_types: self.arena.alloc_from_iter( + self.typeck_results().fru_field_types()[expr.hir_id] + .iter() + .cloned(), + ), }), } } @@ -419,12 +444,12 @@ impl<'tcx> Cx<'tcx> { } }; - let upvars = self - .typeck_results - .closure_min_captures_flattened(def_id) - .zip(substs.upvar_tys()) - .map(|(captured_place, ty)| self.capture_upvar(expr, captured_place, ty)) - .collect(); + let upvars = self.arena.alloc_from_iter( + self.typeck_results + .closure_min_captures_flattened(def_id) + .zip(substs.upvar_tys()) + .map(|(captured_place, ty)| self.capture_upvar(expr, captured_place, ty)), + ); ExprKind::Closure { closure_id: def_id, substs, upvars, movability } } @@ -435,100 +460,95 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::InlineAsm(ref asm) => ExprKind::InlineAsm { template: asm.template, - operands: asm - .operands - .iter() - .map(|(op, _op_sp)| { - match *op { - hir::InlineAsmOperand::In { reg, ref expr } => { - InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) } - } - hir::InlineAsmOperand::Out { reg, late, ref expr } => { - InlineAsmOperand::Out { - reg, - late, - expr: expr.as_ref().map(|expr| self.mirror_expr(expr)), - } - } - hir::InlineAsmOperand::InOut { reg, late, ref expr } => { - InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) } - } - hir::InlineAsmOperand::SplitInOut { - reg, - late, - ref in_expr, - ref out_expr, - } => InlineAsmOperand::SplitInOut { + operands: self.arena.alloc_from_iter(asm.operands.iter().map(|(op, _op_sp)| { + match *op { + hir::InlineAsmOperand::In { reg, ref expr } => { + InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) } + } + hir::InlineAsmOperand::Out { reg, late, ref expr } => { + InlineAsmOperand::Out { reg, late, - in_expr: self.mirror_expr(in_expr), - out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)), - }, - hir::InlineAsmOperand::Const { ref expr } => { - InlineAsmOperand::Const { expr: self.mirror_expr(expr) } + expr: expr.as_ref().map(|expr| self.mirror_expr(expr)), } - hir::InlineAsmOperand::Sym { ref expr } => { - let qpath = match expr.kind { - hir::ExprKind::Path(ref qpath) => qpath, - _ => span_bug!( - expr.span, - "asm `sym` operand should be a path, found {:?}", - expr.kind - ), - }; - let temp_lifetime = - self.region_scope_tree.temporary_scope(expr.hir_id.local_id); - let res = self.typeck_results().qpath_res(qpath, expr.hir_id); - let ty; - match res { - Res::Def(DefKind::Fn, _) | Res::Def(DefKind::AssocFn, _) => { - ty = self.typeck_results().node_type(expr.hir_id); - let user_ty = - self.user_substs_applied_to_res(expr.hir_id, res); - InlineAsmOperand::SymFn { - expr: Expr { - ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::Literal { - literal: ty::Const::zero_sized(self.tcx, ty), - user_ty, - const_id: None, - }, + } + hir::InlineAsmOperand::InOut { reg, late, ref expr } => { + InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) } + } + hir::InlineAsmOperand::SplitInOut { + reg, + late, + ref in_expr, + ref out_expr, + } => InlineAsmOperand::SplitInOut { + reg, + late, + in_expr: self.mirror_expr(in_expr), + out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)), + }, + hir::InlineAsmOperand::Const { ref expr } => { + InlineAsmOperand::Const { expr: self.mirror_expr(expr) } + } + hir::InlineAsmOperand::Sym { ref expr } => { + let qpath = match expr.kind { + hir::ExprKind::Path(ref qpath) => qpath, + _ => span_bug!( + expr.span, + "asm `sym` operand should be a path, found {:?}", + expr.kind + ), + }; + let temp_lifetime = + self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + let res = self.typeck_results().qpath_res(qpath, expr.hir_id); + let ty; + match res { + Res::Def(DefKind::Fn, _) | Res::Def(DefKind::AssocFn, _) => { + ty = self.typeck_results().node_type(expr.hir_id); + let user_ty = self.user_substs_applied_to_res(expr.hir_id, res); + InlineAsmOperand::SymFn { + expr: self.arena.alloc(Expr { + ty, + temp_lifetime, + span: expr.span, + kind: ExprKind::Literal { + literal: ty::Const::zero_sized(self.tcx, ty), + user_ty, + const_id: None, }, - } + }), } + } - Res::Def(DefKind::Static, def_id) => { - InlineAsmOperand::SymStatic { def_id } - } + Res::Def(DefKind::Static, def_id) => { + InlineAsmOperand::SymStatic { def_id } + } - _ => { - self.tcx.sess.span_err( - expr.span, - "asm `sym` operand must point to a fn or static", - ); - - // Not a real fn, but we're not reaching codegen anyways... - ty = self.tcx.ty_error(); - InlineAsmOperand::SymFn { - expr: Expr { - ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::Literal { - literal: ty::Const::zero_sized(self.tcx, ty), - user_ty: None, - const_id: None, - }, + _ => { + self.tcx.sess.span_err( + expr.span, + "asm `sym` operand must point to a fn or static", + ); + + // Not a real fn, but we're not reaching codegen anyways... + ty = self.tcx.ty_error(); + InlineAsmOperand::SymFn { + expr: self.arena.alloc(Expr { + ty, + temp_lifetime, + span: expr.span, + kind: ExprKind::Literal { + literal: ty::Const::zero_sized(self.tcx, ty), + user_ty: None, + const_id: None, }, - } + }), } } } } - }) - .collect(), + } + })), options: asm.options, line_spans: asm.line_spans, }, @@ -550,15 +570,15 @@ impl<'tcx> Cx<'tcx> { let count_def_id = self.tcx.hir().local_def_id(count.hir_id); let count = ty::Const::from_anon_const(self.tcx, count_def_id); - ExprKind::Repeat { value: self.mirror_expr_boxed(v), count } + ExprKind::Repeat { value: self.mirror_expr(v), count } } hir::ExprKind::Ret(ref v) => { - ExprKind::Return { value: v.as_ref().map(|v| self.mirror_expr_boxed(v)) } + ExprKind::Return { value: v.as_ref().map(|v| self.mirror_expr(v)) } } hir::ExprKind::Break(dest, ref value) => match dest.target_id { Ok(target_id) => ExprKind::Break { label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node }, - value: value.as_ref().map(|value| self.mirror_expr_boxed(value)), + value: value.as_ref().map(|value| self.mirror_expr(value)), }, Err(err) => bug!("invalid loop id for break: {}", err), }, @@ -569,19 +589,19 @@ impl<'tcx> Cx<'tcx> { Err(err) => bug!("invalid loop id for continue: {}", err), }, hir::ExprKind::If(cond, then, else_opt) => ExprKind::If { - cond: self.mirror_expr_boxed(cond), - then: self.mirror_expr_boxed(then), - else_opt: else_opt.map(|el| self.mirror_expr_boxed(el)), + cond: self.mirror_expr(cond), + then: self.mirror_expr(then), + else_opt: else_opt.map(|el| self.mirror_expr(el)), }, hir::ExprKind::Match(ref discr, ref arms, _) => ExprKind::Match { - scrutinee: self.mirror_expr_boxed(discr), - arms: arms.iter().map(|a| self.convert_arm(a)).collect(), + scrutinee: self.mirror_expr(discr), + arms: self.arena.alloc_from_iter(arms.iter().map(|a| self.convert_arm(a))), }, hir::ExprKind::Loop(ref body, ..) => { let block_ty = self.typeck_results().node_type(body.hir_id); let temp_lifetime = self.region_scope_tree.temporary_scope(body.hir_id.local_id); let block = self.mirror_block(body); - let body = Box::new(Expr { + let body = self.arena.alloc(Expr { ty: block_ty, temp_lifetime, span: block.span, @@ -590,7 +610,7 @@ impl<'tcx> Cx<'tcx> { ExprKind::Loop { body } } hir::ExprKind::Field(ref source, ..) => ExprKind::Field { - lhs: self.mirror_expr_boxed(source), + lhs: self.mirror_expr(source), name: Field::new(self.tcx.field_index(expr.hir_id, self.typeck_results)), }, hir::ExprKind::Cast(ref source, ref cast_ty) => { @@ -607,13 +627,13 @@ impl<'tcx> Cx<'tcx> { // using a coercion (or is a no-op). let cast = if self.typeck_results().is_coercion_cast(source.hir_id) { // Convert the lexpr to a vexpr. - ExprKind::Use { source: self.mirror_expr_boxed(source) } + ExprKind::Use { source: self.mirror_expr(source) } } else if self.typeck_results().expr_ty(source).is_region_ptr() { // Special cased so that we can type check that the element // type of the source matches the pointed to type of the // destination. ExprKind::Pointer { - source: self.mirror_expr_boxed(source), + source: self.mirror_expr(source), cast: PointerCast::ArrayToPointer, } } else { @@ -651,11 +671,13 @@ impl<'tcx> Cx<'tcx> { }; let source = if let Some((did, offset, var_ty)) = var { - let mk_const = |literal| Expr { - temp_lifetime, - ty: var_ty, - span: expr.span, - kind: ExprKind::Literal { literal, user_ty: None, const_id: None }, + let mk_const = |literal| { + self.arena.alloc(Expr { + temp_lifetime, + ty: var_ty, + span: expr.span, + kind: ExprKind::Literal { literal, user_ty: None, const_id: None }, + }) }; let offset = mk_const(ty::Const::from_bits( self.tcx, @@ -675,12 +697,14 @@ impl<'tcx> Cx<'tcx> { ), ty: var_ty, })); - let bin = ExprKind::Binary { - op: BinOp::Add, - lhs: Box::new(lhs), - rhs: Box::new(offset), - }; - Expr { temp_lifetime, ty: var_ty, span: expr.span, kind: bin } + let bin = + ExprKind::Binary { op: BinOp::Add, lhs: lhs, rhs: offset }; + self.arena.alloc(Expr { + temp_lifetime, + ty: var_ty, + span: expr.span, + kind: bin, + }) } None => offset, } @@ -688,14 +712,18 @@ impl<'tcx> Cx<'tcx> { self.mirror_expr(source) }; - ExprKind::Cast { source: Box::new(source) } + ExprKind::Cast { source: source } }; if let Some(user_ty) = user_ty { // NOTE: Creating a new Expr and wrapping a Cast inside of it may be // inefficient, revisit this when performance becomes an issue. - let cast_expr = - Box::new(Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind: cast }); + let cast_expr = self.arena.alloc(Expr { + temp_lifetime, + ty: expr_ty, + span: expr.span, + kind: cast, + }); debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty); ExprKind::ValueTypeAscription { source: cast_expr, user_ty: Some(*user_ty) } @@ -707,7 +735,7 @@ impl<'tcx> Cx<'tcx> { let user_provided_types = self.typeck_results.user_provided_types(); let user_ty = user_provided_types.get(ty.hir_id).copied(); debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty); - let mirrored = self.mirror_expr_boxed(source); + let mirrored = self.mirror_expr(source); if source.is_syntactic_place_expr() { ExprKind::PlaceTypeAscription { source: mirrored, user_ty } } else { @@ -715,17 +743,15 @@ impl<'tcx> Cx<'tcx> { } } hir::ExprKind::DropTemps(ref source) => { - ExprKind::Use { source: self.mirror_expr_boxed(source) } + ExprKind::Use { source: self.mirror_expr(source) } } - hir::ExprKind::Box(ref value) => ExprKind::Box { value: self.mirror_expr_boxed(value) }, - hir::ExprKind::Array(ref fields) => ExprKind::Array { - fields: fields.iter().map(|field| self.mirror_expr(field)).collect(), - }, - hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { - fields: fields.iter().map(|field| self.mirror_expr(field)).collect(), - }, + hir::ExprKind::Box(ref value) => ExprKind::Box { value: self.mirror_expr(value) }, + hir::ExprKind::Array(ref fields) => { + ExprKind::Array { fields: self.mirror_exprs(fields) } + } + hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) }, - hir::ExprKind::Yield(ref v, _) => ExprKind::Yield { value: self.mirror_expr_boxed(v) }, + hir::ExprKind::Yield(ref v, _) => ExprKind::Yield { value: self.mirror_expr(v) }, hir::ExprKind::Err => unreachable!(), }; @@ -772,7 +798,7 @@ impl<'tcx> Cx<'tcx> { expr: &hir::Expr<'_>, span: Span, overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, - ) -> Expr<'tcx> { + ) -> Expr<'thir, 'tcx> { let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); let (def_id, substs, user_ty) = match overloaded_callee { Some((def_id, substs)) => (def_id, substs, None), @@ -799,13 +825,13 @@ impl<'tcx> Cx<'tcx> { } } - fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> Arm<'tcx> { + fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> Arm<'thir, 'tcx> { Arm { pattern: self.pattern_from_hir(&arm.pat), guard: arm.guard.as_ref().map(|g| match g { - hir::Guard::If(ref e) => Guard::If(self.mirror_expr_boxed(e)), + hir::Guard::If(ref e) => Guard::If(self.mirror_expr(e)), hir::Guard::IfLet(ref pat, ref e) => { - Guard::IfLet(self.pattern_from_hir(pat), self.mirror_expr_boxed(e)) + Guard::IfLet(self.pattern_from_hir(pat), self.mirror_expr(e)) } }), body: self.mirror_expr(arm.body), @@ -815,7 +841,11 @@ impl<'tcx> Cx<'tcx> { } } - fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> { + fn convert_path_expr( + &mut self, + expr: &'tcx hir::Expr<'tcx>, + res: Res, + ) -> ExprKind<'thir, 'tcx> { let substs = self.typeck_results().node_substs(expr.hir_id); match res { // A regular function, constructor function or a constant. @@ -883,7 +913,7 @@ impl<'tcx> Cx<'tcx> { variant_index: adt_def.variant_index_with_ctor_id(def_id), substs, user_ty: user_provided_type, - fields: vec![], + fields: self.arena.alloc_from_iter(iter::empty()), base: None, }, _ => bug!("unexpected ty: {:?}", ty), @@ -904,7 +934,9 @@ impl<'tcx> Cx<'tcx> { def_id: id, } }; - ExprKind::Deref { arg: Box::new(Expr { ty, temp_lifetime, span: expr.span, kind }) } + ExprKind::Deref { + arg: self.arena.alloc(Expr { ty, temp_lifetime, span: expr.span, kind }), + } } Res::Local(var_hir_id) => self.convert_var(var_hir_id), @@ -913,7 +945,7 @@ impl<'tcx> Cx<'tcx> { } } - fn convert_var(&mut self, var_hir_id: hir::HirId) -> ExprKind<'tcx> { + fn convert_var(&mut self, var_hir_id: hir::HirId) -> ExprKind<'thir, 'tcx> { // We want upvars here not captures. // Captures will be handled in MIR. let is_upvar = self @@ -936,9 +968,9 @@ impl<'tcx> Cx<'tcx> { fn overloaded_operator( &mut self, expr: &'tcx hir::Expr<'tcx>, - args: Vec>, - ) -> ExprKind<'tcx> { - let fun = Box::new(self.method_callee(expr, expr.span, None)); + args: &'thir [Expr<'thir, 'tcx>], + ) -> ExprKind<'thir, 'tcx> { + let fun = self.arena.alloc(self.method_callee(expr, expr.span, None)); ExprKind::Call { ty: fun.ty, fun, args, from_hir_call: false, fn_span: expr.span } } @@ -947,9 +979,9 @@ impl<'tcx> Cx<'tcx> { expr: &'tcx hir::Expr<'tcx>, place_ty: Ty<'tcx>, overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, - args: Vec>, + args: &'thir [Expr<'thir, 'tcx>], span: Span, - ) -> ExprKind<'tcx> { + ) -> ExprKind<'thir, 'tcx> { // For an overloaded *x or x[y] expression of type T, the method // call returns an &T and we must add the deref so that the types // line up (this is because `*x` and `x[y]` represent places): @@ -966,8 +998,8 @@ impl<'tcx> Cx<'tcx> { // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type let temp_lifetime = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); - let fun = Box::new(self.method_callee(expr, span, overloaded_callee)); - let ref_expr = Box::new(Expr { + let fun = self.arena.alloc(self.method_callee(expr, span, overloaded_callee)); + let ref_expr = self.arena.alloc(Expr { temp_lifetime, ty: ref_ty, span, @@ -983,7 +1015,7 @@ impl<'tcx> Cx<'tcx> { closure_expr: &'tcx hir::Expr<'tcx>, captured_place: &'tcx ty::CapturedPlace<'tcx>, upvar_ty: Ty<'tcx>, - ) -> Expr<'tcx> { + ) -> Expr<'thir, 'tcx> { let upvar_capture = captured_place.info.capture_kind; let temp_lifetime = self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); let var_ty = captured_place.place.base_ty; @@ -1007,12 +1039,14 @@ impl<'tcx> Cx<'tcx> { for proj in captured_place.place.projections.iter() { let kind = match proj.kind { - HirProjectionKind::Deref => ExprKind::Deref { arg: Box::new(captured_place_expr) }, + HirProjectionKind::Deref => { + ExprKind::Deref { arg: self.arena.alloc(captured_place_expr) } + } HirProjectionKind::Field(field, ..) => { // Variant index will always be 0, because for multi-variant // enums, we capture the enum entirely. ExprKind::Field { - lhs: Box::new(captured_place_expr), + lhs: self.arena.alloc(captured_place_expr), name: Field::new(field as usize), } } @@ -1038,21 +1072,21 @@ impl<'tcx> Cx<'tcx> { temp_lifetime, ty: upvar_ty, span: closure_expr.span, - kind: ExprKind::Borrow { borrow_kind, arg: Box::new(captured_place_expr) }, + kind: ExprKind::Borrow { + borrow_kind, + arg: self.arena.alloc(captured_place_expr), + }, } } } } /// Converts a list of named fields (i.e., for struct-like struct/enum ADTs) into FieldExpr. - fn field_refs(&mut self, fields: &'tcx [hir::Field<'tcx>]) -> Vec> { - fields - .iter() - .map(|field| FieldExpr { - name: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)), - expr: self.mirror_expr(field.expr), - }) - .collect() + fn field_refs(&mut self, fields: &'tcx [hir::Field<'tcx>]) -> &'thir [FieldExpr<'thir, 'tcx>] { + self.arena.alloc_from_iter(fields.iter().map(|field| FieldExpr { + name: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)), + expr: self.mirror_expr(field.expr), + })) } } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index c00e9ff8dd98e..66c11ea95286d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -2,6 +2,7 @@ //! structures into the THIR. The `builder` is generally ignorant of the tcx, //! etc., and instead goes through the `Cx` for most of its work. +use crate::thir::arena::Arena; use crate::thir::util::UserAnnotatedTyHelpers; use crate::thir::*; @@ -13,9 +14,18 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, Ty, TyCtxt}; -#[derive(Clone)] -crate struct Cx<'tcx> { +crate fn build_thir<'thir, 'tcx>( tcx: TyCtxt<'tcx>, + owner_def: ty::WithOptConstParam, + arena: &'thir Arena<'thir, 'tcx>, + expr: &'tcx hir::Expr<'tcx>, +) -> &'thir Expr<'thir, 'tcx> { + Cx::new(tcx, owner_def, &arena).mirror_expr(expr) +} + +struct Cx<'thir, 'tcx> { + tcx: TyCtxt<'tcx>, + arena: &'thir Arena<'thir, 'tcx>, crate param_env: ty::ParamEnv<'tcx>, @@ -26,20 +36,23 @@ crate struct Cx<'tcx> { body_owner: DefId, } -impl<'tcx> Cx<'tcx> { - crate fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam) -> Cx<'tcx> { +impl<'thir, 'tcx> Cx<'thir, 'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + def: ty::WithOptConstParam, + arena: &'thir Arena<'thir, 'tcx>, + ) -> Cx<'thir, 'tcx> { let typeck_results = tcx.typeck_opt_const_arg(def); Cx { tcx, + arena, param_env: tcx.param_env(def.did), region_scope_tree: tcx.region_scope_tree(def.did), typeck_results, body_owner: def.did.to_def_id(), } } -} -impl<'tcx> Cx<'tcx> { crate fn const_eval_literal( &mut self, lit: &'tcx ast::LitKind, @@ -74,7 +87,7 @@ impl<'tcx> Cx<'tcx> { } } -impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> { +impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs index 6e7094307b17d..27a7e99951c3b 100644 --- a/compiler/rustc_mir_build/src/thir/mod.rs +++ b/compiler/rustc_mir_build/src/thir/mod.rs @@ -24,6 +24,9 @@ crate mod pattern; crate use self::pattern::PatTyProj; crate use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange}; +mod arena; +crate use arena::Arena; + mod util; #[derive(Copy, Clone, Debug)] @@ -33,13 +36,13 @@ crate enum LintLevel { } #[derive(Debug)] -crate struct Block<'tcx> { +crate struct Block<'thir, 'tcx> { crate targeted_by_break: bool, crate region_scope: region::Scope, crate opt_destruction_scope: Option, crate span: Span, - crate stmts: Vec>, - crate expr: Option>>, + crate stmts: &'thir [Stmt<'thir, 'tcx>], + crate expr: Option<&'thir Expr<'thir, 'tcx>>, crate safety_mode: BlockSafety, } @@ -52,19 +55,19 @@ crate enum BlockSafety { } #[derive(Debug)] -crate struct Stmt<'tcx> { - crate kind: StmtKind<'tcx>, +crate struct Stmt<'thir, 'tcx> { + crate kind: StmtKind<'thir, 'tcx>, crate opt_destruction_scope: Option, } #[derive(Debug)] -crate enum StmtKind<'tcx> { +crate enum StmtKind<'thir, 'tcx> { Expr { /// scope for this statement; may be used as lifetime of temporaries scope: region::Scope, /// expression being evaluated in this statement - expr: Box>, + expr: &'thir Expr<'thir, 'tcx>, }, Let { @@ -82,7 +85,7 @@ crate enum StmtKind<'tcx> { pattern: Pat<'tcx>, /// let pat: ty = ... - initializer: Option>>, + initializer: Option<&'thir Expr<'thir, 'tcx>>, /// the lint level for this let-statement lint_level: LintLevel, @@ -91,12 +94,12 @@ crate enum StmtKind<'tcx> { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Expr<'_>, 160); +rustc_data_structures::static_assert_size!(Expr<'_, '_>, 144); /// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`) /// into instances of this `Expr` enum. This lowering can be done /// basically as lazily or as eagerly as desired: every recursive -/// reference to an expression in this enum is an `Box>`, which +/// reference to an expression in this enum is an `&'thir Expr<'thir, 'tcx>`, which /// may in turn be another instance of this enum (boxed), or else an /// unlowered `&'tcx H::Expr`. Note that instances of `Expr` are very /// short-lived. They are created by `Thir::to_expr`, analyzed and @@ -108,7 +111,7 @@ rustc_data_structures::static_assert_size!(Expr<'_>, 160); /// example, method calls and overloaded operators are absent: they are /// expected to be converted into `Expr::Call` instances. #[derive(Debug)] -crate struct Expr<'tcx> { +crate struct Expr<'thir, 'tcx> { /// type of this expression crate ty: Ty<'tcx>, @@ -120,28 +123,28 @@ crate struct Expr<'tcx> { crate span: Span, /// kind of expression - crate kind: ExprKind<'tcx>, + crate kind: ExprKind<'thir, 'tcx>, } #[derive(Debug)] -crate enum ExprKind<'tcx> { +crate enum ExprKind<'thir, 'tcx> { Scope { region_scope: region::Scope, lint_level: LintLevel, - value: Box>, + value: &'thir Expr<'thir, 'tcx>, }, Box { - value: Box>, + value: &'thir Expr<'thir, 'tcx>, }, If { - cond: Box>, - then: Box>, - else_opt: Option>>, + cond: &'thir Expr<'thir, 'tcx>, + then: &'thir Expr<'thir, 'tcx>, + else_opt: Option<&'thir Expr<'thir, 'tcx>>, }, Call { ty: Ty<'tcx>, - fun: Box>, - args: Vec>, + fun: &'thir Expr<'thir, 'tcx>, + args: &'thir [Expr<'thir, 'tcx>], /// Whether this is from a call in HIR, rather than from an overloaded /// operator. `true` for overloaded function call. from_hir_call: bool, @@ -150,62 +153,62 @@ crate enum ExprKind<'tcx> { fn_span: Span, }, Deref { - arg: Box>, + arg: &'thir Expr<'thir, 'tcx>, }, // NOT overloaded! Binary { op: BinOp, - lhs: Box>, - rhs: Box>, + lhs: &'thir Expr<'thir, 'tcx>, + rhs: &'thir Expr<'thir, 'tcx>, }, // NOT overloaded! LogicalOp { op: LogicalOp, - lhs: Box>, - rhs: Box>, + lhs: &'thir Expr<'thir, 'tcx>, + rhs: &'thir Expr<'thir, 'tcx>, }, // NOT overloaded! // LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands. Unary { op: UnOp, - arg: Box>, + arg: &'thir Expr<'thir, 'tcx>, }, // NOT overloaded! Cast { - source: Box>, + source: &'thir Expr<'thir, 'tcx>, }, Use { - source: Box>, + source: &'thir Expr<'thir, 'tcx>, }, // Use a lexpr to get a vexpr. NeverToAny { - source: Box>, + source: &'thir Expr<'thir, 'tcx>, }, Pointer { cast: PointerCast, - source: Box>, + source: &'thir Expr<'thir, 'tcx>, }, Loop { - body: Box>, + body: &'thir Expr<'thir, 'tcx>, }, Match { - scrutinee: Box>, - arms: Vec>, + scrutinee: &'thir Expr<'thir, 'tcx>, + arms: &'thir [Arm<'thir, 'tcx>], }, Block { - body: Block<'tcx>, + body: Block<'thir, 'tcx>, }, Assign { - lhs: Box>, - rhs: Box>, + lhs: &'thir Expr<'thir, 'tcx>, + rhs: &'thir Expr<'thir, 'tcx>, }, AssignOp { op: BinOp, - lhs: Box>, - rhs: Box>, + lhs: &'thir Expr<'thir, 'tcx>, + rhs: &'thir Expr<'thir, 'tcx>, }, Field { - lhs: Box>, + lhs: &'thir Expr<'thir, 'tcx>, name: Field, }, Index { - lhs: Box>, - index: Box>, + lhs: &'thir Expr<'thir, 'tcx>, + index: &'thir Expr<'thir, 'tcx>, }, VarRef { id: hir::HirId, @@ -220,35 +223,35 @@ crate enum ExprKind<'tcx> { }, Borrow { borrow_kind: BorrowKind, - arg: Box>, + arg: &'thir Expr<'thir, 'tcx>, }, /// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`. AddressOf { mutability: hir::Mutability, - arg: Box>, + arg: &'thir Expr<'thir, 'tcx>, }, Break { label: region::Scope, - value: Option>>, + value: Option<&'thir Expr<'thir, 'tcx>>, }, Continue { label: region::Scope, }, Return { - value: Option>>, + value: Option<&'thir Expr<'thir, 'tcx>>, }, ConstBlock { value: &'tcx Const<'tcx>, }, Repeat { - value: Box>, + value: &'thir Expr<'thir, 'tcx>, count: &'tcx Const<'tcx>, }, Array { - fields: Vec>, + fields: &'thir [Expr<'thir, 'tcx>], }, Tuple { - fields: Vec>, + fields: &'thir [Expr<'thir, 'tcx>], }, Adt { adt_def: &'tcx AdtDef, @@ -259,23 +262,23 @@ crate enum ExprKind<'tcx> { /// Bar:: { ... }`. user_ty: Option>>, - fields: Vec>, - base: Option>, + fields: &'thir [FieldExpr<'thir, 'tcx>], + base: Option>, }, PlaceTypeAscription { - source: Box>, + source: &'thir Expr<'thir, 'tcx>, /// Type that the user gave to this expression user_ty: Option>>, }, ValueTypeAscription { - source: Box>, + source: &'thir Expr<'thir, 'tcx>, /// Type that the user gave to this expression user_ty: Option>>, }, Closure { closure_id: DefId, substs: UpvarSubsts<'tcx>, - upvars: Vec>, + upvars: &'thir [Expr<'thir, 'tcx>], movability: Option, }, Literal { @@ -296,7 +299,7 @@ crate enum ExprKind<'tcx> { }, InlineAsm { template: &'tcx [InlineAsmTemplatePiece], - operands: Vec>, + operands: &'thir [InlineAsmOperand<'thir, 'tcx>], options: InlineAsmOptions, line_spans: &'tcx [Span], }, @@ -304,40 +307,40 @@ crate enum ExprKind<'tcx> { ThreadLocalRef(DefId), LlvmInlineAsm { asm: &'tcx hir::LlvmInlineAsmInner, - outputs: Vec>, - inputs: Vec>, + outputs: &'thir [Expr<'thir, 'tcx>], + inputs: &'thir [Expr<'thir, 'tcx>], }, Yield { - value: Box>, + value: &'thir Expr<'thir, 'tcx>, }, } #[derive(Debug)] -crate struct FieldExpr<'tcx> { +crate struct FieldExpr<'thir, 'tcx> { crate name: Field, - crate expr: Expr<'tcx>, + crate expr: &'thir Expr<'thir, 'tcx>, } #[derive(Debug)] -crate struct FruInfo<'tcx> { - crate base: Box>, - crate field_types: Vec>, +crate struct FruInfo<'thir, 'tcx> { + crate base: &'thir Expr<'thir, 'tcx>, + crate field_types: &'thir [Ty<'tcx>], } #[derive(Debug)] -crate struct Arm<'tcx> { +crate struct Arm<'thir, 'tcx> { crate pattern: Pat<'tcx>, - crate guard: Option>, - crate body: Expr<'tcx>, + crate guard: Option>, + crate body: &'thir Expr<'thir, 'tcx>, crate lint_level: LintLevel, crate scope: region::Scope, crate span: Span, } #[derive(Debug)] -crate enum Guard<'tcx> { - If(Box>), - IfLet(Pat<'tcx>, Box>), +crate enum Guard<'thir, 'tcx> { + If(&'thir Expr<'thir, 'tcx>), + IfLet(Pat<'tcx>, &'thir Expr<'thir, 'tcx>), } #[derive(Copy, Clone, Debug)] @@ -347,32 +350,32 @@ crate enum LogicalOp { } #[derive(Debug)] -crate enum InlineAsmOperand<'tcx> { +crate enum InlineAsmOperand<'thir, 'tcx> { In { reg: InlineAsmRegOrRegClass, - expr: Expr<'tcx>, + expr: &'thir Expr<'thir, 'tcx>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, - expr: Option>, + expr: Option<&'thir Expr<'thir, 'tcx>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, - expr: Expr<'tcx>, + expr: &'thir Expr<'thir, 'tcx>, }, SplitInOut { reg: InlineAsmRegOrRegClass, late: bool, - in_expr: Expr<'tcx>, - out_expr: Option>, + in_expr: &'thir Expr<'thir, 'tcx>, + out_expr: Option<&'thir Expr<'thir, 'tcx>>, }, Const { - expr: Expr<'tcx>, + expr: &'thir Expr<'thir, 'tcx>, }, SymFn { - expr: Expr<'tcx>, + expr: &'thir Expr<'thir, 'tcx>, }, SymStatic { def_id: DefId,