These are chat archives for rust-lang/rust

3rd
May 2017
Sathya Narrayanan
@sourcepirate
May 03 2017 13:12
use std::fmt::Debug;


#[derive(Clone)]
struct Sample(i32);

#[derive(Debug)]
struct Data(u32);

trait Hello <T, I> {
    fn sayhello(data: T) -> Result<I, i32>;
}

impl Data {
    fn new(i: u32) -> Self {
        Data(i)
    }
}

impl<T, I> Hello<T, I> for Sample 
    where T: Clone, I: Debug {
    fn sayhello (data: T) -> Result<I, i32> {
        Ok(Data::new(2))
    }
}

fn main(){
    let h = Sample(23);
    let l = Sample(13);
    let g = h.sayhello(l);
}
// expected type parameter, found struct `Data`
How can i solve this issue.. I am very new bie to rust.
Aleksey Kladov
@matklad
May 03 2017 13:20

@sourcepirate The type signature of sayhellomeans that it can return any I as long as it is : Debug. However, you don't return I, you return Data.

I think this can be fixed by changing the impl to impl<T> Hello<T, Data> for Sample.

Sathya Narrayanan
@sourcepirate
May 03 2017 13:55
@matklad but I have one question here, shouldn't Data struct implemented Debug trait which I is referring??
Denis Lisov
@tanriol
May 03 2017 13:55
@sourcepirate The #[derive(Debug)] provides this implementation.
Sathya Narrayanan
@sourcepirate
May 03 2017 13:56
Yup which means data struct satisfies "I" isn't it?
Is I and Data different ?
@matklad
Denis Lisov
@tanriol
May 03 2017 13:59
When you write impl<T, I> Hello<T, I> for Sample where T: Clone, I: Debug it means that I is an arbitrary type that implements Debug.
However, your impl cannot work for an arbitrary I, only for Data
Sathya Narrayanan
@sourcepirate
May 03 2017 14:02
Thanks @matklad I get it now
Is there any way to make it even more generic
??
Frank McSherry
@frankmcsherry
May 03 2017 14:02
@sourcepirate What you may want is an "associated type", which is a type that the implementation gets to choose.
The type parameter I is currently one that the caller must be free to choose, but if you want to say: "my implementation picks a type, and returns it" you can use associated types.
Sathya Narrayanan
@sourcepirate
May 03 2017 14:03
Oh!
Frank McSherry
@frankmcsherry
May 03 2017 14:04
For example, if instead of trait Hello<T, I> you have trait Hello<T> { type I; ... }
and then in your implementation of Hello for sample you write type I = Data; you might be good to go.
Sathya Narrayanan
@sourcepirate
May 03 2017 14:05
Thanks @frankmcsherry that was a great explanation
Frank McSherry
@frankmcsherry
May 03 2017 14:06
I'm glad it helped!
Sathya Narrayanan
@sourcepirate
May 03 2017 14:07
You introduced me to associated types now
Frank McSherry
@frankmcsherry
May 03 2017 14:07
They are super useful. :)
The other thing you could have done, to contrast, is impl<T> Hello<T, D> for Sample.
This can be useful too (if you want to implement Hello with for Sample with multiple output types), but often the relationship is one where the type implementor specifies exactly one "output type".
Sorry, impl<T> Hello<T, Data> for Sample.
@matklad pointed that out up above, sorry for repeating it!