Skip to content

Commit 0ce7179

Browse files
committed
Correctly populate detached files roots
1 parent 46f0554 commit 0ce7179

File tree

5 files changed

+65
-17
lines changed

5 files changed

+65
-17
lines changed

crates/project-model/src/workspace.rs

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,13 @@ impl ProjectWorkspace {
518518
progress: &dyn Fn(String),
519519
) -> anyhow::Result<WorkspaceBuildScripts> {
520520
match self {
521-
ProjectWorkspace::Cargo { cargo, toolchain, sysroot, .. } => {
521+
ProjectWorkspace::DetachedFile {
522+
cargo_script: Some(cargo),
523+
toolchain,
524+
sysroot,
525+
..
526+
}
527+
| ProjectWorkspace::Cargo { cargo, toolchain, sysroot, .. } => {
522528
WorkspaceBuildScripts::run_for_workspace(
523529
config,
524530
cargo,
@@ -530,9 +536,8 @@ impl ProjectWorkspace {
530536
format!("Failed to run build scripts for {}", cargo.workspace_root())
531537
})
532538
}
533-
ProjectWorkspace::Json { .. } | ProjectWorkspace::DetachedFile { .. } => {
534-
Ok(WorkspaceBuildScripts::default())
535-
}
539+
ProjectWorkspace::DetachedFile { cargo_script: None, .. }
540+
| ProjectWorkspace::Json { .. } => Ok(WorkspaceBuildScripts::default()),
536541
}
537542
}
538543

@@ -734,13 +739,50 @@ impl ProjectWorkspace {
734739
}))
735740
.collect()
736741
}
737-
ProjectWorkspace::DetachedFile { file, sysroot, .. } => iter::once(PackageRoot {
738-
is_local: true,
739-
include: vec![file.clone()],
740-
exclude: Vec::new(),
741-
})
742-
.chain(mk_sysroot(sysroot.as_ref()))
743-
.collect(),
742+
ProjectWorkspace::DetachedFile { file, cargo_script, sysroot, .. } => {
743+
iter::once(PackageRoot {
744+
is_local: true,
745+
include: vec![file.clone()],
746+
exclude: Vec::new(),
747+
})
748+
.chain(cargo_script.iter().flat_map(|cargo| {
749+
cargo.packages().map(|pkg| {
750+
let is_local = cargo[pkg].is_local;
751+
let pkg_root = cargo[pkg].manifest.parent().to_path_buf();
752+
753+
let mut include = vec![pkg_root.clone()];
754+
755+
// In case target's path is manually set in Cargo.toml to be
756+
// outside the package root, add its parent as an extra include.
757+
// An example of this situation would look like this:
758+
//
759+
// ```toml
760+
// [lib]
761+
// path = "../../src/lib.rs"
762+
// ```
763+
let extra_targets = cargo[pkg]
764+
.targets
765+
.iter()
766+
.filter(|&&tgt| matches!(cargo[tgt].kind, TargetKind::Lib { .. }))
767+
.filter_map(|&tgt| cargo[tgt].root.parent())
768+
.map(|tgt| tgt.normalize().to_path_buf())
769+
.filter(|path| !path.starts_with(&pkg_root));
770+
include.extend(extra_targets);
771+
772+
let mut exclude = vec![pkg_root.join(".git")];
773+
if is_local {
774+
exclude.push(pkg_root.join("target"));
775+
} else {
776+
exclude.push(pkg_root.join("tests"));
777+
exclude.push(pkg_root.join("examples"));
778+
exclude.push(pkg_root.join("benches"));
779+
}
780+
PackageRoot { is_local, include, exclude }
781+
})
782+
}))
783+
.chain(mk_sysroot(sysroot.as_ref()))
784+
.collect()
785+
}
744786
}
745787
}
746788

@@ -756,9 +798,10 @@ impl ProjectWorkspace {
756798
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.num_packages());
757799
cargo.packages().len() + sysroot_package_len + rustc_package_len
758800
}
759-
ProjectWorkspace::DetachedFile { sysroot, .. } => {
801+
ProjectWorkspace::DetachedFile { sysroot, cargo_script, .. } => {
760802
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.num_packages());
761-
sysroot_package_len + 1
803+
sysroot_package_len
804+
+ cargo_script.as_ref().map_or(1, |cargo| cargo.packages().len())
762805
}
763806
}
764807
}

crates/rust-analyzer/src/handlers/notification.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
307307
}
308308
None
309309
}
310+
// FIXME
310311
project_model::ProjectWorkspace::DetachedFile { .. } => return None,
311312
};
312313
Some((idx, package))

crates/rust-analyzer/src/handlers/request.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1761,7 +1761,9 @@ pub(crate) fn handle_open_docs(
17611761
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match ws {
17621762
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((cargo, sysroot.as_ref().ok())),
17631763
ProjectWorkspace::Json { .. } => None,
1764-
ProjectWorkspace::DetachedFile { .. } => None,
1764+
ProjectWorkspace::DetachedFile { cargo_script, sysroot, .. } => {
1765+
cargo_script.as_ref().zip(Some(sysroot.as_ref().ok()))
1766+
}
17651767
});
17661768

17671769
let (cargo, sysroot) = match ws_and_sysroot {

crates/rust-analyzer/src/reload.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ impl GlobalState {
682682
_ => None,
683683
}
684684
}
685+
// FIXME
685686
ProjectWorkspace::DetachedFile { .. } => None,
686687
})
687688
.map(|(id, root, sysroot_root)| {

crates/rust-analyzer/tests/slow-tests/main.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ fn f() {
119119

120120
#[test]
121121
fn completes_items_from_standard_library_in_cargo_script() {
122-
if skip_slow_tests() {
122+
// this test requires nightly so CI can't run it
123+
if skip_slow_tests() || std::env::var("CI").is_ok() {
123124
return;
124125
}
125126

@@ -139,7 +140,7 @@ version = "0.1.0"
139140
pub struct SpecialHashMap2;
140141
//- /src/lib.rs
141142
#!/usr/bin/env -S cargo +nightly -Zscript
142-
---cargo
143+
---
143144
[dependencies]
144145
dependency = { path = "../dependency" }
145146
---
@@ -178,7 +179,7 @@ use dependency2::Spam;
178179
server.write_file_and_save(
179180
"src/lib.rs",
180181
r#"#!/usr/bin/env -S cargo +nightly -Zscript
181-
---cargo
182+
---
182183
[dependencies]
183184
dependency2 = { path = "../dependency2" }
184185
---

0 commit comments

Comments
 (0)