// build-pass fn main() { let mut log_service = LogService { inner: Inner }; log_service.call(()); } pub trait Service { type Response; fn call(&mut self, req: Request) -> Self::Response; } pub struct LogService { inner: S, } impl Service for LogService where S: Service, U: Extension + 'static, for<'a> U::Item<'a>: std::fmt::Debug, { type Response = S::Response; fn call(&mut self, req: T) -> Self::Response { self.inner.call(req) } } pub struct Inner; impl Service<()> for Inner { type Response = Resp; fn call(&mut self, req: ()) -> Self::Response { Resp::A(req) } } pub trait Extension { type Item<'a>; fn touch(self, f: F) -> Self where for<'a> F: Fn(Self::Item<'a>); } pub enum Resp { A(()), } impl Extension for Resp { type Item<'a> = RespItem<'a>; fn touch(self, _f: F) -> Self where for<'a> F: Fn(Self::Item<'a>), { match self { Self::A(a) => Self::A(a), } } } pub enum RespItem<'a> { A(&'a ()), } impl<'a> std::fmt::Debug for RespItem<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::A(arg0) => f.debug_tuple("A").field(arg0).finish(), } } }