What's the difference between <T:Trait> and "where T:Trait"?

What's the difference between these two struct declarations, with <T: Trait> and where T: Trait?

One:

struct IterWrap<T> where T: Iterator {
	it: T
}

Two:

struct IterWrap<T: Iterator> {
	it: T
}

They're equivalent

3 Likes

Are there cases when one is better than the other?

Some only work in the where, like if you need where <T as Foo>::Bar: SomeTrait.

Commonly what you'll see is "short" and "important" things in the early part. Like

fn whatever<K: Eq+Hash, V>(…)

is common, but trying to fit

fn blah<F: FnMut(HashMap<String, Vec<String>, MyCustomHasher>) -> HashSet<String>>(args: GoHere, f: F)

just looks silly, so is better as a where.

EDIT: Fixed the second example to actually be legal, thatnks ekuber & 2e71828.

6 Likes

That made me realise that we should handle that case more gracefully.

5 Likes

I would say the answer is: if you have to ask then there are no difference.

Unfortunately where is weaker (compare), but in cases where both works they are identical.

P.S. I was under impression that Chalk was supposed to fix problems like these, but, unfortunately, it's development stalled.

1 Like

That's not due to the where per se, that's due to using a non-supertrait bound. These work the same:

pub trait Foo: Into<i8>
pub trait Foo where Self: Into<i8>
1 Like