These are chat archives for rust-lang/rust

5th
Dec 2016
Soham Chowdhury
@mrkgnao
Dec 05 2016 16:12
@retep998 mhm, thanks
I was testing out the irc bridge, so that completely escaped my mind
Paul Betts
@paulcbetts
Dec 05 2016 22:45
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S>
    where K: Eq + Hash + Borrow<Q>,
          Q: Eq + Hash,
          S: BuildHasher,
{
    type Output = V;

    #[inline]
    fn index(&self, index: &Q) -> &V {
        self.get(index).expect("no entry found for key")
    }
}
^^^ Why are K and Q different here?
(I'm a Rust noob reading through libstd)
i.e. why isn't it just:
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V, S> Index<&'a K> for HashMap<K, V, S>
    where K: Eq + Hash,
          S: BuildHasher,
{
    type Output = V;

    #[inline]
    fn index(&self, index: &K) -> &V {
        self.get(index).expect("no entry found for key")
    }
}
Paul Betts
@paulcbetts
Dec 05 2016 22:53
also, why are there two ways to specify that a certain type parameter should have a trait
Q: ?Sized and where Q: Eq + Hash
Michael Howell
@notriddle
Dec 05 2016 23:38
The non-where-clause syntax is shorter.
The where-clause syntax can express relationships that the other version cannot.
Michael Howell
@notriddle
Dec 05 2016 23:46
Your version of the Index trait for HashMap could be expressed using just the non-where-clause syntax:
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K: Eq + Hash, V, S: BuildHasher> Index<&'a K> for HashMap<K, V, S>
{
    type Output = V;

    #[inline]
    fn index(&self, index: &K) -> &V {
        self.get(index).expect("no entry found for key")
    }
}
So could the real version, actually.
But it's long, and complicated enough to make you want to be able to see a list of parameters before trying to decode the conditions.
Paul Betts
@paulcbetts
Dec 05 2016 23:55
Got it
Thanks for the explanation
Why do they use Q there though? Q has the ?Sized trait and K has to be Borrowable to Q