diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 4a2f468de7..3d199ed24a 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -377,6 +377,21 @@ impl ProjectWorkspace { } } + pub fn find_sysroot_proc_macro_srv(&self) -> Option { + match self { + ProjectWorkspace::Cargo { sysroot: Some(sysroot), .. } + | ProjectWorkspace::Json { sysroot: Some(sysroot), .. } => { + let standalone_server_name = + format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX); + ["libexec", "lib"] + .into_iter() + .map(|segment| sysroot.root().join(segment).join(&standalone_server_name)) + .find(|server_path| std::fs::metadata(&server_path).is_ok()) + } + _ => None, + } + } + /// Returns the roots for the current `ProjectWorkspace` /// The return type contains the path and whether or not /// the root is a member of the current workspace diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 5dba545b87..762d7d3a18 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -60,24 +60,12 @@ pub fn load_workspace( }; let proc_macro_client = if load_config.with_proc_macro { - let mut path = AbsPathBuf::assert(std::env::current_exe()?); - let mut args = vec!["proc-macro"]; + let (server_path, args): (_, &[_]) = match ws.find_sysroot_proc_macro_srv() { + Some(server_path) => (server_path, &[]), + None => (AbsPathBuf::assert(std::env::current_exe()?), &["proc-macro"]), + }; - if let ProjectWorkspace::Cargo { sysroot, .. } | ProjectWorkspace::Json { sysroot, .. } = - &ws - { - if let Some(sysroot) = sysroot.as_ref() { - let standalone_server_name = - format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX); - let server_path = sysroot.root().join("libexec").join(&standalone_server_name); - if std::fs::metadata(&server_path).is_ok() { - path = server_path; - args = vec![]; - } - } - } - - ProcMacroServer::spawn(path.clone(), args.clone()).map_err(|e| e.to_string()) + ProcMacroServer::spawn(server_path, args).map_err(|e| e.to_string()) } else { Err("proc macro server disabled".to_owned()) }; diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index aa0510a4ea..fcfe4be0b8 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -305,9 +305,6 @@ impl GlobalState { let files_config = self.config.files(); let project_folders = ProjectFolders::new(&self.workspaces, &files_config.exclude); - let standalone_server_name = - format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX); - if self.proc_macro_clients.is_empty() { if let Some((path, path_manually_set)) = self.config.proc_macro_srv() { tracing::info!("Spawning proc-macro servers"); @@ -315,40 +312,17 @@ impl GlobalState { .workspaces .iter() .map(|ws| { - let (path, args) = if path_manually_set { + let (path, args): (_, &[_]) = if path_manually_set { tracing::debug!( "Pro-macro server path explicitly set: {}", path.display() ); - (path.clone(), vec![]) + (path.clone(), &[]) } else { - let mut sysroot_server = None; - if let ProjectWorkspace::Cargo { sysroot, .. } - | ProjectWorkspace::Json { sysroot, .. } = ws - { - if let Some(sysroot) = sysroot.as_ref() { - let server_path = sysroot - .root() - .join("libexec") - .join(&standalone_server_name); - if std::fs::metadata(&server_path).is_ok() { - tracing::debug!( - "Sysroot proc-macro server exists at {}", - server_path.display() - ); - sysroot_server = Some(server_path); - } else { - tracing::debug!( - "Sysroot proc-macro server does not exist at {}", - server_path.display() - ); - } - } + match ws.find_sysroot_proc_macro_srv() { + Some(server_path) => (server_path, &[]), + None => (path.clone(), &["proc-macro"]), } - sysroot_server.map_or_else( - || (path.clone(), vec!["proc-macro".to_owned()]), - |path| (path, vec![]), - ) }; tracing::info!(?args, "Using proc-macro server at {}", path.display(),);