Reputation: 317
I have been having problems compiling my Rust code, I managed to boil down the issue to this snippet:
use std::slice::Iter;
pub trait Foo<'a> {
type Bar: Iterator<Item=&'a usize>;
fn make(&self) -> usize;
}
pub struct Juice;
impl <'a> Foo<'a> for Juice {
type Bar = Iter<'a, usize>;
fn make(&self) -> usize { 0us }
}
// Uncomment this line to break things
// fn get_int<'a, T: Foo<'a>>(t: T) -> usize {
// t.make()
// }
fn main() {
println!("Hello, {:?} world!" , Juice.make());
}
I am pretty sure I am just missing something, is there anything I need to do to make this trait work? I am using the latest nightly alpha build (at the time of writing):
rustc 1.0.0-nightly (458a6a2f6 2015-01-25 21:20:37 +0000)
Upvotes: 5
Views: 1850
Reputation: 128051
Unfortunately, you need to write this:
fn get_int<'a, T: Foo<'a, Bar=I>, I: Iterator<Item=&'a usize>>(t: T) -> usize {
t.make()
}
That is, you have to specify explicitly that the type of Bar
is an iterator of the corresponding type. The trait bound inside the trait definition alone is insufficient.
This is very much like regular type parameters work. Even if you write something like
trait Parameterized<T: Clone> { ... }
You still need to write
fn do_something<P: Parameterized<T>, T: Clone>() { ... }
Or with structs:
struct S<T: Iterator<i32>> { ... }
impl<T: Iterator<i32>> for S<T> { ... }
This does look counterintuitive (and I've stumbled upon this several times as well) and probably deserves an issue in RFC repo.
Upvotes: 7