From a67aa12d6e70d56e904a67f46531637f14250e42 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 26 Jul 2026 17:58:42 +1000 Subject: [PATCH 1/4] Use an explicit list of types for `RefDecodable` into arena This is a little more verbose than using a `[decode]` modifier, but will allow us to stop using higher-order macros when declaring arenas. --- compiler/rustc_middle/src/arena.rs | 86 +++++++++++++++++++++++---- compiler/rustc_middle/src/ty/codec.rs | 49 --------------- 2 files changed, 76 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 87e19fafc0e22..90ae9963b33a0 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -1,3 +1,8 @@ +use rustc_serialize::Decodable; + +use crate::ty::Ty; +use crate::ty::codec::{RefDecodable, TyDecoder}; + /// 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 @@ -12,7 +17,7 @@ macro_rules! arena_types { [] adt_def: rustc_middle::ty::AdtDefData, [] steal_thir: rustc_data_structures::steal::Steal>, [] steal_mir: rustc_data_structures::steal::Steal>, - [decode] mir: rustc_middle::mir::Body<'tcx>, + [] mir: rustc_middle::mir::Body<'tcx>, [] steal_promoted: rustc_data_structures::steal::Steal< rustc_index::IndexVec< @@ -20,12 +25,12 @@ macro_rules! arena_types { rustc_middle::mir::Body<'tcx> > >, - [decode] promoted: + [] promoted: rustc_index::IndexVec< rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> >, - [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, + [] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, [] borrowck_result: rustc_data_structures::fx::FxIndexMap< rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, @@ -92,7 +97,7 @@ macro_rules! arena_types { [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, [] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, [] codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>, - [decode] attribute: rustc_hir::Attribute, + [] attribute: rustc_hir::Attribute, [] name_set: rustc_data_structures::unord::UnordSet, [] autodiff_item: rustc_hir::attrs::AutoDiffItem, [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, @@ -102,14 +107,14 @@ macro_rules! arena_types { // Note that this deliberately duplicates items in the `rustc_hir::arena`, // since we need to allocate this type on both the `rustc_hir` arena // (during lowering) and the `rustc_middle` arena (for decoding MIR) - [decode] asm_template: rustc_ast::InlineAsmTemplatePiece, - [decode] used_trait_imports: rustc_data_structures::unord::UnordSet, + [] asm_template: rustc_ast::InlineAsmTemplatePiece, + [] used_trait_imports: rustc_data_structures::unord::UnordSet, [] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, - [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, + [] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, [] dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>, - [decode] trait_impl_trait_tys: + [] trait_impl_trait_tys: rustc_data_structures::unord::UnordMap< rustc_hir::def_id::DefId, rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>> @@ -119,10 +124,10 @@ macro_rules! arena_types { [] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, [] mod_child: rustc_middle::metadata::ModChild, [] features: rustc_feature::Features, - [decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph, + [] specialization_graph: rustc_middle::traits::specialization_graph::Graph, [] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, [] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, - [decode] token_stream: rustc_ast::tokenstream::TokenStream, + [] token_stream: rustc_ast::tokenstream::TokenStream, [] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>, [] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>, [] parenting: rustc_hir::def_id::LocalDefIdMap, @@ -133,3 +138,64 @@ macro_rules! arena_types { } arena_types!(rustc_arena::declare_arena); + +#[inline] +fn decode_arena_allocatable<'tcx, D, T>(decoder: &mut D) -> &'tcx T +where + D: TyDecoder<'tcx>, + T: ArenaAllocatable<'tcx> + Decodable, +{ + let value: T = Decodable::decode(decoder); + decoder.interner().arena.alloc(value) +} + +#[inline] +fn decode_arena_allocatable_slice<'tcx, D, T>(decoder: &mut D) -> &'tcx [T] +where + D: TyDecoder<'tcx>, + T: ArenaAllocatable<'tcx> + Decodable, +{ + let values: Vec = Decodable::decode(decoder); + decoder.interner().arena.alloc_from_iter(values) +} + +/// Implements [`RefDecodable`] for `T` (and `[T]`), by decoding to `T` and +/// then moving the value or values into an arena allocation. +macro_rules! impl_ref_decodable_into_arena { + ( + $( + $ty:ty, + )* + ) => { + $( + impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { + #[inline] + fn decode(decoder: &mut D) -> &'tcx Self { + decode_arena_allocatable(decoder) + } + } + + impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] { + #[inline] + fn decode(decoder: &mut D) -> &'tcx Self { + decode_arena_allocatable_slice(decoder) + } + } + )* + } +} + +impl_ref_decodable_into_arena! { + // tidy-alphabetical-start + rustc_ast::InlineAsmTemplatePiece, + rustc_ast::tokenstream::TokenStream, + rustc_data_structures::unord::UnordMap>>, + rustc_data_structures::unord::UnordSet, + rustc_hir::Attribute, + rustc_index::IndexVec>, + rustc_middle::mir::Body<'tcx>, + rustc_middle::traits::ImplSource<'tcx, ()>, + rustc_middle::traits::specialization_graph::Graph, + rustc_middle::ty::TypeckResults<'tcx>, + // tidy-alphabetical-end +} diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 5f76467ed7db2..a58d972f0e528 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -17,7 +17,6 @@ use rustc_middle::ty::Const; use rustc_serialize::{Decodable, Encodable}; use rustc_span::{Span, SpanDecoder, SpanEncoder, Spanned}; -use crate::arena::ArenaAllocatable; use crate::infer::canonical::{CanonicalVarKind, CanonicalVarKinds}; use crate::mir::interpret::{AllocId, ConstAllocation, CtfeProvenance}; use crate::mono::MonoItem; @@ -206,24 +205,6 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable for ty::ParamEnv<'tcx> { } } -#[inline] -fn decode_arena_allocable<'tcx, D: TyDecoder<'tcx>, T: ArenaAllocatable<'tcx> + Decodable>( - decoder: &mut D, -) -> &'tcx T { - decoder.interner().arena.alloc(Decodable::decode(decoder)) -} - -#[inline] -fn decode_arena_allocable_slice< - 'tcx, - D: TyDecoder<'tcx>, - T: ArenaAllocatable<'tcx> + Decodable, ->( - decoder: &mut D, -) -> &'tcx [T] { - decoder.interner().arena.alloc_from_iter( as Decodable>::decode(decoder)) -} - impl<'tcx, D: TyDecoder<'tcx>> Decodable for Ty<'tcx> { #[allow(rustc::usage_of_ty_tykind)] fn decode(decoder: &mut D) -> Ty<'tcx> { @@ -500,36 +481,6 @@ macro_rules! __impl_decoder_methods { } } -macro_rules! impl_arena_allocatable_decoder { - ([] $name:ident: $ty:ty) => {}; - ([decode] $name:ident: $ty:ty) => { - impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { - #[inline] - fn decode(decoder: &mut D) -> &'tcx Self { - decode_arena_allocable(decoder) - } - } - - impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] { - #[inline] - fn decode(decoder: &mut D) -> &'tcx Self { - decode_arena_allocable_slice(decoder) - } - } - }; -} - -macro_rules! impl_arena_allocatable_decoders { - ([$($a:tt $name:ident: $ty:ty,)*]) => { - $( - impl_arena_allocatable_decoder!($a $name: $ty); - )* - } -} - -rustc_hir::arena_types!(impl_arena_allocatable_decoders); -arena_types!(impl_arena_allocatable_decoders); - macro_rules! impl_arena_copy_decoder { (<$tcx:tt> $($ty:ty,)*) => { $(impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { From 08cb62dd570fcf44f85de43be917b8ac8db6c196 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 26 Jul 2026 18:03:49 +1000 Subject: [PATCH 2/4] Use the same list for `RefDecodable` of Copy types --- compiler/rustc_middle/src/arena.rs | 15 ++++++++++---- compiler/rustc_middle/src/ty/codec.rs | 28 --------------------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 90ae9963b33a0..035aa3d5deed9 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -140,20 +140,20 @@ macro_rules! arena_types { arena_types!(rustc_arena::declare_arena); #[inline] -fn decode_arena_allocatable<'tcx, D, T>(decoder: &mut D) -> &'tcx T +fn decode_arena_allocatable<'tcx, D, C, T>(decoder: &mut D) -> &'tcx T where D: TyDecoder<'tcx>, - T: ArenaAllocatable<'tcx> + Decodable, + T: ArenaAllocatable<'tcx, C> + Decodable, { let value: T = Decodable::decode(decoder); decoder.interner().arena.alloc(value) } #[inline] -fn decode_arena_allocatable_slice<'tcx, D, T>(decoder: &mut D) -> &'tcx [T] +fn decode_arena_allocatable_slice<'tcx, D, C, T>(decoder: &mut D) -> &'tcx [T] where D: TyDecoder<'tcx>, - T: ArenaAllocatable<'tcx> + Decodable, + T: ArenaAllocatable<'tcx, C> + Decodable, { let values: Vec = Decodable::decode(decoder); decoder.interner().arena.alloc_from_iter(values) @@ -187,15 +187,22 @@ macro_rules! impl_ref_decodable_into_arena { impl_ref_decodable_into_arena! { // tidy-alphabetical-start + (rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo), rustc_ast::InlineAsmTemplatePiece, rustc_ast::tokenstream::TokenStream, rustc_data_structures::unord::UnordMap>>, rustc_data_structures::unord::UnordSet, rustc_hir::Attribute, rustc_index::IndexVec>, + rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs, rustc_middle::mir::Body<'tcx>, rustc_middle::traits::ImplSource<'tcx, ()>, rustc_middle::traits::specialization_graph::Graph, rustc_middle::ty::TypeckResults<'tcx>, + rustc_middle::ty::Variance, + rustc_span::Ident, + rustc_span::Span, + rustc_span::def_id::DefId, + rustc_span::def_id::LocalDefId, // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index a58d972f0e528..0b2a1c55cfcf5 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -481,34 +481,6 @@ macro_rules! __impl_decoder_methods { } } -macro_rules! impl_arena_copy_decoder { - (<$tcx:tt> $($ty:ty,)*) => { - $(impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty { - #[inline] - fn decode(decoder: &mut D) -> &'tcx Self { - decoder.interner().arena.alloc(Decodable::decode(decoder)) - } - } - - impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] { - #[inline] - fn decode(decoder: &mut D) -> &'tcx Self { - decoder.interner().arena.alloc_from_iter( as Decodable>::decode(decoder)) - } - })* - }; -} - -impl_arena_copy_decoder! {<'tcx> - Span, - rustc_span::Ident, - ty::Variance, - rustc_span::def_id::DefId, - rustc_span::def_id::LocalDefId, - (rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo), - rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs, -} - #[macro_export] macro_rules! implement_ty_decoder { ($DecoderName:ident <$($typaram:tt),*>) => { From b0b25c9775b9183d82a4d66fff8be6949a008937 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 26 Jul 2026 18:08:07 +1000 Subject: [PATCH 3/4] Stop using higher-order macros to declare arenas --- compiler/rustc_arena/src/lib.rs | 35 ++-- compiler/rustc_hir/src/arena.rs | 24 +-- compiler/rustc_hir/src/lib.rs | 2 +- compiler/rustc_middle/src/arena.rs | 269 +++++++++++++------------- compiler/rustc_middle/src/ty/codec.rs | 3 + 5 files changed, 172 insertions(+), 161 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index a4248a82bce73..d75f23eedd26c 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -598,21 +598,32 @@ impl DroplessArena { } } -/// Declare an `Arena` containing one dropless arena and many typed arenas (the -/// types of the typed arenas are specified by the arguments). +/// Declares an `Arena` that can allocate values of a variety of `Copy`, `needs_drop` and +/// `!needs_drop` types. /// -/// There are three cases of interest. -/// - Types that are `Copy`: these need not be specified in the arguments. They -/// will use the `DroplessArena`. -/// - Types that are `!Copy` and `!Drop`: these must be specified in the -/// arguments. An empty `TypedArena` will be created for each one, but the -/// `DroplessArena` will always be used and the `TypedArena` will stay empty. -/// This is odd but harmless, because an empty arena allocates no memory. -/// - Types that are `!Copy` and `Drop`: these must be specified in the -/// arguments. The `TypedArena` will be used for them. +/// The declared arena actually contains a single [`DroplessArena`], plus a separate +/// [`TypedArena`] for each of the types listed in the body of the macro invocation. /// +/// Any type that is `Copy` can be allocated in the arena without needing to be listed +/// explicitly. Those values will be stored in the [`DroplessArena`]. +/// +/// Types that are `!Copy` can only be allocated if they are listed in the macro invocation. +/// For types that are `!Copy + needs_drop`, values will be stored in the corresponding +/// [`TypedArena`] and will be dropped when the arena is dropped. +/// +/// As an optimization, types that are `!Copy + !needs_drop` will actually be stored in the +/// [`DroplessArena`], and the corresponding [`TypedArena`] will remain empty. This makes +/// better use of the dropless arena's storage blocks, while the overhead of having a few +/// unused typed-arenas is negligible. #[rustc_macro_transparency = "semiopaque"] -pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) { +pub macro declare_arena( + // Each of these entries becomes a `$name: TypedArena<$ty>` field in the arena. + // This allows values of non-copy type $ty to be allocated in the arena. + // The field names must be distinct, but have no further significance. + $( + [] $name:ident: $ty:ty, + )* +) { #[derive(Default)] pub struct Arena<'tcx> { pub dropless: $crate::DroplessArena, diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index b4b9db5d93f48..8ccd2c9320216 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -1,15 +1,11 @@ -/// This higher-order macro declares a list of types which can be allocated by `Arena`. -/// Note that all `Copy` types can be allocated by default and need not be specified here. -#[macro_export] -macro_rules! arena_types { - ($macro:path) => ( - $macro!([ - // HIR types - [] asm_template: rustc_ast::InlineAsmTemplatePiece, - [] attribute: crate::Attribute, - [] owner_info: crate::OwnerInfo<'tcx>, - [] macro_def: rustc_ast::MacroDef, - [] delegation_info: crate::DelegationInfo, - ]); - ) +//! Declares an arena that can allocate values of any `Copy` type, and of +//! any `!Copy` type listed below. + +rustc_arena::declare_arena! { + // HIR types + [] asm_template: rustc_ast::InlineAsmTemplatePiece, + [] attribute: crate::Attribute, + [] owner_info: crate::OwnerInfo<'tcx>, + [] macro_def: rustc_ast::MacroDef, + [] delegation_info: crate::DelegationInfo, } diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 37aa024be6278..761fc680d2ff6 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -42,4 +42,4 @@ pub use rustc_span::def_id; pub use stability::*; pub use target::{MethodKind, Target}; -arena_types!(rustc_arena::declare_arena); +pub use crate::arena::Arena; diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 035aa3d5deed9..5449bfe214b0b 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -1,143 +1,141 @@ +//! Declares [`rustc_middle::arena::Arena`], which can allocate values of any +//! `Copy` type, and any `!Copy` type explicitly listed below. + use rustc_serialize::Decodable; -use crate::ty::Ty; use crate::ty::codec::{RefDecodable, TyDecoder}; +use crate::ty::{Ty, TyCtxt}; -/// 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. See the `impl_arena_allocatable_decoder!` macro for more. -#[macro_export] -macro_rules! arena_types { - ($macro:path) => ( - $macro!([ - [] layout: rustc_abi::LayoutData, - [] proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>, - [] fn_abi: rustc_target::callconv::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>, - [] adt_def: rustc_middle::ty::AdtDefData, - [] steal_thir: rustc_data_structures::steal::Steal>, - [] steal_mir: rustc_data_structures::steal::Steal>, - [] mir: rustc_middle::mir::Body<'tcx>, - [] steal_promoted: - rustc_data_structures::steal::Steal< - rustc_index::IndexVec< - rustc_middle::mir::Promoted, - rustc_middle::mir::Body<'tcx> - > - >, - [] promoted: - rustc_index::IndexVec< - rustc_middle::mir::Promoted, - rustc_middle::mir::Body<'tcx> - >, - [] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [] borrowck_result: rustc_data_structures::fx::FxIndexMap< - rustc_hir::def_id::LocalDefId, - rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, - >, - [] resolver: rustc_data_structures::steal::Steal>, - [] index_ast: rustc_index::IndexVec< - rustc_span::def_id::LocalDefId, - rustc_data_structures::steal::Steal<( - std::sync::Arc>, - rustc_ast::AstOwner - )> - >, - [] crate_alone: rustc_data_structures::steal::Steal, - [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, - [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, - [] const_allocs: rustc_middle::mir::interpret::Allocation, - [] region_scope_tree: rustc_middle::middle::region::ScopeTree, - // Required for the incremental on-disk cache - [] mir_keys: rustc_hir::def_id::DefIdSet, - [] dropck_outlives: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, - rustc_middle::traits::query::DropckOutlivesResult<'tcx> - > - >, - [] normalize_canonicalized_projection: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, - rustc_middle::traits::query::NormalizationResult<'tcx> - > - >, - [] implied_outlives_bounds: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, - Vec> - > - >, - [] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, - [] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, - [] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, - [] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>, - [] type_op_subtype: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, ()> - >, - [] type_op_normalize_poly_fn_sig: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>> - >, - [] type_op_normalize_fn_sig: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>> - >, - [] type_op_normalize_clause: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Clause<'tcx>> - >, - [] type_op_normalize_ty: - rustc_middle::infer::canonical::Canonical<'tcx, - rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> - >, - [] inspect_probe: rustc_middle::traits::solve::inspect::Probe>, - [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, - [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, - [] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, - [] codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>, - [] attribute: rustc_hir::Attribute, - [] name_set: rustc_data_structures::unord::UnordSet, - [] autodiff_item: rustc_hir::attrs::AutoDiffItem, - [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, - [] stable_order_of_exportable_impls: - rustc_data_structures::fx::FxIndexMap, +// If a type `T` supported by the arena also needs to support decoding into `&'tcx T` +// backed by an arena allocation (via `RefDecodable`), add it to the list in +// `impl_ref_decodable_into_arena!`. - // Note that this deliberately duplicates items in the `rustc_hir::arena`, - // since we need to allocate this type on both the `rustc_hir` arena - // (during lowering) and the `rustc_middle` arena (for decoding MIR) - [] asm_template: rustc_ast::InlineAsmTemplatePiece, - [] used_trait_imports: rustc_data_structures::unord::UnordSet, - [] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, - [] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, +rustc_arena::declare_arena! { + [] layout: rustc_abi::LayoutData, + [] proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>, + [] fn_abi: rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, + [] adt_def: rustc_middle::ty::AdtDefData, + [] steal_thir: rustc_data_structures::steal::Steal>, + [] steal_mir: rustc_data_structures::steal::Steal>, + [] mir: rustc_middle::mir::Body<'tcx>, + [] steal_promoted: + rustc_data_structures::steal::Steal< + rustc_index::IndexVec< + rustc_middle::mir::Promoted, + rustc_middle::mir::Body<'tcx> + > + >, + [] promoted: + rustc_index::IndexVec< + rustc_middle::mir::Promoted, + rustc_middle::mir::Body<'tcx> + >, + [] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, + [] borrowck_result: + rustc_data_structures::fx::FxIndexMap< + rustc_hir::def_id::LocalDefId, + rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, + >, + [] resolver: rustc_data_structures::steal::Steal>, + [] index_ast: + rustc_index::IndexVec< + rustc_span::def_id::LocalDefId, + rustc_data_structures::steal::Steal<( + std::sync::Arc>, + rustc_ast::AstOwner + )> + >, + [] crate_alone: rustc_data_structures::steal::Steal, + [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, + [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, + [] const_allocs: rustc_middle::mir::interpret::Allocation, + [] region_scope_tree: rustc_middle::middle::region::ScopeTree, + // Required for the incremental on-disk cache + [] mir_keys: rustc_hir::def_id::DefIdSet, + [] dropck_outlives: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, + rustc_middle::traits::query::DropckOutlivesResult<'tcx> + > + >, + [] normalize_canonicalized_projection: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, + rustc_middle::traits::query::NormalizationResult<'tcx> + > + >, + [] implied_outlives_bounds: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, + Vec> + > + >, + [] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, + [] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, + [] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, + [] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>, + [] type_op_subtype: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, ()> + >, + [] type_op_normalize_poly_fn_sig: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>> + >, + [] type_op_normalize_fn_sig: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>> + >, + [] type_op_normalize_clause: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Clause<'tcx>> + >, + [] type_op_normalize_ty: + rustc_middle::infer::canonical::Canonical<'tcx, + rustc_middle::infer::canonical::QueryResponse<'tcx, Ty<'tcx>> + >, + [] inspect_probe: rustc_middle::traits::solve::inspect::Probe>, + [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, + [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, + [] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, + [] codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>, + [] attribute: rustc_hir::Attribute, + [] name_set: rustc_data_structures::unord::UnordSet, + [] autodiff_item: rustc_hir::attrs::AutoDiffItem, + [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, + [] stable_order_of_exportable_impls: + rustc_data_structures::fx::FxIndexMap, - [] dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'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 + // (during lowering) and the `rustc_middle` arena (for decoding MIR) + [] asm_template: rustc_ast::InlineAsmTemplatePiece, + [] used_trait_imports: rustc_data_structures::unord::UnordSet, + [] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, + [] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, - [] trait_impl_trait_tys: - rustc_data_structures::unord::UnordMap< - rustc_hir::def_id::DefId, - rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>> - >, - [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, - [] doc_link_resolutions: rustc_hir::def::DocLinkResMap, - [] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, - [] mod_child: rustc_middle::metadata::ModChild, - [] features: rustc_feature::Features, - [] specialization_graph: rustc_middle::traits::specialization_graph::Graph, - [] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, - [] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, - [] token_stream: rustc_ast::tokenstream::TokenStream, - [] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>, - [] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>, - [] parenting: rustc_hir::def_id::LocalDefIdMap, - [] trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>, - [] delayed_lints: rustc_data_structures::steal::Steal, - ]); - ) -} + [] dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>, -arena_types!(rustc_arena::declare_arena); + [] trait_impl_trait_tys: + rustc_data_structures::unord::UnordMap< + rustc_hir::def_id::DefId, + rustc_middle::ty::EarlyBinder<'tcx, Ty<'tcx>> + >, + [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, + [] doc_link_resolutions: rustc_hir::def::DocLinkResMap, + [] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, + [] mod_child: rustc_middle::metadata::ModChild, + [] features: rustc_feature::Features, + [] specialization_graph: rustc_middle::traits::specialization_graph::Graph, + [] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, + [] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, + [] token_stream: rustc_ast::tokenstream::TokenStream, + [] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>, + [] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>, + [] parenting: rustc_hir::def_id::LocalDefIdMap, + [] trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>, + [] delayed_lints: rustc_data_structures::steal::Steal, +} #[inline] fn decode_arena_allocatable<'tcx, D, C, T>(decoder: &mut D) -> &'tcx T @@ -159,8 +157,6 @@ where decoder.interner().arena.alloc_from_iter(values) } -/// Implements [`RefDecodable`] for `T` (and `[T]`), by decoding to `T` and -/// then moving the value or values into an arena allocation. macro_rules! impl_ref_decodable_into_arena { ( $( @@ -185,6 +181,11 @@ macro_rules! impl_ref_decodable_into_arena { } } +// For each of these types, implements `RefDecodable` for `T` (and `[T]`) by +// decoding to `T` and then moving the value or values into an arena allocation. +// +// Types in this list must be `ArenaAllocatable`, either because they are `Copy` +// or because they are listed in the `declare_arena!` invocation. impl_ref_decodable_into_arena! { // tidy-alphabetical-start (rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo), diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 0b2a1c55cfcf5..33047bf3e67b4 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -94,6 +94,9 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate /// /// `Decodable` can still be implemented in cases where `Decodable` is required /// by a trait bound. +/// +/// Implementations of this trait will typically allocate into an arena or interner, +/// e.g. see `impl_ref_decodable_into_arena!`. pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>>: PointeeSized { fn decode(d: &mut D) -> &'tcx Self; } From 01cef43abdc6876586fb903d1dcee27f32edade8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 29 Jul 2026 17:39:27 +1000 Subject: [PATCH 4/4] Remove the `[]` prefix from `declare_arena!` entries --- compiler/rustc_arena/src/lib.rs | 2 +- compiler/rustc_hir/src/arena.rs | 10 +-- compiler/rustc_middle/src/arena.rs | 122 ++++++++++++++--------------- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index d75f23eedd26c..3e9012f2d3871 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -621,7 +621,7 @@ pub macro declare_arena( // This allows values of non-copy type $ty to be allocated in the arena. // The field names must be distinct, but have no further significance. $( - [] $name:ident: $ty:ty, + $name:ident: $ty:ty, )* ) { #[derive(Default)] diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 8ccd2c9320216..6b99f21353e22 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -3,9 +3,9 @@ rustc_arena::declare_arena! { // HIR types - [] asm_template: rustc_ast::InlineAsmTemplatePiece, - [] attribute: crate::Attribute, - [] owner_info: crate::OwnerInfo<'tcx>, - [] macro_def: rustc_ast::MacroDef, - [] delegation_info: crate::DelegationInfo, + asm_template: rustc_ast::InlineAsmTemplatePiece, + attribute: crate::Attribute, + owner_info: crate::OwnerInfo<'tcx>, + macro_def: rustc_ast::MacroDef, + delegation_info: crate::DelegationInfo, } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 5449bfe214b0b..ef943d70c3ecf 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -11,33 +11,33 @@ use crate::ty::{Ty, TyCtxt}; // `impl_ref_decodable_into_arena!`. rustc_arena::declare_arena! { - [] layout: rustc_abi::LayoutData, - [] proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>, - [] fn_abi: rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, - [] adt_def: rustc_middle::ty::AdtDefData, - [] steal_thir: rustc_data_structures::steal::Steal>, - [] steal_mir: rustc_data_structures::steal::Steal>, - [] mir: rustc_middle::mir::Body<'tcx>, - [] steal_promoted: + layout: rustc_abi::LayoutData, + proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>, + fn_abi: rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, + adt_def: rustc_middle::ty::AdtDefData, + steal_thir: rustc_data_structures::steal::Steal>, + steal_mir: rustc_data_structures::steal::Steal>, + mir: rustc_middle::mir::Body<'tcx>, + steal_promoted: rustc_data_structures::steal::Steal< rustc_index::IndexVec< rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> > >, - [] promoted: + promoted: rustc_index::IndexVec< rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> >, - [] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [] borrowck_result: + typeck_results: rustc_middle::ty::TypeckResults<'tcx>, + borrowck_result: rustc_data_structures::fx::FxIndexMap< rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - [] resolver: rustc_data_structures::steal::Steal>, - [] index_ast: + resolver: rustc_data_structures::steal::Steal>, + index_ast: rustc_index::IndexVec< rustc_span::def_id::LocalDefId, rustc_data_structures::steal::Steal<( @@ -45,96 +45,96 @@ rustc_arena::declare_arena! { rustc_ast::AstOwner )> >, - [] crate_alone: rustc_data_structures::steal::Steal, - [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, - [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, - [] const_allocs: rustc_middle::mir::interpret::Allocation, - [] region_scope_tree: rustc_middle::middle::region::ScopeTree, + crate_alone: rustc_data_structures::steal::Steal, + crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, + resolutions: rustc_middle::ty::ResolverGlobalCtxt, + const_allocs: rustc_middle::mir::interpret::Allocation, + region_scope_tree: rustc_middle::middle::region::ScopeTree, // Required for the incremental on-disk cache - [] mir_keys: rustc_hir::def_id::DefIdSet, - [] dropck_outlives: + mir_keys: rustc_hir::def_id::DefIdSet, + dropck_outlives: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::traits::query::DropckOutlivesResult<'tcx> > >, - [] normalize_canonicalized_projection: + normalize_canonicalized_projection: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::traits::query::NormalizationResult<'tcx> > >, - [] implied_outlives_bounds: + implied_outlives_bounds: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, Vec> > >, - [] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, - [] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, - [] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, - [] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>, - [] type_op_subtype: + dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, + candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, + autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, + query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>, + type_op_subtype: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, ()> >, - [] type_op_normalize_poly_fn_sig: + type_op_normalize_poly_fn_sig: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>> >, - [] type_op_normalize_fn_sig: + type_op_normalize_fn_sig: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>> >, - [] type_op_normalize_clause: + type_op_normalize_clause: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Clause<'tcx>> >, - [] type_op_normalize_ty: + type_op_normalize_ty: rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, Ty<'tcx>> >, - [] inspect_probe: rustc_middle::traits::solve::inspect::Probe>, - [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, - [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, - [] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, - [] codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>, - [] attribute: rustc_hir::Attribute, - [] name_set: rustc_data_structures::unord::UnordSet, - [] autodiff_item: rustc_hir::attrs::AutoDiffItem, - [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, - [] stable_order_of_exportable_impls: + inspect_probe: rustc_middle::traits::solve::inspect::Probe>, + effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, + upvars_mentioned: rustc_data_structures::fx::FxIndexMap, + dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation, + codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>, + attribute: rustc_hir::Attribute, + name_set: rustc_data_structures::unord::UnordSet, + autodiff_item: rustc_hir::attrs::AutoDiffItem, + ordered_name_set: rustc_data_structures::fx::FxIndexSet, + stable_order_of_exportable_impls: rustc_data_structures::fx::FxIndexMap, // Note that this deliberately duplicates items in the `rustc_hir::arena`, // since we need to allocate this type on both the `rustc_hir` arena // (during lowering) and the `rustc_middle` arena (for decoding MIR) - [] asm_template: rustc_ast::InlineAsmTemplatePiece, - [] used_trait_imports: rustc_data_structures::unord::UnordSet, - [] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, - [] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, + asm_template: rustc_ast::InlineAsmTemplatePiece, + used_trait_imports: rustc_data_structures::unord::UnordSet, + is_late_bound_map: rustc_data_structures::fx::FxIndexSet, + impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, - [] dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>, + dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>, - [] trait_impl_trait_tys: + trait_impl_trait_tys: rustc_data_structures::unord::UnordMap< rustc_hir::def_id::DefId, rustc_middle::ty::EarlyBinder<'tcx, Ty<'tcx>> >, - [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, - [] doc_link_resolutions: rustc_hir::def::DocLinkResMap, - [] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, - [] mod_child: rustc_middle::metadata::ModChild, - [] features: rustc_feature::Features, - [] specialization_graph: rustc_middle::traits::specialization_graph::Graph, - [] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, - [] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, - [] token_stream: rustc_ast::tokenstream::TokenStream, - [] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>, - [] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>, - [] parenting: rustc_hir::def_id::LocalDefIdMap, - [] trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>, - [] delayed_lints: rustc_data_structures::steal::Steal, + external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, + doc_link_resolutions: rustc_hir::def::DocLinkResMap, + stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, + mod_child: rustc_middle::metadata::ModChild, + features: rustc_feature::Features, + specialization_graph: rustc_middle::traits::specialization_graph::Graph, + crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, + hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, + token_stream: rustc_ast::tokenstream::TokenStream, + maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>, + owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>, + parenting: rustc_hir::def_id::LocalDefIdMap, + trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>, + delayed_lints: rustc_data_structures::steal::Steal, } #[inline]