BurntSushi / same-file

Cross platform Rust library for checking whether two file paths are the same file.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Erroneous `impl Eq` on Windows Handle

cjubb39 opened this issue · comments

Hi! It seems that the Eq trait is erroneously defined on win::Handle (and thus on the top-level wrapper struct).

The comments mention the following:

        match file_info(&file) {
            Ok(info) => Ok(Handle::from_file_info(file, true, info)),
            // In a Windows console, if there is no pipe attached to a STD
            // handle, then GetFileInformationByHandle will return an error.
            // We don't really care. The only thing we care about is that
            // this handle is never equivalent to any other handle, which is
            // accomplished by setting key to None.
            Err(_) => Ok(Handle { file: Some(file), is_std: true, key: None }),
        }

If the Err branch is hit, we'll produce a struct that doesn't satisfy the Eq requirement that a == a.

I'd suggest either:

  1. Removing the impl. This seems less desirable as it would be an externally breaking change.
  2. Altering the PartialEq::eq implementation to look at the file and is_std fields iff the key is None for both self and other.

I'm happy to write the pull request but I'm unsure which direction you'd prefer.

Hmm I think neither option is appropriate unfortunately. The first kind of defeats the convenience factor (and is a breaking change, as you point out) and the second could result in two distinct Handles comparing equivalent even though they aren't.

Is it possible to change the PartialEq impl for Handle to this?

impl PartialEq for Handle {
    fn eq(&self, other: &Handle) -> bool {
        if self.key.is_none() && other.key.is_none() {
            return self as *const Handle == other as *const Handle;
        } else if self.key.is_none() || other.key.is_none() {
            return false;
        }
        self.key == other.key
    }
}