Type resolution problem

Hello,

I am writing some code which abstracts a value-type behind a trait and want to use different implementations by another struct with the concrete implementation supplied as a template parameter.

pub mod a {
    pub trait A {
        type Impl: A;

        const CONST: Self::Impl;

        fn mul(&self, rhs: &Self::Impl) -> Self::Impl;
    }
}

pub mod b {
    use super::a::A;

    pub struct B(pub u32);

    impl A for B {
        type Impl = Self;

        const CONST: Self = B(0);

        fn mul(&self, rhs: &Self::Impl) -> Self::Impl {
            Self(self.0*rhs.0)
        }
    }
}

pub mod c {
    use super::a::A;

    pub struct C<T>(pub T);

    impl<T: A> C<T> {
        pub fn foo(&self, rhs: &<<T as A>::Impl as A>::Impl) {
            T::CONST.mul(rhs);
        }
    }
}

fn main() {
    let rhs = b::B(1);
    let c = c::C(b::B(0));
    c.foo(&rhs);
}

My Problem here is the parameter of function foo()

pub fn foo(&self, rhs: &<<T as A>::Impl as A>::Impl) {
    T::CONST.mul(rhs);
}

with 2 'as' expressions.

My question is if there is a more elegant way to do this abstraction without the need of so many 'as' expressions?

You can leave out the inner as and write

pub fn foo(&self, rhs: &<T::Impl as A>::Impl)
2 Likes

Type aliases can move some of the complexity elsewhere.

    type ImplOf<T> = <T as A>::Impl;

    impl<T: A> C<T> {
        pub fn foo(&self, rhs: &ImplOf<ImplOf<T>>) {
            T::CONST.mul(rhs);
        }
    }
3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.