mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
fix: ensure that the parent of a SourceRoot cannot be itself
This commit is contained in:
parent
72dfbe95de
commit
733995c0d7
1 changed files with 23 additions and 3 deletions
|
@ -285,7 +285,6 @@ impl SourceRootConfig {
|
||||||
/// If a `SourceRoot` doesn't have a parent and is local then it is not contained in this mapping but it can be asserted that it is a root `SourceRoot`.
|
/// If a `SourceRoot` doesn't have a parent and is local then it is not contained in this mapping but it can be asserted that it is a root `SourceRoot`.
|
||||||
pub fn source_root_parent_map(&self) -> FxHashMap<SourceRootId, SourceRootId> {
|
pub fn source_root_parent_map(&self) -> FxHashMap<SourceRootId, SourceRootId> {
|
||||||
let roots = self.fsc.roots();
|
let roots = self.fsc.roots();
|
||||||
let mut i = 0;
|
|
||||||
roots
|
roots
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -293,9 +292,14 @@ impl SourceRootConfig {
|
||||||
.filter_map(|(idx, (root, root_id))| {
|
.filter_map(|(idx, (root, root_id))| {
|
||||||
// We are interested in parents if they are also local source roots.
|
// We are interested in parents if they are also local source roots.
|
||||||
// So instead of a non-local parent we may take a local ancestor as a parent to a node.
|
// So instead of a non-local parent we may take a local ancestor as a parent to a node.
|
||||||
|
//
|
||||||
|
// Here paths in roots are sorted lexicographically, so if a root
|
||||||
|
// is a parent of another root, it will be before it in the list.
|
||||||
roots[..idx].iter().find_map(|(root2, root2_id)| {
|
roots[..idx].iter().find_map(|(root2, root2_id)| {
|
||||||
i += 1;
|
if self.local_filesets.contains(root2_id)
|
||||||
if self.local_filesets.contains(root2_id) && root.starts_with(root2) {
|
&& root.starts_with(root2)
|
||||||
|
&& root_id != root2_id
|
||||||
|
{
|
||||||
return Some((root_id, root2_id));
|
return Some((root_id, root2_id));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -572,4 +576,20 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(vc, vec![(SourceRootId(3), SourceRootId(1)),])
|
assert_eq!(vc, vec![(SourceRootId(3), SourceRootId(1)),])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parents_with_identical_root_id() {
|
||||||
|
let mut builder = FileSetConfigBuilder::default();
|
||||||
|
builder.add_file_set(vec![
|
||||||
|
VfsPath::new_virtual_path("/ROOT/def".to_owned()),
|
||||||
|
VfsPath::new_virtual_path("/ROOT/def/abc/def".to_owned()),
|
||||||
|
]);
|
||||||
|
builder.add_file_set(vec![VfsPath::new_virtual_path("/ROOT/def/abc/def/ghi".to_owned())]);
|
||||||
|
let fsc = builder.build();
|
||||||
|
let src = SourceRootConfig { fsc, local_filesets: vec![0, 1] };
|
||||||
|
let mut vc = src.source_root_parent_map().into_iter().collect::<Vec<_>>();
|
||||||
|
vc.sort_by(|x, y| x.0 .0.cmp(&y.0 .0));
|
||||||
|
|
||||||
|
assert_eq!(vc, vec![(SourceRootId(1), SourceRootId(0)),])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue