Why rust can't infer type through trait associated type

Rust can't infer type through trait associated type

In the beginning I implemented Wrappable for each struct separately, but i decided to try From/Into approach, where complementary trait Wrappable implemented based on primary Wrapper, but rust requires you to annotate types, and sadly api becomes unusable (types in actual project more complex).

notice:
I know that I can change type layout, but I really need layout exactly like this (because in actual project MainWrapper contains const generic params, which doesn't work well with traits).

I have theory that rust can't infer type because there is could be many trait implementation with same associated type, but in my example there is definitely only one such implementation. Shouldn't rust show this error only when there is 1+ implementations?

trait Wrapper {
    type Inner;

    fn wrap(value: Self::Inner) -> Self;
    fn logic(&mut self); // some logic with custom implementation for each wrapped type
}

struct VecU8Wrapper {}

impl Wrapper for VecU8Wrapper {
    type Inner = Vec<u8>;

    fn wrap(value: Self::Inner) -> Self {
        Self {}
    }
    fn logic(&mut self) {}
}

// main wrapper, user will interact with it
pub struct MainWrapper<T: Wrapper> {
    inner: T
}

trait Wrappable<T: Wrapper> {
    fn wrap(self) -> MainWrapper<T>;
}

// implement method wrap for each type which have custom wrapper implemented
impl<T: Wrapper> Wrappable<T> for T::Inner {
    fn wrap(self) -> MainWrapper<T> {
        MainWrapper {
            inner: T::wrap( self )
        }
    }
}

fn main() {
    println!("Hello, world!");

    let mut vec: Vec<u8> = Vec::new();

    let wrapper = vec.wrap(); // Can't infer(
    // let wrapper: MainWrapper<VecU8Wrapper> = vec.wrap(); // works
}

playground

Because multiple types could share the same associated type, so Rust can't know which implementation of Wrapper you want based on the inner type alone. The way to fix this is by using an associated type in Wrappable instead of a generic parameter. Then there is only one possible implementation, making inference trivial.

Do you mean individual impls of Wrappable for each type which has Wrapper?

Or you means something like that? If so, it doesn't compile

impl<T: Wrapper> Wrappable for T::Inner {
    type Wrappable = T;
    fn wrap(self) -> MainWrapper<Self::Wrappable> {
        MainWrapper {
            inner: T::wrap( self )
        }
    }
}

My target is that I won't have to write Wrappable implementation for each type I have Wrapper for.

I figured out the conceptual problem in my idea. Wrapper is like From trait. And Wrappable is like Into trait. But I completely forget that when I use into() I need to explicitly write type. I just made my own From/Into api, and it have same flaws as original From/Into. Who would've expected)

Thanks for help