Unnamed repository; edit this file 'description' to name the repository.
fix: Fix flycheck panicking with "once" invocation strategy
We only ever have one flycheck runner no matter the number of workspaces, so just kick off flycheck for it immediately
Lukas Wirth 2025-01-24
parent c78cc2b · commit 3ab96c4
-rw-r--r--crates/rust-analyzer/src/flycheck.rs11
-rw-r--r--crates/rust-analyzer/src/handlers/notification.rs25
2 files changed, 26 insertions, 10 deletions
diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs
index 22f06d68d8..2309f94a74 100644
--- a/crates/rust-analyzer/src/flycheck.rs
+++ b/crates/rust-analyzer/src/flycheck.rs
@@ -88,6 +88,17 @@ pub(crate) enum FlycheckConfig {
},
}
+impl FlycheckConfig {
+ pub(crate) fn invocation_strategy_once(&self) -> bool {
+ match self {
+ FlycheckConfig::CargoCommand { .. } => false,
+ FlycheckConfig::CustomCommand { invocation_strategy, .. } => {
+ *invocation_strategy == InvocationStrategy::Once
+ }
+ }
+ }
+}
+
impl fmt::Display for FlycheckConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index 98efc637c2..84ba89d9f3 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -291,9 +291,15 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
let file_id = state.vfs.read().0.file_id(&vfs_path);
if let Some(file_id) = file_id {
let world = state.snapshot();
+ let invocation_strategy_once = state.config.flycheck(None).invocation_strategy_once();
let may_flycheck_workspace = state.config.flycheck_workspace(None);
let mut updated = false;
let task = move || -> std::result::Result<(), ide::Cancelled> {
+ if invocation_strategy_once {
+ let saved_file = vfs_path.as_path().map(|p| p.to_owned());
+ world.flycheck[0].restart_workspace(saved_file.clone());
+ }
+
let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| {
let tgt_kind = it.target_kind();
let (tgt_name, root, package) = match it {
@@ -320,16 +326,15 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
// the user opted into package checks then
let package_check_allowed = target.is_some() || !may_flycheck_workspace;
if package_check_allowed {
- let workspace =
- world.workspaces.iter().enumerate().find(|(_, ws)| match &ws.kind {
- project_model::ProjectWorkspaceKind::Cargo { cargo, .. }
- | project_model::ProjectWorkspaceKind::DetachedFile {
- cargo: Some((cargo, _, _)),
- ..
- } => *cargo.workspace_root() == root,
- _ => false,
- });
- if let Some((idx, _)) = workspace {
+ let workspace = world.workspaces.iter().position(|ws| match &ws.kind {
+ project_model::ProjectWorkspaceKind::Cargo { cargo, .. }
+ | project_model::ProjectWorkspaceKind::DetachedFile {
+ cargo: Some((cargo, _, _)),
+ ..
+ } => *cargo.workspace_root() == root,
+ _ => false,
+ });
+ if let Some(idx) = workspace {
world.flycheck[idx].restart_for_package(package, target);
}
}