2
votes

I have a struct Couple in rust with a type parameter

I would like to implement an operation (Not in this case) on this Couple<T>: If T implement Not, the negation of the couple is the couple of the negations.

use std::ops::Not;

struct Couple<T>(T, T);

impl<T> Not for Couple<T>
where
    T: Not,
{
    type Output = Self;

    fn not(self) -> Self {
        Couple(T::not(self.0), T::not(self.1))
    }
}

This code compile with other traits (such as Default::default) but not with the trait Not.

I get the error

error[E0308]: mismatched types
  --> src/lib.rs:12:16
   |
5  | impl<T> Not for Couple<T>
   |      - this type parameter
...
12 |         Couple(T::not(self.0), T::not(self.1))
   |                ^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
   |
   = note: expected type parameter `T`
             found associated type `<T as Not>::Output`
help: consider further restricting this bound
   |
7  |     T: Not + Not<Output = T>,
   |            ^^^^^^^^^^^^^^^^^

Why is it the case? How can I implement Not and other operation traits for Couple?

1

1 Answers

8
votes

Implementing Not for T does not mean that it will necessarily return T. So you have to specify the Output type, by doing e.g. Not<Output = T>.

use std::ops::Not;

struct Couple<T>(T, T);

impl<T> Not for Couple<T>
where
    T: Not<Output = T>,
{
    type Output = Self;

    fn not(self) -> Self {
        Couple(T::not(self.0), T::not(self.1))
    }
}

Alternatively, if you want to allow a different Output type, based on <T as Not>::Output, then you can do this instead:

impl<T> Not for Couple<T>
where
    T: Not,
{
    type Output = Couple<T::Output>;

    fn not(self) -> Self::Output {
        Couple(T::not(self.0), T::not(self.1))
    }
}

You can of course also simplify Couple(T::not(self.0), T::not(self.1)) into Couple(!self.0, !self.1).