From 3ab96c40b302d3f84ff7c27355c1d613ef89d65f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 24 Jan 2025 14:23:01 +0100 Subject: [PATCH] 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 --- crates/rust-analyzer/src/flycheck.rs | 11 ++++++++ .../src/handlers/notification.rs | 25 +++++++++++-------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs index 22f06d68d80d..2309f94a7429 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 98efc637c2c8..84ba89d9f31f 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); } }