What are Arenas used for in rust_ast_lowering?

On compiler/rust_ast_lowering/lib.rs, it uses a macro to create lots of TypedArena<T>s for each AST type (I guess):

rustc_hir::arena_types!(rustc_arena::declare_arena, [], 'tcx);

My Intellij dea expands this macro to:

pub struct Arena<'tcx> {
    pub dropless: ::rustc_arena::DroplessArena,
    drop: ::rustc_arena::DropArena,
    hir_krate:,
    arm:,
    asm_operand:,
    asm_template:,
    attribute:,
   //...

but some types are missing. I believe they are the TypedArena type from rustc_arena/lib.rs

so for example, the attribute struct member should be attribute: TypedArena<rustc_ast::Attribute>.

Anyways, in the process of lowering things, for example when lowering a function declaration to its hir representation:

fn lower_fn_decl(
    &mut self,
    decl: &FnDecl,
    mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
    impl_trait_return_allow: bool,
    make_ret_async: Option<NodeId>,
) -> &'hir hir::FnDecl<'hir> {

it does this:

        this.arena.alloc_from_iter(inputs.iter().map(|param| {
            if let Some((_, ibty)) = &mut in_band_ty_params {
                this.lower_ty_direct(
                    &param.ty,
                    ImplTraitContext::Universal(ibty, this.current_hir_id_owner.0),
                )
            } else {
                this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
            }
        }))

so it just calls alloc_from_iter on the Arena defined from the macro. This just allocates the type inside the arena in the proper member for the type from inputs.

The question is: why use an arena? Why do I need to register the lowered type and the types used during the lowering function into an arena? After it's lowered, I don't need these things anymore.

I know very little about AST, lowering, etc so please give me context on what is happening. I'm just trying to learn so in the future I can contribute to Rust.

The main reason is that everyone now deals in &'tcx Thing<'tcx>. It doesn't matter when the types are materialized, because they're put into the arena, they all have the same lifetime 'tcx. Plus, the compiler can allocate a large blob of space early on, and then deallocate it later as a single blob (or re-use it for a later pass).

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.