Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot implement Hash except by IterBytes ? #9075

Closed
pnkfelix opened this issue Sep 9, 2013 · 6 comments
Closed

cannot implement Hash except by IterBytes ? #9075

pnkfelix opened this issue Sep 9, 2013 · 6 comments
Labels
A-trait-system Area: Trait system A-type-system Area: Type system C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@pnkfelix
Copy link
Member

pnkfelix commented Sep 9, 2013

A strange problem: Let's say I want to implement the Hash trait myself, making use of the hash functions of my substructure, instead of by defining/deriving IterBytes.

rustc rejects my attempts to do so, saying that it failed to find an implementation of IterBytes for the structure in question.

Just to double-check my work, I cut-and-pasted a renamed version of the Hash trait into my code, and checked that I could indeed implement that (which I can):

Test case:

enum AB<A,B> { Lft(A), Rgt(B) }

pub trait Hash2 {
    fn hash_keyed(&self, k0: u64, k1: u64) -> u64;

    #[inline]
    fn hash(&self) -> u64 { self.hash_keyed(0,0) }
}

#[cfg(not(workaround))]
impl<A:Hash, B:Hash> Hash for AB<A,B> {
    fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
        match self {
            &Lft(ref a) => a.hash_keyed(k0, k1),
            &Rgt(ref b) => b.hash_keyed(k0, k1),
        }
    }
}

#[cfg(workaround)]
impl<A:Hash2, B:Hash2> Hash2 for AB<A,B> {
    fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
        match self {
            &Lft(ref a) => a.hash_keyed(k0, k1),
            &Rgt(ref b) => b.hash_keyed(k0, k1),
        }
    }
}

fn main() {

}

Transcript:

% rustc --version
/Users/pnkfelix/opt/rust-dbg/bin/rustc 0.8-pre (dd5c737 2013-09-08 12:05:55 -0700)
host: x86_64-apple-darwin
% rustc --cfg workaround /tmp/foo.rs
warning: no debug symbols in executable (-arch x86_64)
% rustc /tmp/foo.rs
/tmp/foo.rs:11:0: 18:1 error: failed to find an implementation of trait std::to_bytes::IterBytes for AB<A,B>
/tmp/foo.rs:11 impl<A:Hash, B:Hash> Hash for AB<A,B> {
/tmp/foo.rs:12     fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
/tmp/foo.rs:13         match self {
/tmp/foo.rs:14             &Lft(ref a) => a.hash_keyed(k0, k1),
/tmp/foo.rs:15             &Rgt(ref b) => b.hash_keyed(k0, k1),
/tmp/foo.rs:16         }
               ...
% 
@pnkfelix
Copy link
Member Author

pnkfelix commented Sep 9, 2013

Ah, the comment above the Hash trait actually says: "Note that this trait is likely to change somewhat as it is closely related to to_bytes::IterBytes and in almost all cases presently the two are ( and must be ) used together." (emphasis added).

Still, this limitation in how one implements Hash seems strange to me. (Even though I agree that it is usually better to just delegate the definition of hash to IterBytes, the developer should be free to implement Hash their own way if they want.)

@pnkfelix
Copy link
Member Author

pnkfelix commented Sep 9, 2013

The reason for this limitation is apparent in the implementation, as pointed out to me on IRC:

(from hash.rs):

impl<A:IterBytes> Hash for A {
    ...
}

I remain curious as to whether we intend to uphold this limitation permanently, or figure out another approach for resolving this. (But just so I am entirely upfront: I have no objections if we resolve this by saying: "If you want to implement your own hash function, then you have to also implement your own hash table with which to couple it", which is a work-around one can use today if one so desires.)

@pnkfelix
Copy link
Member Author

pnkfelix commented Sep 9, 2013

see also commentary on #8038

@emberian
Copy link
Member

emberian commented Jan 6, 2014

This is quite unfortunate. I think it will be solved by the coherence relaxations (coherence currently ignores type parameters, and is thus overzealous), though Hash/IterBytes probably need to be restructured.

@emberian
Copy link
Member

emberian commented Jan 6, 2014

cc @nikomatsakis

@gereeter
Copy link
Contributor

With the new Hash system, IterBytes is gone and this is fixed, so this should be closed.

flip1995 pushed a commit to flip1995/rust that referenced this issue Jul 18, 2022
Add `dev deprecate` to the development basics

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system A-type-system Area: Type system C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

4 participants