Skip to content

Commit 4339a79

Browse files
authored
Merge pull request #19409 from Veykril/push-osqtywsvmwxv
minor: Don't query the database in workspace switching
2 parents 3edfbcd + 7581e19 commit 4339a79

File tree

1 file changed

+42
-35
lines changed

1 file changed

+42
-35
lines changed

crates/rust-analyzer/src/reload.rs

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::{iter, mem};
1818
use hir::{ChangeWithProcMacros, ProcMacrosBuilder, db::DefDatabase};
1919
use ide_db::{
2020
FxHashMap,
21-
base_db::{CrateGraphBuilder, ProcMacroPaths, RootQueryDb, salsa::Durability},
21+
base_db::{CrateGraphBuilder, ProcMacroPaths, salsa::Durability},
2222
};
2323
use itertools::Itertools;
2424
use load_cargo::{ProjectFolders, load_proc_macro};
@@ -408,11 +408,11 @@ impl GlobalState {
408408
};
409409

410410
let mut builder = ProcMacrosBuilder::default();
411-
let chain = proc_macro_clients
411+
let proc_macro_clients = proc_macro_clients
412412
.iter()
413413
.map(|res| res.as_ref().map_err(|e| e.to_string()))
414414
.chain(iter::repeat_with(|| Err("proc-macro-srv is not running".into())));
415-
for (client, paths) in chain.zip(paths) {
415+
for (client, paths) in proc_macro_clients.zip(paths) {
416416
paths
417417
.into_iter()
418418
.map(move |(crate_id, res)| {
@@ -458,11 +458,12 @@ impl GlobalState {
458458
else {
459459
return;
460460
};
461+
let switching_from_empty_workspace = self.workspaces.is_empty();
461462

462-
info!(%cause, ?force_crate_graph_reload);
463-
if self.fetch_workspace_error().is_err() && !self.workspaces.is_empty() {
463+
info!(%cause, ?force_crate_graph_reload, %switching_from_empty_workspace);
464+
if self.fetch_workspace_error().is_err() && !switching_from_empty_workspace {
464465
if *force_crate_graph_reload {
465-
self.recreate_crate_graph(cause);
466+
self.recreate_crate_graph(cause, false);
466467
}
467468
// It only makes sense to switch to a partially broken workspace
468469
// if we don't have any workspace at all yet.
@@ -479,36 +480,44 @@ impl GlobalState {
479480
.all(|(l, r)| l.eq_ignore_build_data(r));
480481

481482
if same_workspaces {
482-
let (workspaces, build_scripts) = match self.fetch_build_data_queue.last_op_result() {
483-
Some(FetchBuildDataResponse { workspaces, build_scripts }) => {
484-
(workspaces.clone(), build_scripts.as_slice())
485-
}
486-
None => (Default::default(), Default::default()),
487-
};
483+
if switching_from_empty_workspace {
484+
// Switching from empty to empty is a no-op
485+
return;
486+
}
487+
if let Some(FetchBuildDataResponse { workspaces, build_scripts }) =
488+
self.fetch_build_data_queue.last_op_result()
489+
{
490+
if Arc::ptr_eq(workspaces, &self.workspaces) {
491+
info!("set build scripts to workspaces");
488492

489-
if Arc::ptr_eq(&workspaces, &self.workspaces) {
490-
info!("set build scripts to workspaces");
493+
let workspaces = workspaces
494+
.iter()
495+
.cloned()
496+
.zip(build_scripts)
497+
.map(|(mut ws, bs)| {
498+
ws.set_build_scripts(bs.as_ref().ok().cloned().unwrap_or_default());
499+
ws
500+
})
501+
.collect::<Vec<_>>();
502+
// Workspaces are the same, but we've updated build data.
503+
info!("same workspace, but new build data");
504+
self.workspaces = Arc::new(workspaces);
505+
} else {
506+
info!("build scripts do not match the version of the active workspace");
507+
if *force_crate_graph_reload {
508+
self.recreate_crate_graph(cause, switching_from_empty_workspace);
509+
}
491510

492-
let workspaces = workspaces
493-
.iter()
494-
.cloned()
495-
.zip(build_scripts)
496-
.map(|(mut ws, bs)| {
497-
ws.set_build_scripts(bs.as_ref().ok().cloned().unwrap_or_default());
498-
ws
499-
})
500-
.collect::<Vec<_>>();
501-
// Workspaces are the same, but we've updated build data.
502-
info!("same workspace, but new build data");
503-
self.workspaces = Arc::new(workspaces);
511+
// Current build scripts do not match the version of the active
512+
// workspace, so there's nothing for us to update.
513+
return;
514+
}
504515
} else {
505-
info!("build scripts do not match the version of the active workspace");
506516
if *force_crate_graph_reload {
507-
self.recreate_crate_graph(cause);
517+
self.recreate_crate_graph(cause, switching_from_empty_workspace);
508518
}
509519

510-
// Current build scripts do not match the version of the active
511-
// workspace, so there's nothing for us to update.
520+
// No build scripts but unchanged workspaces, nothing to do here
512521
return;
513522
}
514523
} else {
@@ -528,8 +537,7 @@ impl GlobalState {
528537
self.build_deps_changed = false;
529538
self.fetch_build_data_queue.request_op("workspace updated".to_owned(), ());
530539

531-
let initial_build = self.analysis_host.raw_database().all_crates().is_empty();
532-
if !initial_build {
540+
if !switching_from_empty_workspace {
533541
// `switch_workspaces()` will be called again when build scripts already run, which should
534542
// take a short time. If we update the workspace now we will invalidate proc macros and cfgs,
535543
// and then when build scripts complete we will invalidate them again.
@@ -691,12 +699,12 @@ impl GlobalState {
691699
self.local_roots_parent_map = Arc::new(self.source_root_config.source_root_parent_map());
692700

693701
info!(?cause, "recreating the crate graph");
694-
self.recreate_crate_graph(cause);
702+
self.recreate_crate_graph(cause, switching_from_empty_workspace);
695703

696704
info!("did switch workspaces");
697705
}
698706

699-
fn recreate_crate_graph(&mut self, cause: String) {
707+
fn recreate_crate_graph(&mut self, cause: String, initial_build: bool) {
700708
info!(?cause, "Building Crate Graph");
701709
self.report_progress(
702710
"Building CrateGraph",
@@ -732,7 +740,6 @@ impl GlobalState {
732740
ws_to_crate_graph(&self.workspaces, self.config.extra_env(None), load)
733741
};
734742
let mut change = ChangeWithProcMacros::new();
735-
let initial_build = self.analysis_host.raw_database().all_crates().is_empty();
736743
if initial_build || !self.config.expand_proc_macros() {
737744
if self.config.expand_proc_macros() {
738745
change.set_proc_macros(

0 commit comments

Comments
 (0)