diff --git a/crates/proc-macro-api/src/pool.rs b/crates/proc-macro-api/src/pool.rs index 0cb505aa40..a637bc0e48 100644 --- a/crates/proc-macro-api/src/pool.rs +++ b/crates/proc-macro-api/src/pool.rs @@ -28,14 +28,26 @@ impl ProcMacroServerPool { } pub(crate) fn pick_process(&self) -> Result<&ProcMacroServerProcess, ServerError> { - self.workers - .iter() - .filter(|w| w.exited().is_none()) - .min_by_key(|w| w.number_of_active_req()) - .ok_or_else(|| ServerError { - message: "all proc-macro server workers have exited".into(), - io: None, - }) + let mut best: Option<&ProcMacroServerProcess> = None; + let mut best_load = u32::MAX; + + for w in self.workers.iter().filter(|w| w.exited().is_none()) { + let load = w.number_of_active_req(); + + if load == 0 { + return Ok(w); + } + + if load < best_load { + best = Some(w); + best_load = load; + } + } + + best.ok_or_else(|| ServerError { + message: "all proc-macro server workers have exited".into(), + io: None, + }) } pub(crate) fn load_dylib( diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index cb6552c32f..409f2468a7 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -380,7 +380,7 @@ config_data! { /// The number of worker threads in the main loop. The default `null` means to pick /// automatically. numThreads: Option = None, - /// The number of proc-macro-srv processes + /// The number of proc-macro-srv processes proc_macro_processes: NumProcesses = NumProcesses::Concrete(1), /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.