Skip to content

Commit 6c7578b

Browse files
committed
Move cargo metadata off the main loop
1 parent 83f3cdc commit 6c7578b

File tree

4 files changed

+56
-43
lines changed

4 files changed

+56
-43
lines changed

crates/ra_project_model/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl ProjectManifest {
150150
impl ProjectWorkspace {
151151
pub fn load(
152152
manifest: ProjectManifest,
153-
cargo_features: &CargoConfig,
153+
cargo_config: &CargoConfig,
154154
with_sysroot: bool,
155155
) -> Result<ProjectWorkspace> {
156156
let res = match manifest {
@@ -166,7 +166,7 @@ impl ProjectWorkspace {
166166
ProjectWorkspace::Json { project }
167167
}
168168
ProjectManifest::CargoToml(cargo_toml) => {
169-
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)
169+
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_config)
170170
.with_context(|| {
171171
format!(
172172
"Failed to read Cargo metadata from Cargo.toml file {}",

crates/rust-analyzer/src/main_loop.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::{
2121
lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress},
2222
Result,
2323
};
24+
use ra_project_model::ProjectWorkspace;
2425

2526
pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
2627
log::info!("initial config: {:#?}", config);
@@ -58,6 +59,7 @@ enum Event {
5859
pub(crate) enum Task {
5960
Response(Response),
6061
Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>),
62+
Workspaces(Vec<anyhow::Result<ProjectWorkspace>>),
6163
Unit,
6264
}
6365

@@ -111,6 +113,14 @@ impl GlobalState {
111113
}
112114

113115
fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> {
116+
if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found
117+
{
118+
self.show_message(
119+
lsp_types::MessageType::Error,
120+
"rust-analyzer failed to discover workspace".to_string(),
121+
);
122+
};
123+
114124
let registration_options = lsp_types::TextDocumentRegistrationOptions {
115125
document_selector: Some(vec![
116126
lsp_types::DocumentFilter {
@@ -140,7 +150,7 @@ impl GlobalState {
140150
|_, _| (),
141151
);
142152

143-
self.reload();
153+
self.fetch_workspaces();
144154

145155
while let Some(event) = self.next_event(&inbox) {
146156
if let Event::Lsp(lsp_server::Message::Notification(not)) = &event {
@@ -182,6 +192,7 @@ impl GlobalState {
182192
self.diagnostics.set_native_diagnostics(file_id, diagnostics)
183193
}
184194
}
195+
Task::Workspaces(workspaces) => self.switch_workspaces(workspaces),
185196
Task::Unit => (),
186197
}
187198
self.analysis_host.maybe_collect_garbage();
@@ -320,7 +331,7 @@ impl GlobalState {
320331
self.register_request(&req, request_received);
321332

322333
RequestDispatcher { req: Some(req), global_state: self }
323-
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.reload()))?
334+
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
324335
.on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
325336
.on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
326337
.on_sync::<lsp_types::request::Shutdown>(|_, ()| Ok(()))?

crates/rust-analyzer/src/reload.rs

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use vfs::{file_set::FileSetConfig, AbsPath};
1111
use crate::{
1212
config::{Config, FilesWatcher, LinkedProject},
1313
global_state::{GlobalState, Handle},
14+
main_loop::Task,
1415
};
1516

1617
impl GlobalState {
@@ -20,51 +21,51 @@ impl GlobalState {
2021
self.analysis_host.update_lru_capacity(old_config.lru_capacity);
2122
}
2223
if self.config.linked_projects != old_config.linked_projects {
23-
self.reload()
24+
self.fetch_workspaces()
2425
} else if self.config.flycheck != old_config.flycheck {
2526
self.reload_flycheck();
2627
}
2728
}
28-
pub(crate) fn reload(&mut self) {
29-
log::info!("reloading projects: {:?}", self.config.linked_projects);
30-
if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found
31-
{
32-
self.show_message(
33-
lsp_types::MessageType::Error,
34-
"rust-analyzer failed to discover workspace".to_string(),
35-
);
36-
};
37-
38-
let workspaces = {
39-
self.config
40-
.linked_projects
41-
.iter()
42-
.map(|project| match project {
43-
LinkedProject::ProjectManifest(manifest) => {
44-
ra_project_model::ProjectWorkspace::load(
45-
manifest.clone(),
46-
&self.config.cargo,
47-
self.config.with_sysroot,
48-
)
49-
}
50-
LinkedProject::InlineJsonProject(it) => {
51-
Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
52-
}
53-
})
54-
.collect::<Vec<_>>()
55-
.into_iter()
56-
.filter_map(|res| {
57-
res.map_err(|err| {
58-
log::error!("failed to load workspace: {:#}", err);
59-
self.show_message(
60-
lsp_types::MessageType::Error,
61-
format!("rust-analyzer failed to load workspace: {:#}", err),
62-
);
29+
pub(crate) fn fetch_workspaces(&mut self) {
30+
self.task_pool.handle.spawn({
31+
let linked_projects = self.config.linked_projects.clone();
32+
let cargo_config = self.config.cargo.clone();
33+
let with_sysroot = self.config.with_sysroot.clone();
34+
move || {
35+
let workspaces = linked_projects
36+
.iter()
37+
.map(|project| match project {
38+
LinkedProject::ProjectManifest(manifest) => {
39+
ra_project_model::ProjectWorkspace::load(
40+
manifest.clone(),
41+
&cargo_config,
42+
with_sysroot,
43+
)
44+
}
45+
LinkedProject::InlineJsonProject(it) => {
46+
Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
47+
}
6348
})
64-
.ok()
49+
.collect::<Vec<_>>();
50+
Task::Workspaces(workspaces)
51+
}
52+
});
53+
}
54+
pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) {
55+
log::info!("reloading projects: {:?}", self.config.linked_projects);
56+
let workspaces = workspaces
57+
.into_iter()
58+
.filter_map(|res| {
59+
res.map_err(|err| {
60+
log::error!("failed to load workspace: {:#}", err);
61+
self.show_message(
62+
lsp_types::MessageType::Error,
63+
format!("rust-analyzer failed to load workspace: {:#}", err),
64+
);
6565
})
66-
.collect::<Vec<_>>()
67-
};
66+
.ok()
67+
})
68+
.collect::<Vec<_>>();
6869

6970
if let FilesWatcher::Client = self.config.files.watcher {
7071
let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions {

crates/rust-analyzer/tests/heavy_tests/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ version = \"0.0.0\"
447447
",
448448
)
449449
.server();
450+
server.wait_until_workspace_is_loaded();
450451

451452
server.request::<OnEnter>(
452453
TextDocumentPositionParams {

0 commit comments

Comments
 (0)