Auto merge of #14427 - davidbarsky:davidbarsky/allow-subsequent-workspaces-to-have-proc-macros, r=Veykril

fix: allow new, subsequent `rust-project.json`-based workspaces to get proc macro expansion

As detailed in https://github.com/rust-lang/rust-analyzer/issues/14417#issuecomment-1485336174, `rust-project.json` workspaces added after the initial `rust-project.json`-based workspace was already indexed by rust-analyzer would not receive procedural macro expansion despite `config.expand_proc_macros` returning true. To fix this issue:
1. I changed `reload.rs` to check which workspaces are newly added.
2. Spawned new procedural macro expansion servers based on the _new_ workspaces.
    1. This is to prevent spawning duplicate procedural macro expansion servers for already existing workspaces. While the overall memory usage of duplicate procedural macro servers is minimal, this is more about the _principle_ of not leaking processes 😅.
3. Launched procedural macro expansion if any workspaces are `rust-project.json`-based _or_ `same_workspaces` is true. `same_workspaces` being true (and reachable) indicates that that build scripts have finished building (in Cargo-based projects), while the build scripts in `rust-project.json`-based projects have _already been built_ by the build system that produced the `rust-project.json`.

I couldn't really think of structuring this code in a better way without engaging with https://github.com/rust-lang/rust-analyzer/issues/7444.
This commit is contained in:
bors 2023-03-30 07:50:27 +00:00
commit b915eb32fa
4 changed files with 22 additions and 27 deletions

View file

@ -102,7 +102,7 @@ pub fn load_workspace(
(
crate_id,
path.map_or_else(
|| Err("proc macro crate is missing dylib".to_owned()),
|_| Err("proc macro crate is missing dylib".to_owned()),
|(_, path)| load_proc_macro(proc_macro_server, &path, &[]),
),
)

View file

@ -251,7 +251,7 @@ impl GlobalState {
(
crate_id,
res.map_or_else(
|| Err("proc macro crate is missing dylib".to_owned()),
|_| Err("proc macro crate is missing dylib".to_owned()),
|(crate_name, path)| {
progress(path.display().to_string());
load_proc_macro(
@ -370,7 +370,7 @@ impl GlobalState {
let files_config = self.config.files();
let project_folders = ProjectFolders::new(&self.workspaces, &files_config.exclude);
if self.proc_macro_clients.is_empty() {
if self.proc_macro_clients.is_empty() || !same_workspaces {
if let Some((path, path_manually_set)) = self.config.proc_macro_srv() {
tracing::info!("Spawning proc-macro servers");
self.proc_macro_clients = self
@ -448,19 +448,8 @@ impl GlobalState {
};
let mut change = Change::new();
if same_workspaces {
if self.config.expand_proc_macros() {
self.fetch_proc_macros_queue.request_op(cause, proc_macro_paths);
}
} else {
// Set up errors for proc-macros upfront that we haven't run build scripts yet
let mut proc_macros = FxHashMap::default();
for paths in proc_macro_paths {
proc_macros.extend(paths.into_iter().map(move |(crate_id, _)| {
(crate_id, Err("crate has not yet been build".to_owned()))
}));
}
change.set_proc_macros(proc_macros);
if self.config.expand_proc_macros() {
self.fetch_proc_macros_queue.request_op(cause, proc_macro_paths);
}
change.set_crate_graph(crate_graph);
self.analysis_host.apply_change(change);