Skip to content

Commit 2c5beeb

Browse files
committed
Correctly populate detached files roots
1 parent 0e574eb commit 2c5beeb

File tree

5 files changed

+63
-16
lines changed

5 files changed

+63
-16
lines changed

crates/project-model/src/workspace.rs

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,13 @@ impl ProjectWorkspace {
505505
progress: &dyn Fn(String),
506506
) -> anyhow::Result<WorkspaceBuildScripts> {
507507
match self {
508-
ProjectWorkspace::Cargo { cargo, toolchain, sysroot, .. } => {
508+
ProjectWorkspace::DetachedFile {
509+
cargo_script: Some(cargo),
510+
toolchain,
511+
sysroot,
512+
..
513+
}
514+
| ProjectWorkspace::Cargo { cargo, toolchain, sysroot, .. } => {
509515
WorkspaceBuildScripts::run_for_workspace(
510516
config,
511517
cargo,
@@ -517,9 +523,8 @@ impl ProjectWorkspace {
517523
format!("Failed to run build scripts for {}", cargo.workspace_root())
518524
})
519525
}
520-
ProjectWorkspace::Json { .. } | ProjectWorkspace::DetachedFile { .. } => {
521-
Ok(WorkspaceBuildScripts::default())
522-
}
526+
ProjectWorkspace::DetachedFile { cargo_script: None, .. }
527+
| ProjectWorkspace::Json { .. } => Ok(WorkspaceBuildScripts::default()),
523528
}
524529
}
525530

@@ -720,13 +725,50 @@ impl ProjectWorkspace {
720725
}))
721726
.collect()
722727
}
723-
ProjectWorkspace::DetachedFile { file, sysroot, .. } => iter::once(PackageRoot {
724-
is_local: true,
725-
include: vec![file.clone()],
726-
exclude: Vec::new(),
727-
})
728-
.chain(mk_sysroot(sysroot.as_ref()))
729-
.collect(),
728+
ProjectWorkspace::DetachedFile { file, cargo_script, sysroot, .. } => {
729+
iter::once(PackageRoot {
730+
is_local: true,
731+
include: vec![file.clone()],
732+
exclude: Vec::new(),
733+
})
734+
.chain(cargo_script.iter().flat_map(|cargo| {
735+
cargo.packages().map(|pkg| {
736+
let is_local = cargo[pkg].is_local;
737+
let pkg_root = cargo[pkg].manifest.parent().to_path_buf();
738+
739+
let mut include = vec![pkg_root.clone()];
740+
741+
// In case target's path is manually set in Cargo.toml to be
742+
// outside the package root, add its parent as an extra include.
743+
// An example of this situation would look like this:
744+
//
745+
// ```toml
746+
// [lib]
747+
// path = "../../src/lib.rs"
748+
// ```
749+
let extra_targets = cargo[pkg]
750+
.targets
751+
.iter()
752+
.filter(|&&tgt| matches!(cargo[tgt].kind, TargetKind::Lib { .. }))
753+
.filter_map(|&tgt| cargo[tgt].root.parent())
754+
.map(|tgt| tgt.normalize().to_path_buf())
755+
.filter(|path| !path.starts_with(&pkg_root));
756+
include.extend(extra_targets);
757+
758+
let mut exclude = vec![pkg_root.join(".git")];
759+
if is_local {
760+
exclude.push(pkg_root.join("target"));
761+
} else {
762+
exclude.push(pkg_root.join("tests"));
763+
exclude.push(pkg_root.join("examples"));
764+
exclude.push(pkg_root.join("benches"));
765+
}
766+
PackageRoot { is_local, include, exclude }
767+
})
768+
}))
769+
.chain(mk_sysroot(sysroot.as_ref()))
770+
.collect()
771+
}
730772
}
731773
}
732774

@@ -742,9 +784,10 @@ impl ProjectWorkspace {
742784
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.num_packages());
743785
cargo.packages().len() + sysroot_package_len + rustc_package_len
744786
}
745-
ProjectWorkspace::DetachedFile { sysroot, .. } => {
787+
ProjectWorkspace::DetachedFile { sysroot, cargo_script, .. } => {
746788
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.num_packages());
747-
sysroot_package_len + 1
789+
sysroot_package_len
790+
+ cargo_script.as_ref().map_or(1, |cargo| cargo.packages().len())
748791
}
749792
}
750793
}

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
@@ -681,6 +681,7 @@ impl GlobalState {
681681
_ => None,
682682
}
683683
}
684+
// FIXME
684685
ProjectWorkspace::DetachedFile { .. } => None,
685686
})
686687
.map(|(id, root, sysroot_root)| {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ version = "0.1.0"
139139
pub struct SpecialHashMap2;
140140
//- /src/lib.rs
141141
#!/usr/bin/env -S cargo +nightly -Zscript
142-
---cargo
142+
---
143143
[dependencies]
144144
dependency = { path = "../dependency" }
145145
---
@@ -178,7 +178,7 @@ use dependency2::Spam;
178178
server.write_file_and_save(
179179
"src/lib.rs",
180180
r#"#!/usr/bin/env -S cargo +nightly -Zscript
181-
---cargo
181+
---
182182
[dependencies]
183183
dependency2 = { path = "../dependency2" }
184184
---

0 commit comments

Comments
 (0)