Skip to content

Commit aaa8c20

Browse files
committed
internal: do not drop errors from cargo metadata/check
Work towards #3155
1 parent 047b531 commit aaa8c20

File tree

4 files changed

+60
-51
lines changed

4 files changed

+60
-51
lines changed

crates/project_model/src/build_data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub struct BuildDataCollector {
5252
configs: FxHashMap<AbsPathBuf, BuildDataConfig>,
5353
}
5454

55-
#[derive(Debug, Default, PartialEq, Eq)]
55+
#[derive(Debug, Default, PartialEq, Eq, Clone)]
5656
pub struct BuildDataResult {
5757
data: FxHashMap<AbsPathBuf, BuildDataMap>,
5858
}

crates/rust-analyzer/src/global_state.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,16 @@ pub(crate) struct GlobalState {
8282
pub(crate) source_root_config: SourceRootConfig,
8383
pub(crate) proc_macro_client: Option<ProcMacroClient>,
8484

85+
/// For both `workspaces` and `workspace_build_data`, the field stores the
86+
/// data we actually use, while the `OpQueue` stores the result of the last
87+
/// fetch.
88+
///
89+
/// If the fetch (partially) fails, we do not update the values.
8590
pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
86-
pub(crate) fetch_workspaces_queue: OpQueue<(), ()>,
87-
91+
pub(crate) fetch_workspaces_queue: OpQueue<(), Vec<anyhow::Result<ProjectWorkspace>>>,
8892
pub(crate) workspace_build_data: Option<BuildDataResult>,
89-
pub(crate) fetch_build_data_queue: OpQueue<BuildDataCollector, ()>,
93+
pub(crate) fetch_build_data_queue:
94+
OpQueue<BuildDataCollector, Option<anyhow::Result<BuildDataResult>>>,
9095

9196
latest_requests: Arc<RwLock<LatestRequests>>,
9297
}
@@ -140,10 +145,12 @@ impl GlobalState {
140145
status: Status::default(),
141146
source_root_config: SourceRootConfig::default(),
142147
proc_macro_client: None,
148+
143149
workspaces: Arc::new(Vec::new()),
144150
fetch_workspaces_queue: OpQueue::default(),
145151
workspace_build_data: None,
146152
fetch_build_data_queue: OpQueue::default(),
153+
147154
latest_requests: Default::default(),
148155
}
149156
}

crates/rust-analyzer/src/main_loop.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use ide::{Canceled, FileId};
1212
use ide_db::base_db::VfsPath;
1313
use lsp_server::{Connection, Notification, Request, Response};
1414
use lsp_types::notification::Notification as _;
15+
use project_model::BuildDataCollector;
1516
use vfs::ChangeKind;
1617

