Search code examples
rusttraits

Compiler cannot infer if an object of `impl <trait>` has impled another trait in Rust


Consider I have a trait A and I have lots of structs(e.g. X) impled A. Then I write many small functions(return these structs) to abstract my logic. However, the return type of these functions can be huge and too complex to write(like Chain<Map<'a, (i32, u8), u16, Enumerate<Filter<'a, u8, vec::MoveItems<u8>>>>, SkipWhile<'a, u16, Map<'a, &u16, u16, slice::Items<u16>>>>), so I used impl A instead since as far as I know, impl <trait>s are still static dispatched:

trait A {...}
struct X {...}
impl A for X {...}
fn func_to_return_impl_A() -> impl A {...}

Now the problem is that recently I want to impl my structs to another trait B. Whenever I want to use values returned by my small functions as: func_to_return_impl_A(...).method_of_trait_B(...), the compiler complained: no implementation for impl A <method of trait B> .... Moreover, I cannot simply rewrite the return types as impl A + B since trait B may also contain complex generic type or associated types which I cannot write myself:

impl B for X {...}

fn some_func() {
  func_to_return_impl_A().method_of_trait_B(...) //error: no implementation for impl A <method of trait B> ...
}

The only way to avoid this I can think of is to make another wrapper to wrap all my structs and impl it to trait B, but as the model getting more complex, this would be hard to maintain. How should I fix this problem?


Solution

  • Ok I think I've find the ad-hoc solution for my problem: additional Wrapper:

    struct Wrapper<P: A> {
        p: P
    }
    
    impl<P: A> A for Wrapper<P> {...}
    impl<P: A> B for Wrapper<P> {...}
    
    fn func_to_return_impl_A() -> Wrapper<impl A> {...}
    

    Then I can use methods of trait B:

    func_to_return_impl_A().method_of_trait_B(...);