818: In `RootConfig::contains`, check against canonicalized version of root path r=matklad a=pnkfelix

In `RootConfig::contains`, check against canonicalized version of root path since OS may hand us data that uses the canonical form rather than the root as specified by the user.

This is a step towards a resolution of issue #734 but does not completely fix the problem there.

Co-authored-by: Felix S. Klock II <pnkfelix@pnkfx.org>
This commit is contained in:
bors[bot] 2019-02-13 21:33:31 +00:00
commit ebfa26658e

View file

@ -44,6 +44,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<PathBuf>,
excluded_dirs: Vec<PathBuf>,
}
@ -60,7 +62,11 @@ impl std::ops::Deref for Roots {
impl RootConfig {
fn new(root: PathBuf, excluded_dirs: Vec<PathBuf>) -> 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<RelativePathBuf> {
@ -68,7 +74,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.