From 9108b046423b399b8a72b85ea5e69fc3738f5e5b Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 27 Aug 2025 07:43:03 -0400 Subject: [PATCH] Support file or directory removal for Windows symlinks (#15543) ## Summary Similar to https://github.com/rust-lang/cargo/pull/13910. I think this should close https://github.com/astral-sh/uv/issues/15541 since we're indiscriminately calling `remove_dir` on that dangling symlink. --- crates/uv-cache/src/removal.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/crates/uv-cache/src/removal.rs b/crates/uv-cache/src/removal.rs index c827b5e80..d37004dcc 100644 --- a/crates/uv-cache/src/removal.rs +++ b/crates/uv-cache/src/removal.rs @@ -64,9 +64,22 @@ impl Removal { // Remove the file. self.total_bytes += metadata.len(); - if cfg!(windows) && metadata.is_symlink() { - // Remove the junction. - remove_dir(path)?; + if metadata.is_symlink() { + #[cfg(windows)] + { + use std::os::windows::fs::FileTypeExt; + + if metadata.file_type().is_symlink_dir() { + remove_dir(path)?; + } else { + remove_file(path)?; + } + } + + #[cfg(not(windows))] + { + remove_file(path)?; + } } else { remove_file(path)?; } @@ -94,8 +107,17 @@ impl Removal { } let entry = entry?; - if cfg!(windows) && entry.file_type().is_symlink() { - // Remove the junction. + if entry.file_type().is_symlink() && { + #[cfg(windows)] + { + use std::os::windows::fs::FileTypeExt; + entry.file_type().is_symlink_dir() + } + #[cfg(not(windows))] + { + false + } + } { self.num_files += 1; remove_dir(entry.path())?; } else if entry.file_type().is_dir() {