Proble to specify the Iterator Item in a where clause


#1

I don’t manage to make this dummy example work, and it seems to me that I am missing something very fundamental about using the where clause

use std::fmt;

trait TT {
    fn val(&self) -> usize;
}

struct ST {
    value: usize,
}

impl TT for ST {
    fn val(&self) -> usize {
        self.value
    }
}

impl fmt::Display for ST {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "(--{}--)", self.value)
    }
}

fn fun<I, A>(it: I)
    where I: Iterator<Item = A>,
          A: TT + fmt::Display
{
    for x in it {
        println!("{} -> {}", x.to_string(), x.val());
    }
}


fn main() {
    let mut v = Vec::new();
    for i in 0..5 {
        v.push(ST { value: i })
    }
    fun(v.iter());
}

(see it in action https://play.rust-lang.org/?gist=8ff0db28221d829a266feba4cd562cad&version=nightly )
I get the following error:

:38:5: 38:8 error: the trait TT is not implemented for the type &ST [E0277]
:38 fun(v.iter());
^~~
:38:5: 38:8 help: see the detailed explanation for E0277
:38:5: 38:8 help: the following implementations were found:
:38:5: 38:8 help:
:38:5: 38:8 note: required by fun
error: aborting due to previous error
playpen: application terminated with error code 101

But ST does implement TT. How do I fix this? Why it does not work?


#2

The problem is that Vec::iter() will iterate over references to its elements, not elements directly (as indicated by &ST in the error message). You could change the signature of fun to accept references instead:

fn fun<'a, A: 'a, I>(it: I) where I: Iterator<Item = &'a A>, A: TT + fmt::Display

#3

Thanks a lot for the explanation. It makes complete sense!.