rust-lang / rust-lang/rust-analyzer
Using `proc-macro` in `build.rs` causes high cpu usage
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.9k
- Forks
- 2.2k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 72
Description
The rust-analyzer cannot handle big structs with proc-macros, in this case serde's derive macro, in build.rs properly. By adding more fields to a struct, it spins up CPU usage to 100% almost exponentially.
Steps:
- Write the following mentioned code in
build.rs - Rerun the editor
- After finishing the first run compilation, try to edit the code
- You will notice that the
rust-analyzeruses 100% of a single core CPU usage for a long time and the LSP functionality will be blocked
NOTE 1: More fields, much longer wait time. For a struct with 200 fields, it goes into an almost infinite loop.
NOTE 2: It's just bound to build.rs and it works fine in lib.rs.
rust-analyzer version: rust-analyzer 1.87.0-nightly (9fb94b3 2025-03-10)
rustc version: rustc 1.87.0-nightly (9fb94b32d 2025-03-10)
editor or extension: neovim
relevant settings: enabled procMacro and buildScript features.
rust-analyzer command: cargo clippy --message-format=json --all-targets --all-features
repository link (if public, optional): N/A
code snippet to reproduce:
// Cargo.toml
[package]
name = "test_script"
version = "0.1.0"
edition = "2024"
[build-dependencies]
serde = { version = "1.0.219", features = ["derive"] }
// build.rs
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Translations {
pub af: Option<String>,
pub am: Option<String>,
pub ar: Option<String>,
pub az: Option<String>,
pub be: Option<String>,
pub bg: Option<String>,
pub bn: Option<String>,
pub ca: Option<String>,
pub cs: Option<String>,
pub da: Option<String>,
pub de: Option<String>,
pub el: Option<String>,
pub en: Option<String>,
pub es: Option<String>,
pub et: Option<String>,
pub eu: Option<String>,
pub fa: Option<String>,
pub fi: Option<String>,
pub fr: Option<String>,
pub gl: Option<String>,
pub gu: Option<String>,
pub he: Option<String>,
pub hi: Option<String>,
pub hr: Option<String>,
pub hu: Option<String>,
pub hy: Option<String>,
pub id: Option<String>,
pub is: Option<String>,
pub it: Option<String>,
pub ja: Option<String>,
pub ka: Option<String>,
pub kn: Option<String>,
pub ko: Option<String>,
pub lt: Option<String>,
pub lv: Option<String>,
pub ml: Option<String>,
pub mn: Option<String>,
pub mr: Option<String>,
pub ms: Option<String>,
pub nb: Option<String>,
pub nl: Option<String>,
pub pl: Option<String>,
pub ps: Option<String>,
pub pt: Option<String>,
pub ro: Option<String>,
pub ru: Option<String>,
pub si: Option<String>,
pub sk: Option<String>,
pub sl: Option<String>,
pub sr: Option<String>,
pub sv: Option<String>,
pub sw: Option<String>,
pub ta: Option<String>,
pub te: Option<String>,
pub th: Option<String>,
pub tk: Option<String>,
pub tr: Option<String>,
pub uk: Option<String>,
pub ur: Option<String>,
pub vi: Option<String>,
pub zh: Option<String>,
pub cy: Option<String>,
pub ceb: Option<String>,
pub sr_latn: Option<String>,
pub yue_hans: Option<String>,
pub jv: Option<String>,
pub sq: Option<String>,
pub ccp: Option<String>,
pub ga: Option<String>,
pub ky: Option<String>,
pub pa: Option<String>,
pub kk: Option<String>,
pub yue: Option<String>,
pub yo: Option<String>,
pub uz: Option<String>,
pub bs: Option<String>,
pub mk: Option<String>,
pub ne: Option<String>,
pub no: Option<String>,
pub yo_bj: Option<String>,
pub my: Option<String>,
pub sd: Option<String>,
pub ha: Option<String>,
pub ha_ne: Option<String>,
pub or: Option<String>,
pub tm: Option<String>,
pub so: Option<String>,
pub km: Option<String>,
pub zu: Option<String>,
pub as_: Option<String>,
pub lo: Option<String>,
pub ig: Option<String>,
pub tl: Option<String>,
pub de_ch: Option<String>,
pub la: Option<String>,
pub fil: Option<String>,
pub zh_hant: Option<String>,
pub sc: Option<String>,
pub dv: Option<String>,
pub os: Option<String>,
pub oc: Option<String>,
pub br: Option<String>,
pub lb: Option<String>,
pub ast: Option<String>,
}
fn main() {}
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
Reproduce the report with the supplied Cargo.toml and build.rs, then compare the same struct in lib.rs while procMacro and buildScript are enabled. Trace the rust-analyzer build-script and proc-macro path; done when the large struct no longer causes prolonged single-core saturation and LSP functionality remains responsive.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100