From 8a57a66513075838d2af0ca4655afe008d0e769c Mon Sep 17 00:00:00 2001 From: Ethan Donowitz Date: Sun, 19 Oct 2025 12:51:11 -0400 Subject: [PATCH] bug: Use manifest path as reported buildfile Previously, we were reporting the workspace Cargo.toml as the buildfile for a `discover` invocation. This led to incorrect behavior where RA would "unindex" any crates that were included in the first `discover` invocation but not in subsequent invocations (reporting the buildfile as the workspace Cargo.toml implies that we are telling RA about all of the crates in the workspace, but we are actually only telling it about a subset). Consider the following dependency graph: ``` A: C B: C C: ``` If we're invoked with a file from crate `A`, we would tell RA about crates `A` and `C` with the workspace manifest as the buildfile. If we are subsequently invoked with a file from crate `B`, we'd still report the buildfile as the workspace manifest, but now we'd only tell RA about crates `B` and `C`. This causes RA to "unindex" `A`, since we're telling RA that the workspace doesn't include it. This commit rectifies the issue by reporting the current crate's Cargo.toml as the buildfile in the `discover` output. However, this changes the semantics of how and when `check` is invoked. In the above example, we'd now report two separate "projects" after being invoked with files from crates `A` and `B`. Because `A` and `B` do not depend on each other, RA will invoke `check` separately for each of them. This is rather annoying if they share many dependencies (e.g. if `C` has a giant dependency tree), since those `check` invocations will be duplicating a lot of work. This behavior can be adjusted by setting RA's `check.invocationStrategy` setting to `"once"`, which tells it just to invoke check for the current project instead of all the projects we've told it about. This commit also updates the README to reflect this change. Fixes #34 --- README.md | 3 +++ src/main.rs | 17 +---------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 9f0dbb4..5918d9a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Add the following to your `settings.json`: "Cargo.toml" ] }, + "rust-analyzer.check.invocationStrategy": "once", "rust-analyzer.check.overrideCommand": [ "cargo-subspace", "check", // You can also use "clippy" here @@ -115,6 +116,7 @@ also be set via lspconfig. ```lua ["rust-analyzer"] = { check = { + invocationStrategy = "once", overrideCommand = { "cargo-subspace", "clippy", @@ -149,6 +151,7 @@ These settings should be specified in `Settings --> LSP Client --> User Server S "useWorkspace": false, "initializationOptions": { "check": { + "invocationStrategy": "once", "overrideCommand": [ "cargo-subspace", "clippy", diff --git a/src/main.rs b/src/main.rs index ccfa76e..9e88a82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -217,23 +217,8 @@ fn discover(ctx: &Context, discover_args: DiscoverArgs, manifest_path: FilePath< let metadata = cmd.exec()?; let project = compute_project_json(ctx, discover_args, metadata, manifest_path)?; - let root = ctx - .cargo() - .arg("locate-project") - .arg("--workspace") - .arg("--manifest-path") - .arg(manifest_path) - .arg("--message-format") - .arg("plain") - .output()?; - let buildfile: PathBuf = String::from_utf8(root.stdout)?.trim().into(); let output = DiscoverProjectData::Finished { - buildfile: Utf8PathBuf::from_path_buf(buildfile).map_err(|e| { - anyhow!( - "Manifest path `{}` contains non-UTF-8 characters", - e.display() - ) - })?, + buildfile: manifest_path.to_path_buf(), project, }; let json = if ctx.is_tty {