Unnamed repository; edit this file 'description' to name the repository.
fix: Report metadata errors for sysroot
Shoyu Vanilla 6 months ago
parent dcab2ad · commit 5c53759
-rw-r--r--crates/project-model/src/sysroot.rs28
-rw-r--r--crates/project-model/src/tests.rs2
-rw-r--r--crates/project-model/src/workspace.rs4
-rw-r--r--crates/rust-analyzer/src/reload.rs10
4 files changed, 34 insertions, 10 deletions
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs
index 272cf7dada..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,
@@ -293,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())
@@ -332,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)?;
@@ -387,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 a79c8640fa..711cdd11b9 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -248,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 957f336ee4..22b84791ae 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -743,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 {
@@ -1731,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/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!(