diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index 5dfaaf7742..6d5ca8321e 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs @@ -125,8 +125,10 @@ impl FlycheckHandle { config: FlycheckConfig, sysroot_root: Option, workspace_root: AbsPathBuf, + manifest_path: Option, ) -> FlycheckHandle { - let actor = FlycheckActor::new(id, sender, config, sysroot_root, workspace_root); + let actor = + FlycheckActor::new(id, sender, config, sysroot_root, workspace_root, manifest_path); let (sender, receiver) = unbounded::(); let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) .name("Flycheck".to_owned()) @@ -205,6 +207,7 @@ struct FlycheckActor { id: usize, sender: Box, config: FlycheckConfig, + manifest_path: Option, /// Either the workspace root of the workspace we are flychecking, /// or the project root of the project. root: AbsPathBuf, @@ -233,6 +236,7 @@ impl FlycheckActor { config: FlycheckConfig, sysroot_root: Option, workspace_root: AbsPathBuf, + manifest_path: Option, ) -> FlycheckActor { tracing::info!(%id, ?workspace_root, "Spawning flycheck"); FlycheckActor { @@ -241,6 +245,7 @@ impl FlycheckActor { config, sysroot_root, root: workspace_root, + manifest_path, command_handle: None, command_receiver: None, } @@ -388,8 +393,13 @@ impl FlycheckActor { "--message-format=json" }); - cmd.arg("--manifest-path"); - cmd.arg(self.root.join("Cargo.toml")); + if let Some(manifest_path) = &self.manifest_path { + cmd.arg("--manifest-path"); + cmd.arg(manifest_path); + if manifest_path.extension().map_or(false, |ext| ext == "rs") { + cmd.arg("-Zscript"); + } + } options.apply_on_command(&mut cmd); (cmd, options.extra_args.clone()) diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index f8485d336e..7f845f85ae 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -91,7 +91,7 @@ pub enum ProjectWorkspaceKind { /// The file in question. file: ManifestPath, /// Is this file a cargo script file? - cargo_script: Option<(CargoWorkspace, WorkspaceBuildScripts)>, + cargo: Option<(CargoWorkspace, WorkspaceBuildScripts)>, /// Environment variables set in the `.cargo/config` file. cargo_config_extra_env: FxHashMap, }, @@ -135,7 +135,11 @@ impl fmt::Debug for ProjectWorkspace { .field("n_cfg_overrides", &cfg_overrides.len()); debug_struct.finish() } - ProjectWorkspaceKind::DetachedFile { file, cargo_script, cargo_config_extra_env } => f + ProjectWorkspaceKind::DetachedFile { + file, + cargo: cargo_script, + cargo_config_extra_env, + } => f .debug_struct("DetachedFiles") .field("file", &file) .field("cargo_script", &cargo_script.is_some()) @@ -451,7 +455,7 @@ impl ProjectWorkspace { Ok(ProjectWorkspace { kind: ProjectWorkspaceKind::DetachedFile { file: detached_file.to_owned(), - cargo_script, + cargo: cargo_script, cargo_config_extra_env, }, sysroot, @@ -476,7 +480,7 @@ impl ProjectWorkspace { progress: &dyn Fn(String), ) -> anyhow::Result { match &self.kind { - ProjectWorkspaceKind::DetachedFile { cargo_script: Some((cargo, _)), .. } + ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } | ProjectWorkspaceKind::Cargo { cargo, .. } => { WorkspaceBuildScripts::run_for_workspace( config, @@ -489,7 +493,7 @@ impl ProjectWorkspace { format!("Failed to run build scripts for {}", cargo.workspace_root()) }) } - ProjectWorkspaceKind::DetachedFile { cargo_script: None, .. } + ProjectWorkspaceKind::DetachedFile { cargo: None, .. } | ProjectWorkspaceKind::Json { .. } => Ok(WorkspaceBuildScripts::default()), } } @@ -540,9 +544,9 @@ impl ProjectWorkspace { pub fn set_build_scripts(&mut self, bs: WorkspaceBuildScripts) { match &mut self.kind { ProjectWorkspaceKind::Cargo { build_scripts, .. } - | ProjectWorkspaceKind::DetachedFile { - cargo_script: Some((_, build_scripts)), .. - } => *build_scripts = bs, + | ProjectWorkspaceKind::DetachedFile { cargo: Some((_, build_scripts)), .. } => { + *build_scripts = bs + } _ => assert_eq!(bs, WorkspaceBuildScripts::default()), } } @@ -674,7 +678,7 @@ impl ProjectWorkspace { })) .collect() } - ProjectWorkspaceKind::DetachedFile { file, cargo_script, .. } => { + ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => { iter::once(PackageRoot { is_local: true, include: vec![file.as_ref().to_owned()], @@ -736,7 +740,7 @@ impl ProjectWorkspace { let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); cargo.packages().len() + sysroot_package_len + rustc_package_len } - ProjectWorkspaceKind::DetachedFile { cargo_script, .. } => { + ProjectWorkspaceKind::DetachedFile { cargo: cargo_script, .. } => { let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); sysroot_package_len + cargo_script.as_ref().map_or(1, |(cargo, _)| cargo.packages().len()) @@ -781,7 +785,7 @@ impl ProjectWorkspace { ), sysroot, ), - ProjectWorkspaceKind::DetachedFile { file, cargo_script, .. } => ( + ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => ( if let Some((cargo, build_scripts)) = cargo_script { cargo_to_crate_graph( &mut |path| load(path), @@ -851,12 +855,12 @@ impl ProjectWorkspace { ( ProjectWorkspaceKind::DetachedFile { file, - cargo_script: Some((cargo_script, _)), + cargo: Some((cargo_script, _)), cargo_config_extra_env, }, ProjectWorkspaceKind::DetachedFile { file: o_file, - cargo_script: Some((o_cargo_script, _)), + cargo: Some((o_cargo_script, _)), cargo_config_extra_env: o_cargo_config_extra_env, }, ) => { diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs index d38fcf92ce..85f964b1dd 100644 --- a/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -81,7 +81,7 @@ impl Tester { let workspace = ProjectWorkspace { kind: ProjectWorkspaceKind::DetachedFile { file: ManifestPath::try_from(tmp_file).unwrap(), - cargo_script: None, + cargo: None, cargo_config_extra_env: Default::default(), }, sysroot, diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index d2c9f466e5..1fcb5d4496 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -521,7 +521,7 @@ impl GlobalStateSnapshot { let path = path.as_path()?; self.workspaces.iter().find_map(|ws| match &ws.kind { ProjectWorkspaceKind::Cargo { cargo, .. } - | ProjectWorkspaceKind::DetachedFile { cargo_script: Some((cargo, _)), .. } => { + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => { cargo.target_by_root(path).map(|it| (cargo, it)) } ProjectWorkspaceKind::Json { .. } => None, diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index 253d5498aa..fee8e97273 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -292,7 +292,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { let package = match &ws.kind { project_model::ProjectWorkspaceKind::Cargo { cargo, .. } | project_model::ProjectWorkspaceKind::DetachedFile { - cargo_script: Some((cargo, _)), + cargo: Some((cargo, _)), .. } => cargo.packages().find_map(|pkg| { let has_target_with_root = cargo[pkg] diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index dfefb86207..6afcc2c51f 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -767,7 +767,8 @@ pub(crate) fn handle_parent_module( .workspaces .iter() .filter_map(|ws| match &ws.kind { - ProjectWorkspaceKind::Cargo { cargo, .. } => { + ProjectWorkspaceKind::Cargo { cargo, .. } + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => { cargo.parent_manifests(&manifest_path) } _ => None, @@ -1759,7 +1760,7 @@ pub(crate) fn handle_open_docs( let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind { ProjectWorkspaceKind::Cargo { cargo, .. } - | ProjectWorkspaceKind::DetachedFile { cargo_script: Some((cargo, _)), .. } => { + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => { Some((cargo, ws.sysroot.as_ref().ok())) } ProjectWorkspaceKind::Json { .. } => None, diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 4a2fbaa678..f2b6e3ed03 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -502,7 +502,7 @@ impl GlobalState { let env = match &ws.kind { ProjectWorkspaceKind::Cargo { cargo_config_extra_env, .. } | ProjectWorkspaceKind::DetachedFile { - cargo_script: Some(_), + cargo: Some(_), cargo_config_extra_env, .. } => cargo_config_extra_env @@ -669,36 +669,37 @@ impl GlobalState { config, None, self.config.root_path().clone(), + None, )], flycheck::InvocationStrategy::PerWorkspace => { self.workspaces .iter() .enumerate() - .filter_map(|(id, ws)| match &ws.kind { - ProjectWorkspaceKind::Cargo { cargo, .. } => Some(( + .filter_map(|(id, ws)| { + Some(( id, - cargo.workspace_root(), + match &ws.kind { + ProjectWorkspaceKind::Cargo { cargo, .. } + | ProjectWorkspaceKind::DetachedFile { + cargo: Some((cargo, _)), + .. + } => (cargo.workspace_root(), Some(cargo.manifest_path())), + ProjectWorkspaceKind::Json(project) => { + // Enable flychecks for json projects if a custom flycheck command was supplied + // in the workspace configuration. + match config { + FlycheckConfig::CustomCommand { .. } => { + (project.path(), None) + } + _ => return None, + } + } + ProjectWorkspaceKind::DetachedFile { .. } => return None, + }, ws.sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()), - )), - ProjectWorkspaceKind::Json(project) => { - // Enable flychecks for json projects if a custom flycheck command was supplied - // in the workspace configuration. - match config { - FlycheckConfig::CustomCommand { .. } => Some(( - id, - project.path(), - ws.sysroot - .as_ref() - .ok() - .map(|sysroot| sysroot.root().to_owned()), - )), - _ => None, - } - } - // FIXME - ProjectWorkspaceKind::DetachedFile { .. } => None, + )) }) - .map(|(id, root, sysroot_root)| { + .map(|(id, (root, manifest_path), sysroot_root)| { let sender = sender.clone(); FlycheckHandle::spawn( id, @@ -706,6 +707,7 @@ impl GlobalState { config.clone(), sysroot_root, root.to_path_buf(), + manifest_path.map(|it| it.to_path_buf()), ) }) .collect()