[solved] Generics and associated types


I’m currently trying to solve coding puzzles from Advent of Code (i’m not gonna ask for a solution here :wink: ), using Rust so i can learn more about the language. For now, even if it’s more verbose than, say, Python, i really enjoy it so i’ll continue.

And now, on a given problem, i thought i could go further using Rust and use generics in a more “advanced” way. I’m currently stuck on a pure Rust problem. Consider this code:

use std::ops::Add;

pub struct Remote<T> {
    x: T,

pub struct Local<S> {
    x: S,

pub struct Adder<T> {
    local: Local<T>

impl<I: Add> Adder<I> {
    pub fn add(&self, r: Remote<I>) -> I {
        self.local.x + r.x

fn main() {
    let adder: Adder<u64> = Adder{local: Local{x:1}};
    let remote: Remote<u64> = Remote{x:2};


Before even trying to compile, i smelled that something could go wrong with this. I want to add “types” S and T… but they aren’t “linked” together in any way… but as i’m not sure about what the compiler is telling me

error[E0308]: mismatched types                                                                                                                                                                
  --> src/main.rs:17:9                                                                                                                                                                        
16 |     pub fn add(&self, r: Remote<I>) -> I {                                                                                                                                               
   |                                        - expected `I` because of return type                                                                                                             
17 |         self.local.x + r.x                                                                                                                                                               
   |         ^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type                                                                                                                
   = note: expected type `I`                                                                                                                                                                  
              found type `<I as std::ops::Add>::Output`

So aaah… associated type? I tried to do some messy stuff with a second type parameter (named C) on Adder, using PhantomData to actually do something with it so the compiler doesn’t yell at me, and using r: Remote<C> but it doesn’t work any more.

Suddenly I remembered that i could use C=Remote<I> but then the compiler say something like “deprecated” so it’s a no go either.

How could i achieve to get the same type for Remote and Local?


You want the following (note the return type change):

pub fn add(&self, r: Remote<I>) -> I::Output

You’ll also likely want to add a Copy bound on I (ie I: Add + Copy).


Wow… that’s pretty obvious now.

Reading the documentation of std::ops::Add about type Output makes it much clearer now.

Nonetheless i’m not sure how that part works. Could you please point me where in Rust’s book(s) i can learn about it?

Many thanks.

Which bit specifically? The Output associated type of the Add trait? ie what are associated types?

Yes, about associated types :slight_smile:

Probably here (surprised it’s in the “advanced” section, and not in the generics chapter).

1 Like

Interesting readings on the way. Thanks again for your precious help :slight_smile: