Skip to content

Commit 2b438d7

Browse files
committed
fix: Incorrect flychecks with multiple workspaces
When rust-analyzer receives textDocument/didChangeWatchedFiles, we want to trigger a flycheck in all workspaces if we can't find which workspace owns those files. However, since we used .any() instead of .all(), this behaviour was always triggered when the user had more than one workspace. Instead, use .all() so we correctly detect when the file it outside of all workspaces. --- For cargo-based projects, this just made rust-analyzer slower. For projects with a custom check command using $saved_file or {saved_file}, this introduced a race condition that sometimes prevented diagnostics. When we see the following flycheck events in this order: // Created by textDocument/didSave. RequestStateChange(Restart { ... saved_file: Some("foo.rs") }) // Created by textDocument/didChangeWatchedFiles RequestStateChange(Restart { ... saved_file: None }) Then the flycheck debounce takes the last event, we invoke flycheck with saved_file: None, and no flycheck occurs (because we require a value to substitute in $saved_file). Previously the debounce took the first event (until #21666), but that just meant a race condition when events arrive in the opposite order.
1 parent a8e2add commit 2b438d7

2 files changed

Lines changed: 3 additions & 2 deletions

File tree

crates/rust-analyzer/src/flycheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ impl JsonLinesParser<CheckMessage> for CheckParser {
10211021
}
10221022
}
10231023

1024-
#[derive(Deserialize)]
1024+
#[derive(Deserialize, Debug)]
10251025
#[serde(untagged)]
10261026
enum JsonMessage {
10271027
Cargo(cargo_metadata::Message),

crates/rust-analyzer/src/handlers/notification.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,9 @@ pub(crate) fn handle_did_change_watched_files(
295295
for change in params.changes.iter().unique_by(|&it| &it.uri) {
296296
if let Ok(path) = from_proto::abs_path(&change.uri) {
297297
if !trigger_flycheck {
298+
// Trigger if no workspaces contain this file.
298299
trigger_flycheck =
299-
state.config.workspace_roots().iter().any(|root| !path.starts_with(root));
300+
state.config.workspace_roots().iter().all(|root| !path.starts_with(root));
300301
}
301302
state.loader.handle.invalidate(path);
302303
}

0 commit comments

Comments
 (0)