diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index e54fcaf6fc1b7..6f9ecb9cd21e0 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -111,7 +111,7 @@ impl Default for TypedArena { // alloc() will trigger a grow(). ptr: Cell::new(ptr::null_mut()), end: Cell::new(ptr::null_mut()), - chunks: RefCell::new(vec![]), + chunks: Default::default(), _own: PhantomData, } } @@ -325,13 +325,17 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena { unsafe impl Send for TypedArena {} +/// An arena that can hold objects of multiple different types that impl `Copy` +/// and/or satisfy `!mem::needs_drop`. pub struct DroplessArena { /// A pointer to the start of the free space. start: Cell<*mut u8>, /// A pointer to the end of free space. /// - /// The allocation proceeds from the end of the chunk towards the start. + /// The allocation proceeds downwards from the end of the chunk towards the + /// start. (This is slightly simpler and faster than allocating upwards, + /// see .) /// When this pointer crosses the start pointer, a new chunk is allocated. end: Cell<*mut u8>, @@ -516,10 +520,14 @@ impl DroplessArena { } } +// Declare an `Arena` containing one dropless arena and many typed arenas (the +// types of the typed arenas are specified by the arguments). The dropless +// arena will be used for any types that impl `Copy`, and also for any of the +// specified types that satisfy `!mem::needs_drop`. #[rustc_macro_transparency = "semitransparent"] -pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { +pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) { #[derive(Default)] - pub struct Arena<$tcx> { + pub struct Arena<'tcx> { pub dropless: $crate::DroplessArena, $($name: $crate::TypedArena<$ty>,)* } @@ -532,6 +540,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { ) -> &'a mut [Self]; } + // Any type that impls `Copy` can be arena-allocated in the `DroplessArena`. impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T { #[inline] fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self { @@ -544,12 +553,11 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { ) -> &'a mut [Self] { arena.dropless.alloc_from_iter(iter) } - } $( - impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty { + impl<'tcx> ArenaAllocatable<'tcx, $ty> for $ty { #[inline] - fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self { + fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self { if !::std::mem::needs_drop::() { arena.dropless.alloc(self) } else { @@ -559,7 +567,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { #[inline] fn allocate_from_iter<'a>( - arena: &'a Arena<$tcx>, + arena: &'a Arena<'tcx>, iter: impl ::std::iter::IntoIterator, ) -> &'a mut [Self] { if !::std::mem::needs_drop::() { @@ -577,6 +585,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { value.allocate_on(self) } + // Any type that impls `Copy` can have slices be arena-allocated in the `DroplessArena`. #[inline] pub fn alloc_slice(&self, value: &[T]) -> &mut [T] { if value.is_empty() { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 79464a7517217..cd468bcf4474e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -84,7 +84,7 @@ mod item; mod pat; mod path; -rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx); +rustc_hir::arena_types!(rustc_arena::declare_arena); struct LoweringContext<'a, 'hir: 'a> { /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 5091a7bccc55b..f19ca497d8bf2 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -1,52 +1,52 @@ -/// This declares a list of types which can be allocated by `Arena`. +/// This higher-order macro declares a list of types which can be allocated by `Arena`. /// /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`, /// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] macro_rules! arena_types { - ($macro:path, $tcx:lifetime) => ( + ($macro:path) => ( $macro!([ // HIR types - [] hir_krate: rustc_hir::Crate<$tcx>, - [] arm: rustc_hir::Arm<$tcx>, - [] asm_operand: (rustc_hir::InlineAsmOperand<$tcx>, Span), + [] hir_krate: rustc_hir::Crate<'tcx>, + [] arm: rustc_hir::Arm<'tcx>, + [] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, Span), [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, - [] block: rustc_hir::Block<$tcx>, - [] bare_fn_ty: rustc_hir::BareFnTy<$tcx>, - [] body: rustc_hir::Body<$tcx>, - [] generic_arg: rustc_hir::GenericArg<$tcx>, - [] generic_args: rustc_hir::GenericArgs<$tcx>, - [] generic_bound: rustc_hir::GenericBound<$tcx>, - [] generic_param: rustc_hir::GenericParam<$tcx>, - [] expr: rustc_hir::Expr<$tcx>, - [] expr_field: rustc_hir::ExprField<$tcx>, - [] pat_field: rustc_hir::PatField<$tcx>, - [] fn_decl: rustc_hir::FnDecl<$tcx>, - [] foreign_item: rustc_hir::ForeignItem<$tcx>, + [] block: rustc_hir::Block<'tcx>, + [] bare_fn_ty: rustc_hir::BareFnTy<'tcx>, + [] body: rustc_hir::Body<'tcx>, + [] generic_arg: rustc_hir::GenericArg<'tcx>, + [] generic_args: rustc_hir::GenericArgs<'tcx>, + [] generic_bound: rustc_hir::GenericBound<'tcx>, + [] generic_param: rustc_hir::GenericParam<'tcx>, + [] expr: rustc_hir::Expr<'tcx>, + [] expr_field: rustc_hir::ExprField<'tcx>, + [] pat_field: rustc_hir::PatField<'tcx>, + [] fn_decl: rustc_hir::FnDecl<'tcx>, + [] foreign_item: rustc_hir::ForeignItem<'tcx>, [] foreign_item_ref: rustc_hir::ForeignItemRef, - [] impl_item: rustc_hir::ImplItem<$tcx>, + [] impl_item: rustc_hir::ImplItem<'tcx>, [] impl_item_ref: rustc_hir::ImplItemRef, - [] item: rustc_hir::Item<$tcx>, - [] inline_asm: rustc_hir::InlineAsm<$tcx>, - [] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, - [] local: rustc_hir::Local<$tcx>, - [] mod_: rustc_hir::Mod<$tcx>, - [] owner_info: rustc_hir::OwnerInfo<$tcx>, - [] param: rustc_hir::Param<$tcx>, - [] pat: rustc_hir::Pat<$tcx>, - [] path: rustc_hir::Path<$tcx>, - [] path_segment: rustc_hir::PathSegment<$tcx>, - [] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>, - [] qpath: rustc_hir::QPath<$tcx>, - [] stmt: rustc_hir::Stmt<$tcx>, - [] field_def: rustc_hir::FieldDef<$tcx>, - [] trait_item: rustc_hir::TraitItem<$tcx>, + [] item: rustc_hir::Item<'tcx>, + [] inline_asm: rustc_hir::InlineAsm<'tcx>, + [] llvm_inline_asm: rustc_hir::LlvmInlineAsm<'tcx>, + [] local: rustc_hir::Local<'tcx>, + [] mod_: rustc_hir::Mod<'tcx>, + [] owner_info: rustc_hir::OwnerInfo<'tcx>, + [] param: rustc_hir::Param<'tcx>, + [] pat: rustc_hir::Pat<'tcx>, + [] path: rustc_hir::Path<'tcx>, + [] path_segment: rustc_hir::PathSegment<'tcx>, + [] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>, + [] qpath: rustc_hir::QPath<'tcx>, + [] stmt: rustc_hir::Stmt<'tcx>, + [] field_def: rustc_hir::FieldDef<'tcx>, + [] trait_item: rustc_hir::TraitItem<'tcx>, [] trait_item_ref: rustc_hir::TraitItemRef, - [] ty: rustc_hir::Ty<$tcx>, - [] type_binding: rustc_hir::TypeBinding<$tcx>, - [] variant: rustc_hir::Variant<$tcx>, - [] where_predicate: rustc_hir::WherePredicate<$tcx>, - ], $tcx); + [] ty: rustc_hir::Ty<'tcx>, + [] type_binding: rustc_hir::TypeBinding<'tcx>, + [] variant: rustc_hir::Variant<'tcx>, + [] where_predicate: rustc_hir::WherePredicate<'tcx>, + ]); ) } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 2bcc2a4f7cff7..ee2e190e7cd44 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -1,33 +1,33 @@ -/// This declares a list of types which can be allocated by `Arena`. +/// This higher-order macro declares a list of types which can be allocated by `Arena`. /// /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type /// listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] macro_rules! arena_types { - ($macro:path, $tcx:lifetime) => ( + ($macro:path) => ( $macro!([ [] layout: rustc_target::abi::Layout, - [] fn_abi: rustc_target::abi::call::FnAbi<$tcx, rustc_middle::ty::Ty<$tcx>>, + [] fn_abi: rustc_target::abi::call::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, // AdtDef are interned and compared by address [] adt_def: rustc_middle::ty::AdtDef, - [] steal_thir: rustc_data_structures::steal::Steal>, - [] steal_mir: rustc_data_structures::steal::Steal>, - [decode] mir: rustc_middle::mir::Body<$tcx>, + [] steal_thir: rustc_data_structures::steal::Steal>, + [] steal_mir: rustc_data_structures::steal::Steal>, + [decode] mir: rustc_middle::mir::Body<'tcx>, [] steal_promoted: rustc_data_structures::steal::Steal< rustc_index::vec::IndexVec< rustc_middle::mir::Promoted, - rustc_middle::mir::Body<$tcx> + rustc_middle::mir::Body<'tcx> > >, [decode] promoted: rustc_index::vec::IndexVec< rustc_middle::mir::Promoted, - rustc_middle::mir::Body<$tcx> + rustc_middle::mir::Body<'tcx> >, - [decode] typeck_results: rustc_middle::ty::TypeckResults<$tcx>, + [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, [decode] borrowck_result: - rustc_middle::mir::BorrowCheckResult<$tcx>, + rustc_middle::mir::BorrowCheckResult<'tcx>, [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, [decode] code_region: rustc_middle::mir::coverage::CodeRegion, [] const_allocs: rustc_middle::mir::interpret::Allocation, @@ -78,14 +78,14 @@ macro_rules! arena_types { [] foreign_modules: Vec, [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, - [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>, + [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>, [] attribute: rustc_ast::Attribute, [] name_set: rustc_data_structures::fx::FxHashSet, [] hir_id_set: rustc_hir::HirIdSet, // Interned types - [] tys: rustc_middle::ty::TyS<$tcx>, - [] predicates: rustc_middle::ty::PredicateInner<$tcx>, + [] tys: rustc_middle::ty::TyS<'tcx>, + [] predicates: rustc_middle::ty::PredicateInner<'tcx>, // Note that this deliberately duplicates items in the `rustc_hir::arena`, // since we need to allocate this type on both the `rustc_hir` arena @@ -97,8 +97,8 @@ macro_rules! arena_types { [decode] used_trait_imports: rustc_data_structures::fx::FxHashSet, [] dep_kind: rustc_middle::dep_graph::DepKindStruct, - ], $tcx); + ]); ) } -arena_types!(rustc_arena::declare_arena, 'tcx); +arena_types!(rustc_arena::declare_arena); diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 434008ecb1f4f..3f2b987b1e630 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -417,17 +417,17 @@ macro_rules! __impl_decoder_methods { macro_rules! impl_arena_allocatable_decoder { ([]$args:tt) => {}; ([decode $(, $attrs:ident)*] - [[$name:ident: $ty:ty], $tcx:lifetime]) => { - impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for $ty { + [$name:ident: $ty:ty]) => { + impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { #[inline] - fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> { + fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { decode_arena_allocable(decoder) } } - impl<$tcx, D: TyDecoder<$tcx>> RefDecodable<$tcx, D> for [$ty] { + impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] { #[inline] - fn decode(decoder: &mut D) -> Result<&$tcx Self, D::Error> { + fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { decode_arena_allocable_slice(decoder) } } @@ -438,15 +438,15 @@ macro_rules! impl_arena_allocatable_decoder { } macro_rules! impl_arena_allocatable_decoders { - ([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { + ([$($a:tt $name:ident: $ty:ty,)*]) => { $( - impl_arena_allocatable_decoder!($a [[$name: $ty], $tcx]); + impl_arena_allocatable_decoder!($a [$name: $ty]); )* } } -rustc_hir::arena_types!(impl_arena_allocatable_decoders, 'tcx); -arena_types!(impl_arena_allocatable_decoders, 'tcx); +rustc_hir::arena_types!(impl_arena_allocatable_decoders); +arena_types!(impl_arena_allocatable_decoders); #[macro_export] macro_rules! implement_ty_decoder {