Unnamed repository; edit this file 'description' to name the repository.
Correctly populate detached files roots
Lukas Wirth 2024-04-19
parent 46f0554 · commit 0ce7179
-rw-r--r--crates/project-model/src/workspace.rs69
-rw-r--r--crates/rust-analyzer/src/handlers/notification.rs1
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs4
-rw-r--r--crates/rust-analyzer/src/reload.rs1
-rw-r--r--crates/rust-analyzer/tests/slow-tests/main.rs7
5 files changed, 65 insertions, 17 deletions
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 7709f99b2e..98c5a02dcd 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -518,7 +518,13 @@ impl ProjectWorkspace {
progress: &dyn Fn(String),
) -> anyhow::Result<WorkspaceBuildScripts> {
match self {
- ProjectWorkspace::Cargo { cargo, toolchain, sysroot, .. } => {
+ ProjectWorkspace::DetachedFile {
+ cargo_script: Some(cargo),
+ toolchain,
+ sysroot,
+ ..
+ }
+ | ProjectWorkspace::Cargo { cargo, toolchain, sysroot, .. } => {
WorkspaceBuildScripts::run_for_workspace(
config,
cargo,
@@ -530,9 +536,8 @@ impl ProjectWorkspace {
format!("Failed to run build scripts for {}", cargo.workspace_root())
})
}
- ProjectWorkspace::Json { .. } | ProjectWorkspace::DetachedFile { .. } => {
- Ok(WorkspaceBuildScripts::default())
- }
+ ProjectWorkspace::DetachedFile { cargo_script: None, .. }
+ | ProjectWorkspace::Json { .. } => Ok(WorkspaceBuildScripts::default()),
}
}
@@ -734,13 +739,50 @@ impl ProjectWorkspace {
}))
.collect()
}
- ProjectWorkspace::DetachedFile { file, sysroot, .. } => iter::once(PackageRoot {
- is_local: true,
- include: vec![file.clone()],
- exclude: Vec::new(),
- })
- .chain(mk_sysroot(sysroot.as_ref()))
- .collect(),
+ ProjectWorkspace::DetachedFile { file, cargo_script, sysroot, .. } => {
+ iter::once(PackageRoot {
+ is_local: true,
+ include: vec![file.clone()],
+ exclude: Vec::new(),
+ })
+ .chain(cargo_script.iter().flat_map(|cargo| {
+ cargo.packages().map(|pkg| {
+ let is_local = cargo[pkg].is_local;
+ let pkg_root = cargo[pkg].manifest.parent().to_path_buf();
+
+ let mut include = vec![pkg_root.clone()];
+
+ // In case target's path is manually set in Cargo.toml to be
+ // outside the package root, add its parent as an extra include.
+ // An example of this situation would look like this:
+ //
+ // ```toml
+ // [lib]
+ // path = "../../src/lib.rs"
+ // ```
+ let extra_targets = cargo[pkg]
+ .targets
+ .iter()
+ .filter(|&&tgt| matches!(cargo[tgt].kind, TargetKind::Lib { .. }))
+ .filter_map(|&tgt| cargo[tgt].root.parent())
+ .map(|tgt| tgt.normalize().to_path_buf())
+ .filter(|path| !path.starts_with(&pkg_root));
+ include.extend(extra_targets);
+
+ let mut exclude = vec![pkg_root.join(".git")];
+ if is_local {
+ exclude.push(pkg_root.join("target"));
+ } else {
+ exclude.push(pkg_root.join("tests"));
+ exclude.push(pkg_root.join("examples"));
+ exclude.push(pkg_root.join("benches"));
+ }
+ PackageRoot { is_local, include, exclude }
+ })
+ }))
+ .chain(mk_sysroot(sysroot.as_ref()))
+ .collect()
+ }
}
}
@@ -756,9 +798,10 @@ impl ProjectWorkspace {
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.num_packages());
cargo.packages().len() + sysroot_package_len + rustc_package_len
}
- ProjectWorkspace::DetachedFile { sysroot, .. } => {
+ ProjectWorkspace::DetachedFile { sysroot, cargo_script, .. } => {
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.num_packages());
- sysroot_package_len + 1
+ sysroot_package_len
+ + cargo_script.as_ref().map_or(1, |cargo| cargo.packages().len())
}
}
}
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index 84065c6848..4b8c3d06ce 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -307,6 +307,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
}
None
}
+ // FIXME
project_model::ProjectWorkspace::DetachedFile { .. } => return None,
};
Some((idx, package))
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index aa5567bb66..cf97d7d9d2 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -1761,7 +1761,9 @@ pub(crate) fn handle_open_docs(
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match ws {
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((cargo, sysroot.as_ref().ok())),
ProjectWorkspace::Json { .. } => None,
- ProjectWorkspace::DetachedFile { .. } => None,
+ ProjectWorkspace::DetachedFile { cargo_script, sysroot, .. } => {
+ cargo_script.as_ref().zip(Some(sysroot.as_ref().ok()))
+ }
});
let (cargo, sysroot) = match ws_and_sysroot {
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 557faaf84c..5d8a66cabc 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -682,6 +682,7 @@ impl GlobalState {
_ => None,
}
}
+ // FIXME
ProjectWorkspace::DetachedFile { .. } => None,
})
.map(|(id, root, sysroot_root)| {
diff --git a/crates/rust-analyzer/tests/slow-tests/main.rs b/crates/rust-analyzer/tests/slow-tests/main.rs
index 22d8b6bdf1..b87f02947b 100644
--- a/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -119,7 +119,8 @@ fn f() {
#[test]
fn completes_items_from_standard_library_in_cargo_script() {
- if skip_slow_tests() {
+ // this test requires nightly so CI can't run it
+ if skip_slow_tests() || std::env::var("CI").is_ok() {
return;
}
@@ -139,7 +140,7 @@ version = "0.1.0"
pub struct SpecialHashMap2;
//- /src/lib.rs
#!/usr/bin/env -S cargo +nightly -Zscript
----cargo
+---
[dependencies]
dependency = { path = "../dependency" }
---
@@ -178,7 +179,7 @@ use dependency2::Spam;
server.write_file_and_save(
"src/lib.rs",
r#"#!/usr/bin/env -S cargo +nightly -Zscript
----cargo
+---
[dependencies]
dependency2 = { path = "../dependency2" }
---