Generic associated types are not identical

pub struct Unit {
    hp: i32,
}

trait Health {
    type Output;

    fn get(&self) -> Self::Output;
    fn lower(&mut self, v: Self::Output);
}

impl Health for Unit {
    type Output = i32;

    fn get(&self) -> Self::Output {
        self.hp
    }

    fn lower(&mut self, enemy: Self::Output) {
        self.hp -= enemy;
    }
}

trait Attack<T>
where
    T: Health,
{
    fn attack(&self, e: &mut T);
}

impl<S, O> Attack<O> for S
where
    S: Health,
    O: Health,
{
    fn attack(&self, out: &mut O) {
        out.lower(self.get());
    }
}


fn main() {}
error[E0308]: mismatched types
  --> src/main.rs:37:19
   |
31 | impl<S, O> Attack<O> for S
   |      -  - expected type parameter
   |      |
   |      found type parameter
...
37 |         out.lower(self.get());
   |             ----- ^^^^^^^^^^ expected type parameter `O`, found type parameter `S`
   |             |
   |             arguments to this method are incorrect
   |
   = note: expected associated type `<O as Health>::Output`
              found associated type `<S as Health>::Output`
   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
note: associated function defined here
  --> src/main.rs:9:8
   |
9  |     fn lower(&mut self, v: Self::Output);
   |        ^^^^^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

Is there any way to specify that O::Ouput and S::Output should be the same type?

Please, next time you ask a question, ask an actual question. Don't just dump a wall of code in a post and expect people to guess what your problem is.


Now, the error in this case is really trivial so you are lucky. You didn't specify anywhere that the two associated Output types should be the same, so the compiler can't (shouldn't) assume they are. If you require that they be the same, the code compiles.

I realized I had forgotten to ask a question. I immediately edited, but you responded too quickly.
Thank you for your help.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.