Working around the limitations of extension traits

iterator, rust, traits

Solution

As of `rustc 0.13.0-nightly (8bca470c5 2014-12-08 00:12:30 +0000)` defining `last()` as an inherent method on your type should work.

#[deriving(Copy)]
struct Foo<T> {t: T}

impl<T> Iterator<T> for Foo<T> {
    fn next(&mut self) -> Option<T> { None }
}

// this does not work
// error: conflicting implementations for trait `core::iter::IteratorExt` [E0119]
// impl<T> IteratorExt<T> for Foo<T> {
//    fn last(mut self) -> Option<T> { None }
//}

// but this currently does
impl<T> Foo<T> {
    fn last(mut self) -> Option<T> { Some(self.t) }
}


fn main() {
    let mut t = Foo{ t: 3u };
    println!("{}", t.next())
    println!("{}", t.last()) // last has been "shadowed" by our impl
    println!("{}", t.nth(3)) // other IteratorExt methods are still available
}

Since you're not supposed to use Extension traits as generic bounds (but just to provide additional methods), this should theoretically work for your scenario, as you can have your own type and its `impl` in the same crate.

Users of your type will use the inherent `last` method instead of the one on `IteratorExt` but still be able to use the other methods on `IteratorExt`.

Problem

The pattern of having an object-safe trait `Foo` and a (potentially unsafe) extension trait `FooExt` implemented for all instances of `Foo` seems to become standard now. https://github.com/rust-lang/rfcs/pull/445 This is a problem for me in the case of `Iterator<A>`, as I have a library that overrides the default method `IteratorExt#last()` of the old iterator trait (the underlying library has an efficient implementation of `last()`). This in now impossible, because for any `A`, there will always be a conflicting trait implementation of `IteratorExt`, the one that `libcore` already provides for all `Iterator<A>`. `iterator.rs:301:1: 306:2 error: conflicting implementations for trait `core::iter::IteratorExt` [E0119] ` ``` iterator.rs:301 impl<'a, K: Key> iter::IteratorExt<Vec<u8>> for ValueIterator<'a,K,Vec<u8>> { iterator.rs:302 fn last(&mut self) -> Option<Vec<u8>> { iterator.rs:303 self.seek_last(); iterator.rs:304 Some(self.value()) iterator.rs:305 } iterator.rs:306 } ... ``` Now, as far as I see, I have two options: - have my own trait and my own `last()` implementation. That would mean it conflicts if `IteratorExt` is imported unless carefully used. This also has the danger accidentally using an inefficient version of `last()` if the version from `IteratorExt` is used. I'd loose convenient access to `IteratorExt`. - have my own trait and name the method differently (`seek_last()`). Disadvantage: I ask the user to learn vocabulary and to always favor my method over that provided by `IteratorExt`. Same problem: I'd like to avoid accidental usage of `last()`. Is there any other, better, solution I am missing?

Original source