Excessive rustc memory usage and compile time
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
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
rustcprocesses compete for memory simultaneously.
Questions
- Are there known coding patterns in
bitflags!-generated code that contribute disproportionately to memory usage and should be avoided? - Are there ongoing or planned efforts to reduce
rustcmemory consumption for workloads involving large numbers of types and trait implementations? - 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?
- Are there alternative approaches, compiler flags, or code-generation patterns that could mitigate this issue?
Expected outcome
rustcmemory 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Cargo.toml and src/lib.rs reproducer, varying the number of generated bitflags types and recording rustc memory and compile time. Use the listed profiling consumers, including rustc_resolve::Module::for_each_child, rustc_middle::dep_graph::CurrentDepGraph::record_edge, and rustc_arena::DroplessArena::grow, to identify where scaling occurs. Done means characterizing the cause and either demonstrating a substantial reduction or documenting a concrete mitigation or guidance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100