From cfed7c59f49d4a4dd5ac001f520278583c883559 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 13 Feb 2019 17:16:28 +0100 Subject: In `RootConfig::contains`, check against canonicalized version of root path since OS may hand us data that uses that rather than the root as specified by the user. --- crates/ra_vfs/src/lib.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'crates/ra_vfs') diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 5d98d905c..2c3c35f28 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -42,6 +42,8 @@ impl_arena_id!(VfsRoot); /// returns `true` iff path belongs to the source root pub(crate) struct RootConfig { root: PathBuf, + // result of `root.canonicalize()` if that differs from `root`; `None` otherwise. + canonical_root: Option, excluded_dirs: Vec, } @@ -58,7 +60,11 @@ impl std::ops::Deref for Roots { impl RootConfig { fn new(root: PathBuf, excluded_dirs: Vec) -> RootConfig { - RootConfig { root, excluded_dirs } + let mut canonical_root = root.canonicalize().ok(); + if Some(&root) == canonical_root.as_ref() { + canonical_root = None; + } + RootConfig { root, canonical_root, excluded_dirs } } /// Checks if root contains a path and returns a root-relative path. pub(crate) fn contains(&self, path: &Path) -> Option { @@ -66,7 +72,14 @@ impl RootConfig { if self.excluded_dirs.iter().any(|it| path.starts_with(it)) { return None; } - let rel_path = path.strip_prefix(&self.root).ok()?; + let rel_path = path.strip_prefix(&self.root) + .or_else(|err_payload| { + self.canonical_root + .as_ref() + .map_or(Err(err_payload), + |canonical_root| path.strip_prefix(canonical_root)) + }) + .ok()?; let rel_path = RelativePathBuf::from_path(rel_path).ok()?; // Ignore some common directories. -- cgit v1.2.3