Traits with associated type in templates

yggie

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)
Vladimir Matveev

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.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related