about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-04-19 16:15:10 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-04-19 18:25:10 +0200
commit0ce7179e6b56dcc931b2892071602a0f09f99c2a (patch)
tree7faf2875b7e7e98dd33ed6dec398cd5eb112eaf4
parent46f05543a2520af5dced5667e5d2c16586539ffa (diff)
downloadrust-0ce7179e6b56dcc931b2892071602a0f09f99c2a.tar.gz
rust-0ce7179e6b56dcc931b2892071602a0f09f99c2a.zip
Correctly populate detached files roots
-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 7709f99b2e9..98c5a02dcdc 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 84065c68487..4b8c3d06ce4 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 aa5567bb666..cf97d7d9d23 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 557faaf84ca..5d8a66cabc7 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 22d8b6bdf18..b87f02947bf 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" }
 ---