diff options
| author | Jacob Pratt <jacob@jhpratt.dev> | 2025-03-23 20:44:11 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-23 20:44:11 -0400 |
| commit | 8e30df7f26e3a637f0bb41f877871a240bcbbe06 (patch) | |
| tree | 68af7fc2d40dcf8227657af39e2cd62119981a08 /library/std/src/sys/fs | |
| parent | 0fc6279ce9775005f60eeef8440f3a2bcce74ce3 (diff) | |
| parent | 6b2fa32f142f341ba227b5ea784ea2a1a5e79fe8 (diff) | |
| download | rust-8e30df7f26e3a637f0bb41f877871a240bcbbe06.tar.gz rust-8e30df7f26e3a637f0bb41f877871a240bcbbe06.zip | |
Rollup merge of #138671 - ChrisDenton:filetype, r=joshtriplett
Fix `FileType` `PartialEq` implementation on Windows Fixes #138668 On Windows the [`FileType`](https://doc.rust-lang.org/stable/std/fs/struct.FileType.html) struct was deriving `PartialEq` which in turn means it was doing a bit-for-bit comparison on the file attributes and reparse point. This is wrong because `attributes` may contain many things unrelated to file type. `FileType` on Windows allows for four possible combinations (see also [`FileTypeExt`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html)): `file`, `dir`, `symlink_file` and `symlink_dir`. So the new implementation makes sure both symlink and directory information match (and only those things). This could be considered just a bug fix but it is a behaviour change so someone from libs-api might want to FCP this (or might not)...
Diffstat (limited to 'library/std/src/sys/fs')
| -rw-r--r-- | library/std/src/sys/fs/windows.rs | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 362e64abf1a..06bba019393 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -41,8 +41,8 @@ pub struct FileAttr { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType { - attributes: u32, - reparse_tag: u32, + is_directory: bool, + is_symlink: bool, } pub struct ReadDir { @@ -1111,32 +1111,29 @@ impl FileTimes { } impl FileType { - fn new(attrs: u32, reparse_tag: u32) -> FileType { - FileType { attributes: attrs, reparse_tag } + fn new(attributes: u32, reparse_tag: u32) -> FileType { + let is_directory = attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0; + let is_symlink = { + let is_reparse_point = attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0; + let is_reparse_tag_name_surrogate = reparse_tag & 0x20000000 != 0; + is_reparse_point && is_reparse_tag_name_surrogate + }; + FileType { is_directory, is_symlink } } pub fn is_dir(&self) -> bool { - !self.is_symlink() && self.is_directory() + !self.is_symlink && self.is_directory } pub fn is_file(&self) -> bool { - !self.is_symlink() && !self.is_directory() + !self.is_symlink && !self.is_directory } pub fn is_symlink(&self) -> bool { - self.is_reparse_point() && self.is_reparse_tag_name_surrogate() + self.is_symlink } pub fn is_symlink_dir(&self) -> bool { - self.is_symlink() && self.is_directory() + self.is_symlink && self.is_directory } pub fn is_symlink_file(&self) -> bool { - self.is_symlink() && !self.is_directory() - } - fn is_directory(&self) -> bool { - self.attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0 - } - fn is_reparse_point(&self) -> bool { - self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 - } - fn is_reparse_tag_name_surrogate(&self) -> bool { - self.reparse_tag & 0x20000000 != 0 + self.is_symlink && !self.is_directory } } |
