Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 607375d

Browse files
committed
Load proc-macros asynchronously
1 parent e9fb2ff commit 607375d

File tree

10 files changed

+154
-88
lines changed

10 files changed

+154
-88
lines changed

crates/base-db/src/input.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
77
//! actual IO is done and lowered to input.
88
9-
use std::{fmt, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
9+
use std::{fmt, mem, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
1010

1111
use cfg::CfgOptions;
1212
use rustc_hash::FxHashMap;
1313
use stdx::hash::{NoHashHashMap, NoHashHashSet};
1414
use syntax::SmolStr;
1515
use tt::token_id::Subtree;
16-
use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath};
16+
use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath};
1717

18+
pub type ProcMacroPaths = FxHashMap<CrateId, Result<(Option<String>, AbsPathBuf), String>>;
1819
pub type ProcMacros = FxHashMap<CrateId, ProcMacroLoadResult>;
1920

2021
/// Files are grouped into source roots. A source root is a directory on the
@@ -455,16 +456,11 @@ impl CrateGraph {
455456
}
456457

457458
/// Extends this crate graph by adding a complete disjoint second crate
458-
/// graph.
459+
/// graph and adjust the ids in the [`ProcMacroPaths`] accordingly.
459460
///
460461
/// The ids of the crates in the `other` graph are shifted by the return
461462
/// amount.
462-
pub fn extend(
463-
&mut self,
464-
other: CrateGraph,
465-
proc_macros: &mut ProcMacros,
466-
other_proc_macros: ProcMacros,
467-
) -> u32 {
463+
pub fn extend(&mut self, other: CrateGraph, proc_macros: &mut ProcMacroPaths) -> u32 {
468464
let start = self.arena.len() as u32;
469465
self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
470466
let new_id = id.shift(start);
@@ -473,8 +469,11 @@ impl CrateGraph {
473469
}
474470
(new_id, data)
475471
}));
476-
proc_macros
477-
.extend(other_proc_macros.into_iter().map(|(id, macros)| (id.shift(start), macros)));
472+
473+
*proc_macros = mem::take(proc_macros)
474+
.into_iter()
475+
.map(|(id, macros)| (id.shift(start), macros))
476+
.collect();
478477
start
479478
}
480479

crates/base-db/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ pub use crate::{
1616
input::{
1717
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
1818
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
19-
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, ProcMacros, SourceRoot, SourceRootId,
20-
TargetLayoutLoadResult,
19+
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, ProcMacroPaths, ProcMacros, SourceRoot,
20+
SourceRootId, TargetLayoutLoadResult,
2121
},
2222
};
2323
pub use salsa::{self, Cancelled};

crates/project-model/src/tests.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
path::{Path, PathBuf},
44
};
55

6-
use base_db::{CrateGraph, FileId, ProcMacros};
6+
use base_db::{CrateGraph, FileId, ProcMacroPaths};
77
use cfg::{CfgAtom, CfgDiff};
88
use expect_test::{expect, Expect};
99
use paths::{AbsPath, AbsPathBuf};
@@ -14,11 +14,14 @@ use crate::{
1414
WorkspaceBuildScripts,
1515
};
1616

17-
fn load_cargo(file: &str) -> (CrateGraph, ProcMacros) {
17+
fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) {
1818
load_cargo_with_overrides(file, CfgOverrides::default())
1919
}
2020

