From e3498121b4700f5a9dce9bf6d72af4bc411e262d Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 24 Dec 2025 16:36:18 +0100 Subject: [PATCH] [ty] Fix module resolution on network drives (#22173) --- crates/ruff_db/src/system/os.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/ruff_db/src/system/os.rs b/crates/ruff_db/src/system/os.rs index 92513b72d8..f553dff1be 100644 --- a/crates/ruff_db/src/system/os.rs +++ b/crates/ruff_db/src/system/os.rs @@ -275,16 +275,16 @@ impl OsSystem { /// instead of at least one system call for each component between `path` and `prefix`. /// /// However, using `canonicalize` to resolve the path's casing doesn't work in two cases: - /// * if `path` is a symlink because `canonicalize` then returns the symlink's target and not the symlink's source path. - /// * on Windows: If `path` is a mapped network drive because `canonicalize` then returns the UNC path - /// (e.g. `Z:\` is mapped to `\\server\share` and `canonicalize` then returns `\\?\UNC\server\share`). + /// * if `path` is a symlink, `canonicalize` returns the symlink's target and not the symlink's source path. + /// * on Windows: If `path` is a mapped network drive, `canonicalize` returns the UNC path + /// (e.g. `Z:\` is mapped to `\\server\share` and `canonicalize` returns `\\?\UNC\server\share`). /// /// Symlinks and mapped network drives should be rare enough that this fast path is worth trying first, /// even if it comes at a cost for those rare use cases. fn path_exists_case_sensitive_fast(&self, path: &SystemPath) -> Option { // This is a more forgiving version of `dunce::simplified` that removes all `\\?\` prefixes on Windows. // We use this more forgiving version because we don't intend on using either path for anything other than comparison - // and the prefix is only relevant when passing the path to other programs and its longer than 200 something + // and the prefix is only relevant when passing the path to other programs and it's longer than 200 something // characters. fn simplify_ignore_verbatim(path: &SystemPath) -> &SystemPath { if cfg!(windows) { @@ -298,9 +298,7 @@ impl OsSystem { } } - let simplified = simplify_ignore_verbatim(path); - - let Ok(canonicalized) = simplified.as_std_path().canonicalize() else { + let Ok(canonicalized) = path.as_std_path().canonicalize() else { // The path doesn't exist or can't be accessed. The path doesn't exist. return Some(false); }; @@ -309,12 +307,13 @@ impl OsSystem { // The original path is valid UTF8 but the canonicalized path isn't. This definitely suggests // that a symlink is involved. Fall back to the slow path. tracing::debug!( - "Falling back to the slow case-sensitive path existence check because the canonicalized path of `{simplified}` is not valid UTF-8" + "Falling back to the slow case-sensitive path existence check because the canonicalized path of `{path}` is not valid UTF-8" ); return None; }; let simplified_canonicalized = simplify_ignore_verbatim(&canonicalized); + let simplified = simplify_ignore_verbatim(path); // Test if the paths differ by anything other than casing. If so, that suggests that // `path` pointed to a symlink (or some other none reversible path normalization happened).