Skip to content

Commit d9c6cb3

Browse files
committed
Stop using higher-order macros to declare arenas
1 parent 08cb62d commit d9c6cb3

5 files changed

Lines changed: 172 additions & 161 deletions

File tree

compiler/rustc_arena/src/lib.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -598,21 +598,32 @@ impl DroplessArena {
598598
}
599599
}
600600

601-
/// Declare an `Arena` containing one dropless arena and many typed arenas (the
602-
/// types of the typed arenas are specified by the arguments).
601+
/// Declares an `Arena` that can allocate values of a variety of `Copy`, `needs_drop` and
602+
/// `!needs_drop` types.
603603
///
604-
/// There are three cases of interest.
605-
/// - Types that are `Copy`: these need not be specified in the arguments. They
606-
/// will use the `DroplessArena`.
607-
/// - Types that are `!Copy` and `!Drop`: these must be specified in the
608-
/// arguments. An empty `TypedArena` will be created for each one, but the
609-
/// `DroplessArena` will always be used and the `TypedArena` will stay empty.
610-
/// This is odd but harmless, because an empty arena allocates no memory.
611-
/// - Types that are `!Copy` and `Drop`: these must be specified in the
612-
/// arguments. The `TypedArena` will be used for them.
604+
/// The declared arena actually contains a single [`DroplessArena`], plus a separate
605+
/// [`TypedArena`] for each of the types listed in the body of the macro invocation.
613606
///
607+
/// Any type that is `Copy` can be allocated in the arena without needing to be listed
608+
/// explicitly. Those values will be stored in the [`DroplessArena`].
609+
///
610+
/// Types that are `!Copy` can only be allocated if they are listed in the macro invocation.
611+
/// For types that are `!Copy + needs_drop`, values will be stored in the corresponding
612+
/// [`TypedArena`] and will be dropped when the arena is dropped.
613+
///
614+
/// As an optimization, types that are `!Copy + !needs_drop` will actually be stored in the
615+
/// [`DroplessArena`], and the corresponding [`TypedArena`] will remain empty. This makes
616+
/// better use of the dropless arena's storage blocks, while the overhead of having a few
617+
/// unused typed-arenas is negligible.
614618
#[rustc_macro_transparency = "semiopaque"]
615-
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
619+
pub macro declare_arena(
620+
// Each of these entries becomes a `$name: TypedArena<$ty>` field in the arena.
621+
// This allows values of non-copy type $ty to be allocated in the arena.
622+
// The field names must be distinct, but have no further significance.
623+
$(
624+
$name:ident: $ty:ty,
625+
)*
626+
) {
616627
#[derive(Default)]
617628
pub struct Arena<'tcx> {
618629
pub dropless: $crate::DroplessArena,

compiler/rustc_hir/src/arena.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
2-
/// Note that all `Copy` types can be allocated by default and need not be specified here.
3-
#[macro_export]
4-
macro_rules! arena_types {
5-
($macro:path) => (
6-
$macro!([
7-
// HIR types
8-
[] asm_template: rustc_ast::InlineAsmTemplatePiece,
9-
[] attribute: crate::Attribute,
10-
[] owner_info: crate::OwnerInfo<'tcx>,
11-
[] macro_def: rustc_ast::MacroDef,
12-
[] delegation_info: crate::DelegationInfo,
13-
]);
14-
)
1+
//! Declares an arena that can allocate values of any `Copy` type, and of
2+
//! any `!Copy` type listed below.
3+
4+
rustc_arena::declare_arena! {
5+
// HIR types
6+
asm_template: rustc_ast::InlineAsmTemplatePiece,
7+
attribute: crate::Attribute,
8+
owner_info: crate::OwnerInfo<'tcx>,
9+
macro_def: rustc_ast::MacroDef,
10+
delegation_info: crate::DelegationInfo,
1511
}

compiler/rustc_hir/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ pub use rustc_span::def_id;
4242
pub use stability::*;
4343
pub use target::{MethodKind, Target};
4444

45-
arena_types!(rustc_arena::declare_arena);
45+
pub use crate::arena::Arena;

compiler/rustc_middle/src/arena.rs

Lines changed: 135 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,141 @@
1+
//! Declares [`rustc_middle::arena::Arena`], which can allocate values of any
2+
//! `Copy` type, and any `!Copy` type explicitly listed below.
3+
14
use rustc_serialize::Decodable;
25

3-
use crate::ty::Ty;
46
use crate::ty::codec::{RefDecodable, TyDecoder};
7+
use crate::ty::{Ty, TyCtxt};
58

6-
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
7-
///
8-
/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type
9-
/// listed. See the `impl_arena_allocatable_decoder!` macro for more.
10-
#[macro_export]
11-
macro_rules! arena_types {
12-
($macro:path) => (
13-
$macro!([
14-
[] layout: rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx>,
15-
[] proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>,
16-
[] fn_abi: rustc_target::callconv::FnAbi<'tcx, rustc_middle::ty::Ty<'tcx>>,
17-
[] adt_def: rustc_middle::ty::AdtDefData,
18-
[] steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
19-
[] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
20-
[] mir: rustc_middle::mir::Body<'tcx>,
21-
[] steal_promoted:
22-
rustc_data_structures::steal::Steal<
23-
rustc_index::IndexVec<
24-
rustc_middle::mir::Promoted,
25-
rustc_middle::mir::Body<'tcx>
26-
>
27-
>,
28-
[] promoted:
29-
rustc_index::IndexVec<
30-
rustc_middle::mir::Promoted,
31-
rustc_middle::mir::Body<'tcx>
32-
>,
33-
[] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
34-
[] borrowck_result: rustc_data_structures::fx::FxIndexMap<
35-
rustc_hir::def_id::LocalDefId,
36-
rustc_middle::ty::DefinitionSiteHiddenType<'tcx>,
37-
>,
38-
[] resolver: rustc_data_structures::steal::Steal<rustc_middle::ty::ResolverAstLowering<'tcx>>,
39-
[] index_ast: rustc_index::IndexVec<
40-
rustc_span::def_id::LocalDefId,
41-
rustc_data_structures::steal::Steal<(
42-
std::sync::Arc<rustc_middle::ty::ResolverAstLowering<'tcx>>,
43-
rustc_ast::AstOwner
44-
)>
45-
>,
46-
[] crate_alone: rustc_data_structures::steal::Steal<rustc_ast::Crate>,
47-
[] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
48-
[] resolutions: rustc_middle::ty::ResolverGlobalCtxt,
49-
[] const_allocs: rustc_middle::mir::interpret::Allocation,
50-
[] region_scope_tree: rustc_middle::middle::region::ScopeTree,
51-
// Required for the incremental on-disk cache
52-
[] mir_keys: rustc_hir::def_id::DefIdSet,
53-
[] dropck_outlives:
54-
rustc_middle::infer::canonical::Canonical<'tcx,
55-
rustc_middle::infer::canonical::QueryResponse<'tcx,
56-
rustc_middle::traits::query::DropckOutlivesResult<'tcx>
57-
>
58-
>,
59-
[] normalize_canonicalized_projection:
60-
rustc_middle::infer::canonical::Canonical<'tcx,
61-
rustc_middle::infer::canonical::QueryResponse<'tcx,
62-
rustc_middle::traits::query::NormalizationResult<'tcx>
63-
>
64-
>,
65-
[] implied_outlives_bounds:
66-
rustc_middle::infer::canonical::Canonical<'tcx,
67-
rustc_middle::infer::canonical::QueryResponse<'tcx,
68-
Vec<rustc_middle::traits::query::OutlivesBound<'tcx>>
69-
>
70-
>,
71-
[] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>,
72-
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
73-
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
74-
[] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
75-
[] type_op_subtype:
76-
rustc_middle::infer::canonical::Canonical<'tcx,
77-
rustc_middle::infer::canonical::QueryResponse<'tcx, ()>
78-
>,
79-
[] type_op_normalize_poly_fn_sig:
80-
rustc_middle::infer::canonical::Canonical<'tcx,
81-
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>>
82-
>,
83-
[] type_op_normalize_fn_sig:
84-
rustc_middle::infer::canonical::Canonical<'tcx,
85-
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>>
86-
>,
87-
[] type_op_normalize_clause:
88-
rustc_middle::infer::canonical::Canonical<'tcx,
89-
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Clause<'tcx>>
90-
>,
91-
[] type_op_normalize_ty:
92-
rustc_middle::infer::canonical::Canonical<'tcx,
93-
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>>
94-
>,
95-
[] inspect_probe: rustc_middle::traits::solve::inspect::Probe<rustc_middle::ty::TyCtxt<'tcx>>,
96-
[] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities,
97-
[] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
98-
[] dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation,
99-
[] codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>,
100-
[] attribute: rustc_hir::Attribute,
101-
[] name_set: rustc_data_structures::unord::UnordSet<rustc_span::Symbol>,
102-
[] autodiff_item: rustc_hir::attrs::AutoDiffItem,
103-
[] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::Symbol>,
104-
[] stable_order_of_exportable_impls:
105-
rustc_data_structures::fx::FxIndexMap<rustc_hir::def_id::DefId, usize>,
9+
// If a type `T` supported by the arena also needs to support decoding into `&'tcx T`
10+
// backed by an arena allocation (via `RefDecodable`), add it to the list in
11+
// `impl_ref_decodable_into_arena!`.
10612

107-
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
108-
// since we need to allocate this type on both the `rustc_hir` arena
109-
// (during lowering) and the `rustc_middle` arena (for decoding MIR)
110-
[] asm_template: rustc_ast::InlineAsmTemplatePiece,
111-
[] used_trait_imports: rustc_data_structures::unord::UnordSet<rustc_hir::def_id::LocalDefId>,
112-
[] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::ItemLocalId>,
113-
[] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,
13+
rustc_arena::declare_arena! {
14+
layout: rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx>,
15+
proxy_coroutine_layout: rustc_middle::mir::CoroutineLayout<'tcx>,
16+
fn_abi: rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>,
17+
adt_def: rustc_middle::ty::AdtDefData,
18+
steal_thir: rustc_data_structures::steal::Steal<rustc_middle::thir::Thir<'tcx>>,
19+
steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<'tcx>>,
20+
mir: rustc_middle::mir::Body<'tcx>,
21+
steal_promoted:
22+
rustc_data_structures::steal::Steal<
23+
rustc_index::IndexVec<
24+
rustc_middle::mir::Promoted,
25+
rustc_middle::mir::Body<'tcx>
26+
>
27+
>,
28+
promoted:
29+
rustc_index::IndexVec<
30+
rustc_middle::mir::Promoted,
31+
rustc_middle::mir::Body<'tcx>
32+
>,
33+
typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
34+
borrowck_result:
35+
rustc_data_structures::fx::FxIndexMap<
36+
rustc_hir::def_id::LocalDefId,
37+
rustc_middle::ty::DefinitionSiteHiddenType<'tcx>,
38+
>,
39+
resolver: rustc_data_structures::steal::Steal<rustc_middle::ty::ResolverAstLowering<'tcx>>,
40+
index_ast:
41+
rustc_index::IndexVec<
42+
rustc_span::def_id::LocalDefId,
43+
rustc_data_structures::steal::Steal<(
44+
std::sync::Arc<rustc_middle::ty::ResolverAstLowering<'tcx>>,
45+
rustc_ast::AstOwner
46+
)>
47+
>,
48+
crate_alone: rustc_data_structures::steal::Steal<rustc_ast::Crate>,
49+
crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
50+
resolutions: rustc_middle::ty::ResolverGlobalCtxt,
51+
const_allocs: rustc_middle::mir::interpret::Allocation,
52+
region_scope_tree: rustc_middle::middle::region::ScopeTree,
53+
// Required for the incremental on-disk cache
54+
mir_keys: rustc_hir::def_id::DefIdSet,
55+
dropck_outlives:
56+
rustc_middle::infer::canonical::Canonical<'tcx,
57+
rustc_middle::infer::canonical::QueryResponse<'tcx,
58+
rustc_middle::traits::query::DropckOutlivesResult<'tcx>
59+
>
60+
>,
61+
normalize_canonicalized_projection:
62+
rustc_middle::infer::canonical::Canonical<'tcx,
63+
rustc_middle::infer::canonical::QueryResponse<'tcx,
64+
rustc_middle::traits::query::NormalizationResult<'tcx>
65+
>
66+
>,
67+
implied_outlives_bounds:
68+
rustc_middle::infer::canonical::Canonical<'tcx,
69+
rustc_middle::infer::canonical::QueryResponse<'tcx,
70+
Vec<rustc_middle::traits::query::OutlivesBound<'tcx>>
71+
>
72+
>,
73+
dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>,
74+
candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
75+
autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
76+
query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
77+
type_op_subtype:
78+
rustc_middle::infer::canonical::Canonical<'tcx,
79+
rustc_middle::infer::canonical::QueryResponse<'tcx, ()>
80+
>,
81+
type_op_normalize_poly_fn_sig:
82+
rustc_middle::infer::canonical::Canonical<'tcx,
83+
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>>
84+
>,
85+
type_op_normalize_fn_sig:
86+
rustc_middle::infer::canonical::Canonical<'tcx,
87+
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>>
88+
>,
89+
type_op_normalize_clause:
90+
rustc_middle::infer::canonical::Canonical<'tcx,
91+
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Clause<'tcx>>
92+
>,
93+
type_op_normalize_ty:
94+
rustc_middle::infer::canonical::Canonical<'tcx,
95+
rustc_middle::infer::canonical::QueryResponse<'tcx, Ty<'tcx>>
96+
>,
97+
inspect_probe: rustc_middle::traits::solve::inspect::Probe<TyCtxt<'tcx>>,
98+
effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities,
99+
upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
100+
dyn_compatibility_violations: rustc_middle::traits::DynCompatibilityViolation,
101+
codegen_unit: rustc_middle::mono::CodegenUnit<'tcx>,
102+
attribute: rustc_hir::Attribute,
103+
name_set: rustc_data_structures::unord::UnordSet<rustc_span::Symbol>,
104+
autodiff_item: rustc_hir::attrs::AutoDiffItem,
105+
ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::Symbol>,
106+
stable_order_of_exportable_impls:
107+
rustc_data_structures::fx::FxIndexMap<rustc_hir::def_id::DefId, usize>,
114108

115-
[] dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>,
109+
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
110+
// since we need to allocate this type on both the `rustc_hir` arena
111+
// (during lowering) and the `rustc_middle` arena (for decoding MIR)
112+
asm_template: rustc_ast::InlineAsmTemplatePiece,
113+
used_trait_imports: rustc_data_structures::unord::UnordSet<rustc_hir::def_id::LocalDefId>,
114+
is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::ItemLocalId>,
115+
impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,
116116

117-
[] trait_impl_trait_tys:
118-
rustc_data_structures::unord::UnordMap<
119-
rustc_hir::def_id::DefId,
120-
rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
121-
>,
122-
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>,
123-
[] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
124-
[] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem,
125-
[] mod_child: rustc_middle::metadata::ModChild,
126-
[] features: rustc_feature::Features,
127-
[] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
128-
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
129-
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
130-
[] token_stream: rustc_ast::tokenstream::TokenStream,
131-
[] maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>,
132-
[] owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>,
133-
[] parenting: rustc_hir::def_id::LocalDefIdMap<rustc_hir::ItemLocalId>,
134-
[] trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>,
135-
[] delayed_lints: rustc_data_structures::steal::Steal<rustc_hir::lints::DelayedLints>,
136-
]);
137-
)
138-
}
117+
dep_kind_vtable: rustc_middle::dep_graph::DepKindVTable<'tcx>,
139118

140-
arena_types!(rustc_arena::declare_arena);
119+
trait_impl_trait_tys:
120+
rustc_data_structures::unord::UnordMap<
121+
rustc_hir::def_id::DefId,
122+
rustc_middle::ty::EarlyBinder<'tcx, Ty<'tcx>>
123+
>,
124+
external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<TyCtxt<'tcx>>,
125+
doc_link_resolutions: rustc_hir::def::DocLinkResMap,
126+
stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem,
127+
mod_child: rustc_middle::metadata::ModChild,
128+
features: rustc_feature::Features,
129+
specialization_graph: rustc_middle::traits::specialization_graph::Graph,
130+
crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
131+
hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
132+
token_stream: rustc_ast::tokenstream::TokenStream,
133+
maybe_owner: rustc_middle::hir::ProjectedMaybeOwner<'tcx>,
134+
owner_info: rustc_middle::hir::ProjectedOwnerInfo<'tcx>,
135+
parenting: rustc_hir::def_id::LocalDefIdMap<rustc_hir::ItemLocalId>,
136+
trait_candidates: rustc_hir::ItemLocalMap<&'tcx [rustc_hir::TraitCandidate<'tcx>]>,
137+
delayed_lints: rustc_data_structures::steal::Steal<rustc_hir::lints::DelayedLints>,
138+
}
141139

142140
#[inline]
143141
fn decode_arena_allocatable<'tcx, D, C, T>(decoder: &mut D) -> &'tcx T
@@ -159,8 +157,6 @@ where
159157
decoder.interner().arena.alloc_from_iter(values)
160158
}
161159

