Help me to understand trait bound

Here is my code:

#[derive(Copy,Clone, Debug)]
struct My<T: Sized>(T);

impl<T> Add for My<T>
where T : Sized + Add<Output = T>
{
    type Output = My<T>;

    fn add(self, rhs: Self) -> Self::Output 
    {
        My(self.0 + rhs.0)
    }
}

It is obvious from my code that I simply want to add two My together with the help of the Add trait. I do not understand the second part of trait bound which is Add<Output=T>. The addition of two My(T) will be My(T), but the second trait bound tells that it will be the type T referring to Output=T. However, later we use the line type Output = My<T> which seems okay to me.

Why?
Are there any easy-to-understand ways to implement the Add trait for My(T)?

Thanks.

T is the type of the wrapped field, i.e. self.0. If you add self.0 + rhs.0, you also get a T, which is exactly what you want, because you can then wrap it in a My. Every type checks out.

Note that the Add bound is on the wrapped type, i.e., T itself, not on My<T>.

1 Like

because the trait Add has both a generic type parameter (Rhs, i.e. the other operand of the + operator, which default to Self), and an associated type (Output, which is the result of the + operator). this means, type T can have implementations for Add trait that will return result type that is different from T. so the trait bound T: Add<Output = T> restricts the generic type T to those implements Add and the return type is also T, this makes sure in your implementation, the code

My(self.0 + rhs.0)

has the correct type. otherwise, self.0 + rhs0 could be any type, so you can't use it to construct a My<T> value.

1 Like

The second trait bound is a bound on T, which says "you can add T to it and get another T". It's not a bound on My<T>.

1 Like