Implementation overloading

So this is fine:

    trait MulawExt: Iterator {
        fn mulaw(self) -> Mulaw<Self> where Self: Sized;
    }

    impl<I> MulawExt for I where I: Iterator<Item = u16> {
        fn mulaw(self) -> Mulaw<Self> where Self: Sized {
            unimplemented!()
        }
    }

But then adding this implementation for when Item = u8 errors out.

    impl<I> MulawExt for I where I: Iterator<Item = u8> {
        fn mulaw(self) -> Mulaw<Self> where Self: Sized {
            unimplemented!()
        }
    }

conflicting implementations of trait MulawExt:

Is it possible to overload different implementations of a trait function for specific concrete or primitive types and constrained to an associated type? A trait function foo() for <Item = SomeType> and a trait function foo() for <Item = f64> etc

Yes, something like this should work:

struct Mulaw<T>(T);

trait MulawExt: Iterator {
    fn mulaw(self) -> Mulaw<Self> where Self: Sized;
}

impl<I> MulawExt for I where I: Iterator, I::Item: MulawHelper {
    fn mulaw(self) -> Mulaw<Self> where Self: Sized {
        I::Item::mulaw_helper(self)
    }
}

trait MulawHelper: Sized {
    fn mulaw_helper<I: Iterator<Item = Self>>(iterator: I) -> Mulaw<I>;
}

impl MulawHelper for u8 {
    fn mulaw_helper<I: Iterator<Item = u8>>(iterator: I) -> Mulaw<I> {
        println!("mulaw_helper for u8");
        Mulaw(iterator)
    }
}

impl MulawHelper for u16 {
    fn mulaw_helper<I: Iterator<Item = u16>>(iterator: I) -> Mulaw<I> {
        println!("mulaw_helper for u16");
        Mulaw(iterator)
    }
}

fn main() {
    vec![0u8].into_iter().mulaw();
    vec![0u16].into_iter().mulaw();
}
1 Like

Thank you. I was hoping I just made a mistake with the syntax, because it would be nice to do C++ esque overloading.

Looks like this was https://github.com/rust-lang/rfcs/pull/1672. It was closed as postponed along with https://github.com/rust-lang/rfcs/pull/1658 (lots of discussion there).

1 Like