1718
use crate::{
@@ -227,8 +228,15 @@ impl GlobalState {
227228
(Progress::Report, Some(msg))
228229
}
229230
ProjectWorkspaceProgress::End(workspaces) => {
230-
self.fetch_workspaces_completed();
231-
self.switch_workspaces(workspaces, None);
231+
self.fetch_workspaces_completed(workspaces);
232+
self.switch_workspaces();
233+
if self.config.run_build_scripts() {
234+
let mut collector = BuildDataCollector::default();
235+
for ws in self.workspaces.iter() {
236+
ws.collect_build_data_configs(&mut collector);
237+
}
238+
self.fetch_build_data_request(collector)
239+
}
232240
(Progress::End, None)
233241
}
234242
};
@@ -240,11 +248,9 @@ impl GlobalState {
240248
BuildDataProgress::Report(msg) => {
241249
(Some(Progress::Report), Some(msg))
242250
}
243-
BuildDataProgress::End(collector) => {
244-
self.fetch_build_data_completed();
245-
let workspaces =
246-
(*self.workspaces).clone().into_iter().map(Ok).collect();
247-
self.switch_workspaces(workspaces, Some(collector));
251+
BuildDataProgress::End(build_data_result) => {
252+
self.fetch_build_data_completed(build_data_result);
253+
self.switch_workspaces();
248254
(Some(Progress::End), None)
249255
}
250256
};

crates/rust-analyzer/src/reload.rs

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,11 @@ impl GlobalState {
139139
sender.send(Task::FetchBuildData(BuildDataProgress::End(res))).unwrap();
140140
});
141141
}
142-
pub(crate) fn fetch_build_data_completed(&mut self) {
143-
self.fetch_build_data_queue.op_completed(())
142+
pub(crate) fn fetch_build_data_completed(
143+
&mut self,
144+
build_data: anyhow::Result<BuildDataResult>,
145+
) {
146+
self.fetch_build_data_queue.op_completed(Some(build_data))
144147
}
145148

146149
pub(crate) fn fetch_workspaces_request(&mut self) {
@@ -194,54 +197,55 @@ impl GlobalState {
194197
}
195198
});
196199
}
197-
pub(crate) fn fetch_workspaces_completed(&mut self) {
198-
self.fetch_workspaces_queue.op_completed(())
199-
}
200-
201-
pub(crate) fn switch_workspaces(
200+
pub(crate) fn fetch_workspaces_completed(
202201
&mut self,
203202
workspaces: Vec<anyhow::Result<ProjectWorkspace>>,
204-
workspace_build_data: Option<anyhow::Result<BuildDataResult>>,
205203
) {
204+
self.fetch_workspaces_queue.op_completed(workspaces)
205+
}
206+
207+
pub(crate) fn switch_workspaces(&mut self) {
206208
let _p = profile::span("GlobalState::switch_workspaces");
209+
let workspaces = self.fetch_workspaces_queue.last_op_result();
207210
log::info!("will switch workspaces: {:?}", workspaces);
208211

209-
let mut has_errors = false;
212+
let mut error_message = None;
210213
let workspaces = workspaces
211-
.into_iter()
212-
.filter_map(|res| {
213-
res.map_err(|err| {
214-
has_errors = true;
214+
.iter()
215+
.filter_map(|res| match res {
216+
Ok(it) => Some(it.clone()),
217+
Err(err) => {
215218
log::error!("failed to load workspace: {:#}", err);
216-
if self.workspaces.is_empty() {
217-
self.show_message(
218-
lsp_types::MessageType::Error,
219-
format!("rust-analyzer failed to load workspace: {:#}", err),
220-
);
221-
}
222-
})
223-
.ok()
219+
let message = error_message.get_or_insert_with(String::new);
220+
stdx::format_to!(
221+
message,
222+
"rust-analyzer failed to load workspace: {:#}\n",
223+
err
224+
);
225+
None
226+
}
224227
})
225228
.collect::<Vec<_>>();
226229

227-
let workspace_build_data = match workspace_build_data {
228-
Some(Ok(it)) => Some(it),
230+
let workspace_build_data = match self.fetch_build_data_queue.last_op_result() {
231+
Some(Ok(it)) => Some(it.clone()),
232+
None => None,
229233
Some(Err(err)) => {
230234
log::error!("failed to fetch build data: {:#}", err);
231-
self.show_message(
232-
lsp_types::MessageType::Error,
233-
format!("rust-analyzer failed to fetch build data: {:#}", err),
234-
);
235-
return;
235+
let message = error_message.get_or_insert_with(String::new);
236+
stdx::format_to!(message, "rust-analyzer failed to fetch build data: {:#}\n", err);
237+
None
236238
}
237-
None => None,
238239
};
239240

240-
if *self.workspaces == workspaces && self.workspace_build_data == workspace_build_data {
241-
return;
241+
if let Some(error_message) = error_message {
242+
self.show_message(lsp_types::MessageType::Error, error_message);
243+
if !self.workspaces.is_empty() {
244+
return;
245+
}
242246
}
243247

244-
if !self.workspaces.is_empty() && has_errors {
248+
if *self.workspaces == workspaces && self.workspace_build_data == workspace_build_data {
245249
return;
246250
}
247251

@@ -337,14 +341,6 @@ impl GlobalState {
337341
};
338342
change.set_crate_graph(crate_graph);
339343

340-
if self.config.run_build_scripts() && workspace_build_data.is_none() {
341-
let mut collector = BuildDataCollector::default();
342-
for ws in &workspaces {
343-
ws.collect_build_data_configs(&mut collector);
344-
}
345-
self.fetch_build_data_request(collector)
346-
}
347-
348344
self.source_root_config = project_folders.source_root_config;
349345
self.workspaces = Arc::new(workspaces);
350346
self.workspace_build_data = workspace_build_data;

0 commit comments

Comments
 (0)