21-
fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> (CrateGraph, ProcMacros) {
21+
fn load_cargo_with_overrides(
22+
file: &str,
23+
cfg_overrides: CfgOverrides,
24+
) -> (CrateGraph, ProcMacroPaths) {
2225
let meta = get_test_json_file(file);
2326
let cargo_workspace = CargoWorkspace::new(meta);
2427
let project_workspace = ProjectWorkspace::Cargo {
@@ -34,7 +37,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> (CrateG
3437
to_crate_graph(project_workspace)
3538
}
3639

37-
fn load_rust_project(file: &str) -> (CrateGraph, ProcMacros) {
40+
fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) {
3841
let data = get_test_json_file(file);
3942
let project = rooted_project_json(data);
4043
let sysroot = Ok(get_fake_sysroot());
@@ -92,9 +95,8 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
9295
ProjectJson::new(base, data)
9396
}
9497

95-
fn to_crate_graph(project_workspace: ProjectWorkspace) -> (CrateGraph, ProcMacros) {
98+
fn to_crate_graph(project_workspace: ProjectWorkspace) -> (CrateGraph, ProcMacroPaths) {
9699
project_workspace.to_crate_graph(
97-
&mut |_, _| Ok(Vec::new()),
98100
&mut {
99101
let mut counter = 0;
100102
move |_path| {

crates/project-model/src/workspace.rs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{collections::VecDeque, fmt, fs, process::Command, sync::Arc};
77
use anyhow::{bail, format_err, Context, Result};
88
use base_db::{
99
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
10-
FileId, LangCrateOrigin, ProcMacroLoadResult, ProcMacros, TargetLayoutLoadResult,
10+
FileId, LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
1111
};
1212
use cfg::{CfgDiff, CfgOptions};
1313
use paths::{AbsPath, AbsPathBuf};
@@ -576,16 +576,14 @@ impl ProjectWorkspace {
576576

577577
pub fn to_crate_graph(
578578
&self,
579-
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
580579
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
581580
extra_env: &FxHashMap<String, String>,
582-
) -> (CrateGraph, ProcMacros) {
581+
) -> (CrateGraph, ProcMacroPaths) {
583582
let _p = profile::span("ProjectWorkspace::to_crate_graph");
584583

585584
let (mut crate_graph, proc_macros) = match self {
586585
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
587586
rustc_cfg.clone(),
588-
load_proc_macro,
589587
load,
590588
project,
591589
sysroot.as_ref().ok(),
@@ -602,7 +600,6 @@ impl ProjectWorkspace {
602600
toolchain: _,
603601
target_layout,
604602
} => cargo_to_crate_graph(
605-
load_proc_macro,
606603
load,
607604
rustc.as_ref().ok(),
608605
cargo,
@@ -679,15 +676,14 @@ impl ProjectWorkspace {
679676

680677
fn project_json_to_crate_graph(
681678
rustc_cfg: Vec<CfgFlag>,
682-
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
683679
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
684680
project: &ProjectJson,
685681
sysroot: Option<&Sysroot>,
686682
extra_env: &FxHashMap<String, String>,
687683
target_layout: TargetLayoutLoadResult,
688-
) -> (CrateGraph, ProcMacros) {
684+
) -> (CrateGraph, ProcMacroPaths) {
689685
let mut crate_graph = CrateGraph::default();
690-
let mut proc_macros = FxHashMap::<_, _>::default();
686+
let mut proc_macros = FxHashMap::default();
691687
let sysroot_deps = sysroot.as_ref().map(|sysroot| {
692688
sysroot_to_crate_graph(
693689
&mut crate_graph,
@@ -708,16 +704,15 @@ fn project_json_to_crate_graph(
708704
})
709705
.map(|(crate_id, krate, file_id)| {
710706
let env = krate.env.clone().into_iter().collect();
711-
if let Some(it) = krate.proc_macro_dylib_path.clone() {
707+
if let Some(path) = krate.proc_macro_dylib_path.clone() {
712708
proc_macros.insert(
713709
crate_id,
714-
load_proc_macro(
715-
krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
716-
&it,
717-
),
710+
Ok((
711+
krate.display_name.as_ref().map(|it| it.canonical_name().to_owned()),
712+
path,
713+
)),
718714
);
719715
}
720-
721716
let target_cfgs = match krate.target.as_deref() {
722717
Some(target) => cfg_cache
723718
.entry(target)
@@ -782,7 +777,6 @@ fn project_json_to_crate_graph(
782777
}
783778

784779
fn cargo_to_crate_graph(
785-
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
786780
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
787781
rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>,
788782
cargo: &CargoWorkspace,
@@ -791,7 +785,7 @@ fn cargo_to_crate_graph(
791785
override_cfg: &CfgOverrides,
792786
build_scripts: &WorkspaceBuildScripts,
793787
target_layout: TargetLayoutLoadResult,
794-
) -> (CrateGraph, ProcMacros) {
788+
) -> (CrateGraph, ProcMacroPaths) {
795789
let _p = profile::span("cargo_to_crate_graph");
796790
let mut crate_graph = CrateGraph::default();
797791
let mut proc_macros = FxHashMap::default();
@@ -862,7 +856,6 @@ fn cargo_to_crate_graph(
862856
&cargo[pkg],
863857
build_scripts.get_output(pkg),
864858
cfg_options.clone(),
865-
&mut |path| load_proc_macro(&cargo[tgt].name, path),
866859
file_id,
867860
&cargo[tgt].name,
868861
cargo[tgt].is_proc_macro,
@@ -938,7 +931,6 @@ fn cargo_to_crate_graph(
938931
&mut proc_macros,
939932
&mut pkg_to_lib_crate,
940933
load,
941-
load_proc_macro,
942934
rustc_workspace,
943935
cargo,
944936
&public_deps,
@@ -966,7 +958,7 @@ fn detached_files_to_crate_graph(
966958
detached_files: &[AbsPathBuf],
967959
sysroot: Option<&Sysroot>,
968960
target_layout: TargetLayoutLoadResult,
969-
) -> (CrateGraph, ProcMacros) {
961+
) -> (CrateGraph, ProcMacroPaths) {
970962
let _p = profile::span("detached_files_to_crate_graph");
971963
let mut crate_graph = CrateGraph::default();
972964
let (public_deps, _libproc_macro) = match sysroot {
@@ -1018,10 +1010,9 @@ fn detached_files_to_crate_graph(
10181010

10191011
fn handle_rustc_crates(
10201012
crate_graph: &mut CrateGraph,
1021-
proc_macros: &mut ProcMacros,
1013+
proc_macros: &mut ProcMacroPaths,
10221014
pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
10231015
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
1024-
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
10251016
rustc_workspace: &CargoWorkspace,
10261017
cargo: &CargoWorkspace,
10271018
public_deps: &SysrootPublicDeps,
@@ -1084,7 +1075,6 @@ fn handle_rustc_crates(
10841075
&rustc_workspace[pkg],
10851076
build_scripts.get_output(pkg),
10861077
cfg_options.clone(),
1087-
&mut |path| load_proc_macro(&rustc_workspace[tgt].name, path),
10881078
file_id,
10891079
&rustc_workspace[tgt].name,
10901080
rustc_workspace[tgt].is_proc_macro,
@@ -1146,11 +1136,10 @@ fn handle_rustc_crates(
11461136

11471137
fn add_target_crate_root(
11481138
crate_graph: &mut CrateGraph,
1149-
proc_macros: &mut ProcMacros,
1139+
proc_macros: &mut ProcMacroPaths,
11501140
pkg: &PackageData,
11511141
build_data: Option<&BuildScriptOutput>,
11521142
cfg_options: CfgOptions,
1153-
load_proc_macro: &mut dyn FnMut(&AbsPath) -> ProcMacroLoadResult,
11541143
file_id: FileId,
11551144
cargo_name: &str,
11561145
is_proc_macro: bool,
@@ -1197,11 +1186,11 @@ fn add_target_crate_root(
11971186
target_layout,
11981187
);
11991188
let proc_macro = match build_data.as_ref().map(|it| &it.proc_macro_dylib_path) {
1200-
Some(it) => it.as_deref().map(load_proc_macro),
1189+
Some(it) => it.clone().map(Ok),
12011190
None => Some(Err("crate has not (yet) been built".into())),
12021191
};
12031192
if let Some(proc_macro) = proc_macro {
1204-
proc_macros.insert(crate_id, proc_macro);
1193+
proc_macros.insert(crate_id, proc_macro.map(|path| (Some(cargo_name.to_owned()), path)));
12051194
}
12061195

12071196
crate_id

crates/rust-analyzer/src/cli/load_cargo.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn load_workspace(
6969
Box::new(loader)
7070
};
7171

72-
let proc_macro_client = match &load_config.with_proc_macro_server {
72+
let proc_macro_server = match &load_config.with_proc_macro_server {
7373
ProcMacroServerChoice::Sysroot => ws
7474
.find_sysroot_proc_macro_srv()
7575
.ok_or_else(|| "failed to find sysroot proc-macro server".to_owned())
@@ -83,9 +83,6 @@ pub fn load_workspace(
8383
};
8484

8585
let (crate_graph, proc_macros) = ws.to_crate_graph(
86-
&mut |_, path: &AbsPath| {
87-
load_proc_macro(proc_macro_client.as_ref().map_err(|e| &**e), path, &[])
88-
},
8986
&mut |path: &AbsPath| {
9087
let contents = loader.load_sync(path);
9188
let path = vfs::VfsPath::from(path.to_path_buf());
@@ -94,6 +91,21 @@ pub fn load_workspace(
9491
},
9592
extra_env,
9693
);
94+
let proc_macros = {
95+
let proc_macro_server = match &proc_macro_server {
96+
Ok(it) => Ok(it),
97+
Err(e) => Err(e.as_str()),
98+
};
99+
proc_macros
100+
.into_iter()
101+
.map(|(crate_id, path)| {
102+
(
103+
crate_id,
104+
path.and_then(|(_, path)| load_proc_macro(proc_macro_server, &path, &[])),
105+
)
106+
})
107+
.collect()
108+
};
97109

98110
let project_folders = ProjectFolders::new(&[ws], &[]);
99111
loader.set_config(vfs::loader::Config {
@@ -114,7 +126,7 @@ pub fn load_workspace(
114126
if load_config.prefill_caches {
115127
host.analysis().parallel_prime_caches(1, |_| {})?;
116128
}
117-
Ok((host, vfs, proc_macro_client.ok()))
129+
Ok((host, vfs, proc_macro_server.ok()))
118130
}
119131

120132
fn load_crate_graph(

crates/rust-analyzer/src/global_state.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ pub(crate) struct GlobalState {
5959
pub(crate) mem_docs: MemDocs,
6060
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
6161
pub(crate) shutdown_requested: bool,
62-
pub(crate) proc_macro_changed: bool,
6362
pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
6463
pub(crate) source_root_config: SourceRootConfig,
65-
pub(crate) proc_macro_clients: Vec<Result<ProcMacroServer, String>>,
64+
65+
pub(crate) proc_macro_changed: bool,
66+
pub(crate) proc_macro_clients: Arc<[Result<ProcMacroServer, String>]>,
6667

6768
pub(crate) flycheck: Arc<[FlycheckHandle]>,
6869
pub(crate) flycheck_sender: Sender<flycheck::Message>,
@@ -151,10 +152,11 @@ impl GlobalState {
151152
mem_docs: MemDocs::default(),
152153
semantic_tokens_cache: Arc::new(Default::default()),
153154
shutdown_requested: false,
154-
proc_macro_changed: false,
155155
last_reported_status: None,
156156
source_root_config: SourceRootConfig::default(),
157-
proc_macro_clients: vec![],
157+
158+
proc_macro_changed: false,
159+
proc_macro_clients: Arc::new([]),
158160

159161
flycheck: Arc::new([]),
160162
flycheck_sender,

crates/rust-analyzer/src/handlers.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use std::{
66
io::Write as _,
77
process::{self, Stdio},
8+
sync::Arc,
89
};
910

1011
use anyhow::Context;
@@ -44,7 +45,7 @@ use crate::{
4445
};
4546

4647
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<()> {
47-
state.proc_macro_clients.clear();
48+
state.proc_macro_clients = Arc::new([]);
4849
state.proc_macro_changed = false;
4950

5051
state.fetch_workspaces_queue.request_op("reload workspace request".to_string());
@@ -53,7 +54,7 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> Result<
5354
}
5455

5556
pub(crate) fn handle_proc_macros_reload(state: &mut GlobalState, _: ()) -> Result<()> {
56-
state.proc_macro_clients.clear();
57+
state.proc_macro_clients = Arc::new([]);
5758
state.proc_macro_changed = false;
5859

5960
state.fetch_build_data_queue.request_op("reload proc macros request".to_string());

0 commit comments

Comments
 (0)