Baffled by trait bounds error

I am using the Arc<impl trait> pattern for services in my app. I use it all over. But for some reason I can't figure out, the pattern is not working for one new case.

Consider:

pub trait MyService {
  ...
}

In another module:

pub fn new(
    service: Arc<impl MyService + 'static + Send + Sync>,
) -> Arc<impl OtherService + Send + Sync> {
    Arc::new(ServiceImpl {
        service,
    })
}

    pub struct ServiceImpl<
        M: MyService + 'static + Send + Sync,
    > {
        pub service: M,
    }

    impl<
            H: MyService + Send + Sync,
        > OtherService for ServiceImpl<H, M>
    {
        ...
    }

Error:

error[E0277]: the trait bound `std::sync::Arc<impl MyService + 'static + Send + Sync>: services::MyService` is not satisfied
  --> backtest/src/backtest_service.rs:22:9
   |
22 |         service,
   |         ^^^^^^^^^^^^^^^ the trait `services::MyService` is not implemented for `std::sync::Arc<impl MyService + 'static + Send + Sync>`
   |

I cannot see any difference between this code and other services using MyService - they all follow the same pattern - and this error message is baffling to me, which I'm sure is why I can't spot the problem. How does some_trait "implement" Arc<impl some_trait + 'static + Send + Sync>?

Ok, I solved it. I was missing the Arc<> wrapper in the struct!

One of those things you can see past 100 times, that won't jump out at you if you're not fully grokking the error message.

Now it makes sense.

Mods - feel free to delete the thread, or leave it up if you think it's a useful lesson.

(In my defense, the actual example is much more complex.)

1 Like