Skip to content

Excessive rustc memory usage and compile time #157764

@imre-kis-arm

Description

@imre-kis-arm

Summary

When a crate defines a large number of bitflags! types, rustc memory consumption and compilation time grow approximately linearly with the number of generated types. The growth is large enough to make real-world scenarios hit practical memory limits.

The issue appears to be primarily related to the number of generated trait implementations, as the bitflags! macro generates implementations for several traits (such as Add, Sub, BitOr, etc.) for the type.

Reproducer

Cargo.toml

[package]
name = "rustc-mem-measure"
version = "0.1.0"
edition = "2024"

[dependencies]
bitflags = "2.13.0"

src/lib.rs

use bitflags::bitflags;

macro_rules! create_bitflags_instance {
    ($name:ident) => {
        bitflags! {
            pub struct $name: u64 {
                const BIT0  = 1 << 0;
                const BIT1  = 1 << 1;
                const BIT2  = 1 << 2;
                const BIT3  = 1 << 3;
                const BIT4  = 1 << 4;
                const BIT5  = 1 << 5;
                const BIT6  = 1 << 6;
                const BIT7  = 1 << 7;
            }
        }
    };
}

create_bitflags_instance!(Type0);
create_bitflags_instance!(Type1);
create_bitflags_instance!(Type2);
create_bitflags_instance!(Type3);
create_bitflags_instance!(Type4);
create_bitflags_instance!(Type5);
create_bitflags_instance!(Type6);
create_bitflags_instance!(Type7);
create_bitflags_instance!(Type8);
create_bitflags_instance!(Type9);
// ...

Note that the create_bitflags_instance! macro is only used to simplify the example. Replacing it with manually written type definitions has only a minimal effect on resource consumption.

Observed scaling

Type count Memory usage (MB) Time (s)
1 33.3 0.2
10 63.2 1.0
100 393.5 9.7
1000 4391.5 104.6

Memory usage and compile time both scale approximately linearly with the number of generated bitflags! types.

Toolchain

The measurements were collected using a custom debug-built toolchain (dc375db7d8df0aa450e622c529147c95eee756f5). However, similar behavior is observed across multiple toolchain versions, including Rust 1.80 through the latest stable available at the time of writing (1.96.0 (30a34c682 2026-05-25)).

Profiling information

Using the debug-built toolchain, the largest memory consumers observed in the rustc process were:

MB % of useful heap Consumer
797.7 18.16% 2,714 places below Massif threshold
502.4 11.44% rustc_resolve::Module::for_each_child / Resolver::finalize_imports
438.5 9.99% rustc_arena::DroplessArena::grow
386.6 8.80% rustc_middle::dep_graph::CurrentDepGraph::record_edge
367.7 8.37% indexmap::Core<rustc_span::SpanData, ()>::insert_full

Real-world impact

This issue was discovered while developing the Arm system register crate: arm-sysregs The crate generates types and accessors for Armv8-A system registers. Currently only about 25% of the registers are covered, yet builds are already approaching CI memory limits (~3 GB).

The current scaling is therefore problematic because:

  • Memory requirements continue to grow as more registers are added. When the crate is complete, the extrapolated memory usage of rustc will be ~12GB.
  • Downstream projects compiling the crate inherit the cost.
  • Parallel builds amplify the problem because multiple rustc processes compete for memory simultaneously.

Questions

  1. Are there known coding patterns in bitflags!-generated code that contribute disproportionately to memory usage and should be avoided?
  2. Are there ongoing or planned efforts to reduce rustc memory consumption for workloads involving large numbers of types and trait implementations?
  3. The profiling results suggest significant memory usage in dependency graph tracking and related compiler infrastructure. Would it be feasible to introduce more cache-like behavior where less frequently used entries can be discarded and recomputed when necessary, rather than retaining all information for the duration of compilation?
  4. Are there alternative approaches, compiler flags, or code-generation patterns that could mitigate this issue?

Expected outcome

  • rustc memory usage for this pattern could be reduced substantially, or
  • Guidance could be provided on which language/library patterns are responsible for the scaling and how generated code can be structured to avoid them.

Any suggestions for investigation or mitigation would be greatly appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-compilememIssue: Problems and improvements with respect to memory usage during compilation.I-compiletimeIssue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions