diff --git a/tower/src/buffer/service.rs b/tower/src/buffer/service.rs index 9493f1074..c32ef2d80 100644 --- a/tower/src/buffer/service.rs +++ b/tower/src/buffer/service.rs @@ -65,7 +65,7 @@ where /// the background `Worker` that you can then spawn. pub fn pair(service: S, bound: usize) -> (Self, Worker) where - S: Service + Send + 'static, + S: Service + Send, F: Send, S::Error: Into + Send + Sync, Req: Send + 'static, @@ -132,8 +132,8 @@ where impl Clone for Buffer where - Req: Send + 'static, - F: Send + 'static, + Req: Send, + F: Send, { fn clone(&self) -> Self { Self { diff --git a/tower/src/builder/mod.rs b/tower/src/builder/mod.rs index 8f081d234..4660789c0 100644 --- a/tower/src/builder/mod.rs +++ b/tower/src/builder/mod.rs @@ -75,7 +75,7 @@ use std::fmt; /// # #[cfg(feature = "limit")] /// # use tower::limit::concurrency::ConcurrencyLimitLayer; /// # #[cfg(feature = "limit")] -/// # async fn wrap(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send { +/// # async fn wrap(svc: S) where S: Service<(), Error = &'static str> + Send, S::Future: Send { /// ServiceBuilder::new() /// .concurrency_limit(5) /// .service(svc); @@ -703,7 +703,7 @@ impl ServiceBuilder { /// /// [`BoxService::layer()`]: crate::util::BoxService::layer() #[cfg(feature = "util")] - pub fn boxed( + pub fn boxed<'a, S, R>( self, ) -> ServiceBuilder< Stack< @@ -711,6 +711,7 @@ impl ServiceBuilder { fn( L::Service, ) -> crate::util::BoxService< + 'a, R, >::Response, >::Error, @@ -721,8 +722,8 @@ impl ServiceBuilder { > where L: Layer, - L::Service: Service + Send + 'static, - >::Future: Send + 'static, + L::Service: Service + Send + 'a, + >::Future: Send + 'a, { self.layer(crate::util::BoxService::layer()) } @@ -766,7 +767,7 @@ impl ServiceBuilder { /// [`BoxCloneService`]: crate::util::BoxCloneService /// [`boxed`]: Self::boxed #[cfg(feature = "util")] - pub fn boxed_clone( + pub fn boxed_clone<'a, S, R>( self, ) -> ServiceBuilder< Stack< @@ -774,6 +775,7 @@ impl ServiceBuilder { fn( L::Service, ) -> crate::util::BoxCloneService< + 'a, R, >::Response, >::Error, @@ -784,8 +786,8 @@ impl ServiceBuilder { > where L: Layer, - L::Service: Service + Clone + Send + 'static, - >::Future: Send + 'static, + L::Service: Service + Clone + Send + 'a, + >::Future: Send + 'a, { self.layer(crate::util::BoxCloneService::layer()) } diff --git a/tower/src/util/boxed/layer.rs b/tower/src/util/boxed/layer.rs index 34e65fa43..fbf0d86d2 100644 --- a/tower/src/util/boxed/layer.rs +++ b/tower/src/util/boxed/layer.rs @@ -22,11 +22,11 @@ use tower_service::Service; /// use std::time::Duration; /// use tower::{Service, ServiceBuilder, BoxError, util::BoxLayer}; /// -/// fn common_layer() -> BoxLayer +/// fn common_layer<'a, S, T>() -> BoxLayer<'a, S, T, S::Response, BoxError> /// where -/// S: Service + Send + 'static, -/// S::Future: Send + 'static, -/// S::Error: Into + 'static, +/// S: Service + Send + 'a, +/// S::Future: Send + 'a, +/// S::Error: Into + 'a, /// { /// let builder = ServiceBuilder::new() /// .concurrency_limit(100); @@ -51,17 +51,17 @@ use tower_service::Service; /// [`Service`]: tower_service::Service /// [`BoxService`]: super::BoxService /// [`Timeout`]: crate::timeout -pub struct BoxLayer { - boxed: Arc> + Send + Sync + 'static>, +pub struct BoxLayer<'a, In, T, U, E> { + boxed: Arc> + Send + Sync + 'a>, } -impl BoxLayer { +impl<'a, In, T, U, E> BoxLayer<'a, In, T, U, E> { /// Create a new [`BoxLayer`]. pub fn new(inner_layer: L) -> Self where - L: Layer + Send + Sync + 'static, - L::Service: Service + Send + 'static, - >::Future: Send + 'static, + L: Layer + Send + Sync + 'a, + L::Service: Service + Send + 'a, + >::Future: Send + 'a, { let layer = layer_fn(move |inner: In| { let out = inner_layer.layer(inner); @@ -74,15 +74,15 @@ impl BoxLayer { } } -impl Layer for BoxLayer { - type Service = BoxService; +impl<'a, In, T, U, E> Layer for BoxLayer<'a, In, T, U, E> { + type Service = BoxService<'a, T, U, E>; fn layer(&self, inner: In) -> Self::Service { self.boxed.layer(inner) } } -impl Clone for BoxLayer { +impl<'a, In, T, U, E> Clone for BoxLayer<'a, In, T, U, E> { fn clone(&self) -> Self { Self { boxed: Arc::clone(&self.boxed), @@ -90,7 +90,7 @@ impl Clone for BoxLayer { } } -impl fmt::Debug for BoxLayer { +impl<'a, In, T, U, E> fmt::Debug for BoxLayer<'a, In, T, U, E> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BoxLayer").finish() } diff --git a/tower/src/util/boxed/layer_clone.rs b/tower/src/util/boxed/layer_clone.rs index 1f6268995..f004df6f5 100644 --- a/tower/src/util/boxed/layer_clone.rs +++ b/tower/src/util/boxed/layer_clone.rs @@ -33,11 +33,11 @@ use tower_service::Service; /// # fn new() -> Self { Self } /// # } /// -/// fn common_layer() -> BoxCloneServiceLayer +/// fn common_layer<'a, S, T>() -> BoxCloneServiceLayer<'a, S, T, S::Response, BoxError> /// where -/// S: Service + Clone + Send + 'static, -/// S::Future: Send + 'static, -/// S::Error: Into + 'static, +/// S: Service + Clone + Send + 'a, +/// S::Future: Send + 'a, +/// S::Error: Into + 'a, /// { /// let builder = ServiceBuilder::new() /// .concurrency_limit(100); @@ -82,17 +82,17 @@ use tower_service::Service; /// [`Service`]: tower_service::Service /// [`BoxService`]: super::BoxService /// [`Timeout`]: crate::timeout -pub struct BoxCloneServiceLayer { - boxed: Arc> + Send + Sync + 'static>, +pub struct BoxCloneServiceLayer<'a, In, T, U, E> { + boxed: Arc> + Send + Sync + 'a>, } -impl BoxCloneServiceLayer { +impl<'a, In, T, U, E> BoxCloneServiceLayer<'a, In, T, U, E> { /// Create a new [`BoxCloneServiceLayer`]. pub fn new(inner_layer: L) -> Self where - L: Layer + Send + Sync + 'static, - L::Service: Service + Send + Clone + 'static, - >::Future: Send + 'static, + L: Layer + Send + Sync + 'a, + L::Service: Service + Send + Clone + 'a, + >::Future: Send + 'a, { let layer = layer_fn(move |inner: In| { let out = inner_layer.layer(inner); @@ -105,15 +105,15 @@ impl BoxCloneServiceLayer { } } -impl Layer for BoxCloneServiceLayer { - type Service = BoxCloneService; +impl<'a, In, T, U, E> Layer for BoxCloneServiceLayer<'a, In, T, U, E> { + type Service = BoxCloneService<'a, T, U, E>; fn layer(&self, inner: In) -> Self::Service { self.boxed.layer(inner) } } -impl Clone for BoxCloneServiceLayer { +impl<'a, In, T, U, E> Clone for BoxCloneServiceLayer<'a, In, T, U, E> { fn clone(&self) -> Self { Self { boxed: Arc::clone(&self.boxed), @@ -121,7 +121,7 @@ impl Clone for BoxCloneServiceLayer { } } -impl fmt::Debug for BoxCloneServiceLayer { +impl<'a, In, T, U, E> fmt::Debug for BoxCloneServiceLayer<'a, In, T, U, E> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BoxCloneServiceLayer").finish() } diff --git a/tower/src/util/boxed/sync.rs b/tower/src/util/boxed/sync.rs index 57dcfec71..4c8e15d37 100644 --- a/tower/src/util/boxed/sync.rs +++ b/tower/src/util/boxed/sync.rs @@ -45,27 +45,29 @@ use std::{ /// /// [`Service`]: crate::Service /// [`Rc`]: std::rc::Rc -pub struct BoxService { - inner: - SyncWrapper> + Send>>, +pub struct BoxService<'a, T, U, E> { + inner: SyncWrapper< + Box> + Send + 'a>, + >, } /// A boxed `Future + Send` trait object. /// /// This type alias represents a boxed future that is [`Send`] and can be moved /// across threads. -type BoxFuture = Pin> + Send>>; +type BoxFuture<'a, T, E> = Pin> + Send + 'a>>; -impl BoxService { +impl<'a, T, U, E> BoxService<'a, T, U, E> { #[allow(missing_docs)] pub fn new(inner: S) -> Self where - S: Service + Send + 'static, - S::Future: Send + 'static, + S: Service + Send + 'a, + S::Future: Send + 'a, { // rust can't infer the type - let inner: Box> + Send> = - Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _)); + let inner: Box< + dyn Service> + Send + 'a, + > = Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _)); let inner = SyncWrapper::new(inner); BoxService { inner } } @@ -76,28 +78,28 @@ impl BoxService { /// [`Layer`]: crate::Layer pub fn layer() -> LayerFn Self> where - S: Service + Send + 'static, - S::Future: Send + 'static, + S: Service + Send + 'a, + S::Future: Send + 'a, { layer_fn(Self::new) } } -impl Service for BoxService { +impl<'a, T, U, E> Service for BoxService<'a, T, U, E> { type Response = U; type Error = E; - type Future = BoxFuture; + type Future = BoxFuture<'a, U, E>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.get_mut().poll_ready(cx) } - fn call(&mut self, request: T) -> BoxFuture { + fn call(&mut self, request: T) -> BoxFuture<'a, U, E> { self.inner.get_mut().call(request) } } -impl fmt::Debug for BoxService { +impl<'a, T, U, E> fmt::Debug for BoxService<'a, T, U, E> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BoxService").finish() } diff --git a/tower/src/util/boxed/unsync.rs b/tower/src/util/boxed/unsync.rs index f645f1699..3ce29f719 100644 --- a/tower/src/util/boxed/unsync.rs +++ b/tower/src/util/boxed/unsync.rs @@ -4,34 +4,39 @@ use tower_service::Service; use std::fmt; use std::{ future::Future, + marker::PhantomData, pin::Pin, task::{Context, Poll}, }; /// A boxed [`Service`] trait object. -pub struct UnsyncBoxService { - inner: Box>>, +pub struct UnsyncBoxService<'a, T, U, E> { + inner: Box> + 'a>, } /// A boxed [`Future`] trait object. /// /// This type alias represents a boxed future that is *not* [`Send`] and must /// remain on the current thread. -type UnsyncBoxFuture = Pin>>>; +type UnsyncBoxFuture<'a, T, E> = Pin> + 'a>>; #[derive(Debug)] -struct UnsyncBoxed { +struct UnsyncBoxed<'a, S> { inner: S, + _marker: PhantomData<&'a ()>, } -impl UnsyncBoxService { +impl<'a, T, U, E> UnsyncBoxService<'a, T, U, E> { #[allow(missing_docs)] pub fn new(inner: S) -> Self where - S: Service + 'static, - S::Future: 'static, + S: Service + 'a, + S::Future: 'a, { - let inner = Box::new(UnsyncBoxed { inner }); + let inner = Box::new(UnsyncBoxed { + inner, + _marker: PhantomData, + }); UnsyncBoxService { inner } } @@ -40,41 +45,41 @@ impl UnsyncBoxService { /// [`Layer`]: crate::Layer pub fn layer() -> LayerFn Self> where - S: Service + 'static, - S::Future: 'static, + S: Service + 'a, + S::Future: 'a, { layer_fn(Self::new) } } -impl Service for UnsyncBoxService { +impl<'a, T, U, E> Service for UnsyncBoxService<'a, T, U, E> { type Response = U; type Error = E; - type Future = UnsyncBoxFuture; + type Future = UnsyncBoxFuture<'a, U, E>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) } - fn call(&mut self, request: T) -> UnsyncBoxFuture { + fn call(&mut self, request: T) -> UnsyncBoxFuture<'a, U, E> { self.inner.call(request) } } -impl fmt::Debug for UnsyncBoxService { +impl<'a, T, U, E> fmt::Debug for UnsyncBoxService<'a, T, U, E> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("UnsyncBoxService").finish() } } -impl Service for UnsyncBoxed +impl<'a, S, Request> Service for UnsyncBoxed<'a, S> where - S: Service + 'static, - S::Future: 'static, + S: Service + 'a, + S::Future: 'a, { type Response = S::Response; type Error = S::Error; - type Future = Pin>>>; + type Future = Pin> + 'a>>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) diff --git a/tower/src/util/boxed_clone.rs b/tower/src/util/boxed_clone.rs index 1209fd2ef..0915b41b4 100644 --- a/tower/src/util/boxed_clone.rs +++ b/tower/src/util/boxed_clone.rs @@ -55,19 +55,20 @@ use tower_service::Service; /// # fn assert_service(svc: S) -> S /// # where S: Service { svc } /// ``` -pub struct BoxCloneService( +pub struct BoxCloneService<'a, T, U, E>( Box< - dyn CloneService>> + dyn 'a + + CloneService>> + Send, >, ); -impl BoxCloneService { +impl<'a, T, U, E> BoxCloneService<'a, T, U, E> { /// Create a new `BoxCloneService`. pub fn new(inner: S) -> Self where - S: Service + Clone + Send + 'static, - S::Future: Send + 'static, + S: Service + Clone + Send + 'a, + S::Future: Send + 'a, { let inner = inner.map_future(|f| Box::pin(f) as _); BoxCloneService(Box::new(inner)) @@ -79,17 +80,17 @@ impl BoxCloneService { /// [`Layer`]: crate::Layer pub fn layer() -> LayerFn Self> where - S: Service + Clone + Send + 'static, - S::Future: Send + 'static, + S: Service + Clone + Send + 'a, + S::Future: Send + 'a, { layer_fn(Self::new) } } -impl Service for BoxCloneService { +impl<'a, T, U, E> Service for BoxCloneService<'a, T, U, E> { type Response = U; type Error = E; - type Future = BoxFuture<'static, Result>; + type Future = BoxFuture<'a, Result>; #[inline] fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { @@ -102,34 +103,44 @@ impl Service for BoxCloneService { } } -impl Clone for BoxCloneService { +impl<'a, T: 'a, U: 'a, E: 'a> Clone for BoxCloneService<'a, T, U, E> { fn clone(&self) -> Self { Self(self.0.clone_box()) } } trait CloneService: Service { - fn clone_box( + fn clone_box<'a>( &self, ) -> Box< - dyn CloneService + dyn 'a + + CloneService + Send, - >; + > + where + Self: 'a; } impl CloneService for T where - T: Service + Send + Clone + 'static, + T: Service + Send + Clone, { - fn clone_box( + fn clone_box<'a>( &self, - ) -> Box + Send> + ) -> Box< + dyn CloneService + + Send + + 'a, + > + where + Self: 'a, { - Box::new(self.clone()) + let v = self.clone(); + Box::new(v) } } -impl fmt::Debug for BoxCloneService { +impl<'a, T, U, E> fmt::Debug for BoxCloneService<'a, T, U, E> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BoxCloneService").finish() } diff --git a/tower/src/util/mod.rs b/tower/src/util/mod.rs index c617a9e05..c920ea2ce 100644 --- a/tower/src/util/mod.rs +++ b/tower/src/util/mod.rs @@ -980,10 +980,10 @@ pub trait ServiceExt: tower_service::Service { /// /// [`Service`]: crate::Service /// [`boxed_clone`]: Self::boxed_clone - fn boxed(self) -> BoxService + fn boxed<'a>(self) -> BoxService<'a, Request, Self::Response, Self::Error> where - Self: Sized + Send + 'static, - Self::Future: Send + 'static, + Self: Sized + Send + 'a, + Self::Future: Send + 'a, { BoxService::new(self) } @@ -1029,10 +1029,10 @@ pub trait ServiceExt: tower_service::Service { /// /// [`Service`]: crate::Service /// [`boxed`]: Self::boxed - fn boxed_clone(self) -> BoxCloneService + fn boxed_clone<'a>(self) -> BoxCloneService<'a, Request, Self::Response, Self::Error> where - Self: Clone + Sized + Send + 'static, - Self::Future: Send + 'static, + Self: Clone + Sized + Send + 'a, + Self::Future: Send + 'a, { BoxCloneService::new(self) }