Unnamed repository; edit this file 'description' to name the repository.
fix: load rust-analyzer.toml for virtual workspaces
Matt "Siyuan" Yan 6 weeks ago
parent ff041aa · commit 865e224
-rw-r--r--crates/load-cargo/src/lib.rs27
-rw-r--r--crates/rust-analyzer/tests/slow-tests/ratoml.rs42
2 files changed, 69 insertions, 0 deletions
diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs
index 654ff4f75b..c91acd9cf9 100644
--- a/crates/load-cargo/src/lib.rs
+++ b/crates/load-cargo/src/lib.rs
@@ -282,6 +282,19 @@ impl ProjectFolders {
}
}
+ // Collect workspace roots not already covered by a local PackageRoot
+ // (e.g. virtual workspaces where no package lives at the workspace root).
+ // We need these to load workspace-root rust-analyzer.toml into a local source root.
+ let uncovered_ws_roots: Vec<AbsPathBuf> = workspaces
+ .iter()
+ .filter_map(|ws| {
+ let ws_root = ws.workspace_root().to_path_buf();
+ let dominated =
+ roots.iter().any(|root| root.is_local && root.include.contains(&ws_root));
+ (!dominated).then_some(ws_root)
+ })
+ .collect();
+
for root in roots.into_iter().filter(|it| !it.include.is_empty()) {
let file_set_roots: Vec<VfsPath> =
root.include.iter().cloned().map(VfsPath::from).collect();
@@ -334,6 +347,20 @@ impl ProjectFolders {
}
}
+ // For virtual workspaces, the workspace root has no local PackageRoot, so
+ // rust-analyzer.toml there would fall into a library source root and be
+ // ignored. Load it explicitly via Entry::Files and register the workspace
+ // root as a local file-set root so the file is classified as local.
+ for ws_root in &uncovered_ws_roots {
+ let ratoml_path = ws_root.join("rust-analyzer.toml");
+ let file_set_roots = vec![VfsPath::from(ws_root.clone())];
+ let entry = vfs::loader::Entry::Files(vec![ratoml_path]);
+ res.watch.push(res.load.len());
+ res.load.push(entry);
+ local_filesets.push(fsc.len() as u64);
+ fsc.add_file_set(file_set_roots);
+ }
+
if let Some(user_config_path) = user_config_dir_path {
let ratoml_path = {
let mut p = user_config_path.to_path_buf();
diff --git a/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/crates/rust-analyzer/tests/slow-tests/ratoml.rs
index cac7efd84a..dd113babff 100644
--- a/crates/rust-analyzer/tests/slow-tests/ratoml.rs
+++ b/crates/rust-analyzer/tests/slow-tests/ratoml.rs
@@ -1008,3 +1008,45 @@ fn main() {
InternalTestingFetchConfigResponse::CheckWorkspace(true),
);
}
+
+#[test]
+fn ratoml_virtual_workspace() {
+ if skip_slow_tests() {
+ return;
+ }
+
+ let server = RatomlTest::new(
+ vec![
+ r#"
+//- /p1/Cargo.toml
+[workspace]
+members = ["member"]
+"#,
+ r#"
+//- /p1/rust-analyzer.toml
+assist.emitMustUse = true
+"#,
+ r#"
+//- /p1/member/Cargo.toml
+[package]
+name = "member"
+version = "0.1.0"
+edition = "2021"
+"#,
+ r#"
+//- /p1/member/src/lib.rs
+pub fn add(left: usize, right: usize) -> usize {
+ left + right
+}
+"#,
+ ],
+ vec!["p1"],
+ None,
+ );
+
+ server.query(
+ InternalTestingFetchConfigOption::AssistEmitMustUse,
+ 3,
+ InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+ );
+}