Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20866 from ShoyuVanilla/metadata-err
fix: Run `cargo metadata` on sysroot with cwd=sysroot
| -rw-r--r-- | crates/project-model/src/sysroot.rs | 31 | ||||
| -rw-r--r-- | crates/project-model/src/tests.rs | 3 | ||||
| -rw-r--r-- | crates/project-model/src/workspace.rs | 8 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/cli/rustc_tests.rs | 1 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/reload.rs | 10 |
5 files changed, 35 insertions, 18 deletions
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs index c0a5009afb..5cc399bfe7 100644 --- a/crates/project-model/src/sysroot.rs +++ b/crates/project-model/src/sysroot.rs @@ -30,7 +30,7 @@ pub struct Sysroot { #[derive(Debug, Clone, Eq, PartialEq)] pub enum RustLibSrcWorkspace { - Workspace(CargoWorkspace), + Workspace { ws: CargoWorkspace, metadata_err: Option<String> }, Json(ProjectJson), Stitched(stitched::Stitched), Empty, @@ -39,7 +39,9 @@ pub enum RustLibSrcWorkspace { impl fmt::Display for RustLibSrcWorkspace { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - RustLibSrcWorkspace::Workspace(ws) => write!(f, "workspace {}", ws.workspace_root()), + RustLibSrcWorkspace::Workspace { ws, .. } => { + write!(f, "workspace {}", ws.workspace_root()) + } RustLibSrcWorkspace::Json(json) => write!(f, "json {}", json.manifest_or_root()), RustLibSrcWorkspace::Stitched(stitched) => { write!(f, "stitched with {} crates", stitched.crates.len()) @@ -74,7 +76,7 @@ impl Sysroot { pub fn is_rust_lib_src_empty(&self) -> bool { match &self.workspace { - RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(), + RustLibSrcWorkspace::Workspace { ws, .. } => ws.packages().next().is_none(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0, RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(), RustLibSrcWorkspace::Empty => true, @@ -85,9 +87,16 @@ impl Sysroot { self.error.as_deref() } + pub fn metadata_error(&self) -> Option<&str> { + match &self.workspace { + RustLibSrcWorkspace::Workspace { metadata_err, .. } => metadata_err.as_deref(), + _ => None, + } + } + pub fn num_packages(&self) -> usize { match &self.workspace { - RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(), + RustLibSrcWorkspace::Workspace { ws, .. } => ws.packages().count(), RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(), RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.len(), RustLibSrcWorkspace::Empty => 0, @@ -210,7 +219,6 @@ impl Sysroot { &self, sysroot_source_config: &RustSourceWorkspaceConfig, no_deps: bool, - current_dir: &AbsPath, target_dir: &Utf8Path, progress: &dyn Fn(String), ) -> Option<RustLibSrcWorkspace> { @@ -224,7 +232,7 @@ impl Sysroot { if fs::metadata(&library_manifest).is_ok() { match self.load_library_via_cargo( &library_manifest, - current_dir, + src_root, target_dir, cargo_config, no_deps, @@ -294,7 +302,9 @@ impl Sysroot { && let Some(src_root) = &self.rust_lib_src_root { let has_core = match &self.workspace { - RustLibSrcWorkspace::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), + RustLibSrcWorkspace::Workspace { ws: workspace, .. } => { + workspace.packages().any(|p| workspace[p].name == "core") + } RustLibSrcWorkspace::Json(project_json) => project_json .crates() .filter_map(|(_, krate)| krate.display_name.clone()) @@ -333,7 +343,7 @@ impl Sysroot { // Make sure we never attempt to write to the sysroot let locked = true; - let (mut res, _) = + let (mut res, err) = FetchMetadata::new(library_manifest, current_dir, &cargo_config, self, no_deps) .exec(target_dir, locked, progress)?; @@ -388,7 +398,10 @@ impl Sysroot { let cargo_workspace = CargoWorkspace::new(res, library_manifest.clone(), Default::default(), true); - Ok(RustLibSrcWorkspace::Workspace(cargo_workspace)) + Ok(RustLibSrcWorkspace::Workspace { + ws: cargo_workspace, + metadata_err: err.map(|e| format!("{e:#}")), + }) } } diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 987d381fac..711cdd11b9 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -241,7 +241,6 @@ fn smoke_test_real_sysroot_cargo() { let loaded_sysroot = sysroot.load_workspace( &RustSourceWorkspaceConfig::default_cargo(), false, - &cwd, &Utf8PathBuf::default(), &|_| (), ); @@ -249,7 +248,7 @@ fn smoke_test_real_sysroot_cargo() { sysroot.set_workspace(loaded_sysroot); } assert!( - matches!(sysroot.workspace(), RustLibSrcWorkspace::Workspace(_)), + matches!(sysroot.workspace(), RustLibSrcWorkspace::Workspace { .. }), "got {}", sysroot.workspace() ); diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 0649ce9eeb..22b84791ae 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -383,7 +383,6 @@ impl ProjectWorkspace { toolchain.clone(), )), config.no_deps, - workspace_dir, &target_dir, progress, ) @@ -487,7 +486,6 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::Json(*sysroot_project), config.no_deps, - project_root, &target_dir, progress, ) @@ -499,7 +497,6 @@ impl ProjectWorkspace { toolchain.clone(), )), config.no_deps, - project_root, &target_dir, progress, ) @@ -561,7 +558,6 @@ impl ProjectWorkspace { toolchain.clone(), )), config.no_deps, - dir, &target_dir, &|_| (), ); @@ -747,7 +743,7 @@ impl ProjectWorkspace { pub fn to_roots(&self) -> Vec<PackageRoot> { let mk_sysroot = || { let mut r = match self.sysroot.workspace() { - RustLibSrcWorkspace::Workspace(ws) => ws + RustLibSrcWorkspace::Workspace { ws, .. } => ws .packages() .filter_map(|pkg| { if ws[pkg].is_local { @@ -1735,7 +1731,7 @@ fn sysroot_to_crate_graph( ) -> (SysrootPublicDeps, Option<CrateBuilderId>) { let _p = tracing::info_span!("sysroot_to_crate_graph").entered(); match sysroot.workspace() { - RustLibSrcWorkspace::Workspace(cargo) => { + RustLibSrcWorkspace::Workspace { ws: cargo, .. } => { let (sysroot_cg, sysroot_pm) = cargo_to_crate_graph( load, None, diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs index 609ebf2b51..20567149bb 100644 --- a/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -78,7 +78,6 @@ impl Tester { let loaded_sysroot = sysroot.load_workspace( &RustSourceWorkspaceConfig::default_cargo(), false, - &path, &Utf8PathBuf::default(), &|_| (), ); diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index ca15e6a98e..1475f02447 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -222,6 +222,16 @@ impl GlobalState { message.push_str(err); message.push_str("\n\n"); } + if let Some(err) = ws.sysroot.metadata_error() { + status.health |= lsp_ext::Health::Warning; + format_to!( + message, + "Failed to read Cargo metadata with dependencies for sysroot of `{}`: ", + ws.manifest_or_root() + ); + message.push_str(err); + message.push_str("\n\n"); + } if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(err)), .. } = &ws.kind { status.health |= lsp_ext::Health::Warning; format_to!( |