162-
/// Implements [`RefDecodable`] for `T` (and `[T]`), by decoding to `T` and
163-
/// then moving the value or values into an arena allocation.
164160
macro_rules! impl_ref_decodable_into_arena {
165161
(
166162
$(
@@ -185,6 +181,11 @@ macro_rules! impl_ref_decodable_into_arena {
185181
}
186182
}
187183

184+
// For each of these types, implements `RefDecodable` for `T` (and `[T]`) by
185+
// decoding to `T` and then moving the value or values into an arena allocation.
186+
//
187+
// Types in this list must be `ArenaAllocatable`, either because they are `Copy`
188+
// or because they are listed in the `declare_arena!` invocation.
188189
impl_ref_decodable_into_arena! {
189190
// tidy-alphabetical-start
190191
(rustc_middle::middle::exported_symbols::ExportedSymbol<'tcx>, rustc_middle::middle::exported_symbols::SymbolExportInfo),

compiler/rustc_middle/src/ty/codec.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate
9494
///
9595
/// `Decodable` can still be implemented in cases where `Decodable` is required
9696
/// by a trait bound.
97+
///
98+
/// Implementations of this trait will typically allocate into an arena or interner,
99+
/// e.g. see `impl_ref_decodable_into_arena!`.
97100
pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>>: PointeeSized {
98101
fn decode(d: &mut D) -> &'tcx Self;
99102
}

0 commit comments

Comments
 (0)