Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable non-'static where possible #765

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tower/src/buffer/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ where
/// the background `Worker` that you can then spawn.
pub fn pair<S>(service: S, bound: usize) -> (Self, Worker<S, Req>)
where
S: Service<Req, Future = F> + Send + 'static,
S: Service<Req, Future = F> + Send,
F: Send,
S::Error: Into<crate::BoxError> + Send + Sync,
Req: Send + 'static,
Expand Down Expand Up @@ -132,8 +132,8 @@ where

impl<Req, F> Clone for Buffer<Req, F>
where
Req: Send + 'static,
F: Send + 'static,
Req: Send,
F: Send,
{
fn clone(&self) -> Self {
Self {
Expand Down
16 changes: 9 additions & 7 deletions tower/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use std::fmt;
/// # #[cfg(feature = "limit")]
/// # use tower::limit::concurrency::ConcurrencyLimitLayer;
/// # #[cfg(feature = "limit")]
/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + Send, S::Future: Send {
/// ServiceBuilder::new()
/// .concurrency_limit(5)
/// .service(svc);
Expand Down Expand Up @@ -703,14 +703,15 @@ impl<L> ServiceBuilder<L> {
///
/// [`BoxService::layer()`]: crate::util::BoxService::layer()
#[cfg(feature = "util")]
pub fn boxed<S, R>(
pub fn boxed<'a, S, R>(
self,
) -> ServiceBuilder<
Stack<
tower_layer::LayerFn<
fn(
L::Service,
) -> crate::util::BoxService<
'a,
R,
<L::Service as Service<R>>::Response,
<L::Service as Service<R>>::Error,
Expand All @@ -721,8 +722,8 @@ impl<L> ServiceBuilder<L> {
>
where
L: Layer<S>,
L::Service: Service<R> + Send + 'static,
<L::Service as Service<R>>::Future: Send + 'static,
L::Service: Service<R> + Send + 'a,
<L::Service as Service<R>>::Future: Send + 'a,
{
self.layer(crate::util::BoxService::layer())
}
Expand Down Expand Up @@ -766,14 +767,15 @@ impl<L> ServiceBuilder<L> {
/// [`BoxCloneService`]: crate::util::BoxCloneService
/// [`boxed`]: Self::boxed
#[cfg(feature = "util")]
pub fn boxed_clone<S, R>(
pub fn boxed_clone<'a, S, R>(
self,
) -> ServiceBuilder<
Stack<
tower_layer::LayerFn<
fn(
L::Service,
) -> crate::util::BoxCloneService<
'a,
R,
<L::Service as Service<R>>::Response,
<L::Service as Service<R>>::Error,
Expand All @@ -784,8 +786,8 @@ impl<L> ServiceBuilder<L> {
>
where
L: Layer<S>,
L::Service: Service<R> + Clone + Send + 'static,
<L::Service as Service<R>>::Future: Send + 'static,
L::Service: Service<R> + Clone + Send + 'a,
<L::Service as Service<R>>::Future: Send + 'a,
{
self.layer(crate::util::BoxCloneService::layer())
}
Expand Down
28 changes: 14 additions & 14 deletions tower/src/util/boxed/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ use tower_service::Service;
/// use std::time::Duration;
/// use tower::{Service, ServiceBuilder, BoxError, util::BoxLayer};
///
/// fn common_layer<S, T>() -> BoxLayer<S, T, S::Response, BoxError>
/// fn common_layer<'a, S, T>() -> BoxLayer<'a, S, T, S::Response, BoxError>
/// where
/// S: Service<T> + Send + 'static,
/// S::Future: Send + 'static,
/// S::Error: Into<BoxError> + 'static,
/// S: Service<T> + Send + 'a,
/// S::Future: Send + 'a,
/// S::Error: Into<BoxError> + 'a,
/// {
/// let builder = ServiceBuilder::new()
/// .concurrency_limit(100);
Expand All @@ -51,17 +51,17 @@ use tower_service::Service;
/// [`Service`]: tower_service::Service
/// [`BoxService`]: super::BoxService
/// [`Timeout`]: crate::timeout
pub struct BoxLayer<In, T, U, E> {
boxed: Arc<dyn Layer<In, Service = BoxService<T, U, E>> + Send + Sync + 'static>,
pub struct BoxLayer<'a, In, T, U, E> {
boxed: Arc<dyn Layer<In, Service = BoxService<'a, T, U, E>> + Send + Sync + 'a>,
}

impl<In, T, U, E> BoxLayer<In, T, U, E> {
impl<'a, In, T, U, E> BoxLayer<'a, In, T, U, E> {
/// Create a new [`BoxLayer`].
pub fn new<L>(inner_layer: L) -> Self
where
L: Layer<In> + Send + Sync + 'static,
L::Service: Service<T, Response = U, Error = E> + Send + 'static,
<L::Service as Service<T>>::Future: Send + 'static,
L: Layer<In> + Send + Sync + 'a,
L::Service: Service<T, Response = U, Error = E> + Send + 'a,
<L::Service as Service<T>>::Future: Send + 'a,
{
let layer = layer_fn(move |inner: In| {
let out = inner_layer.layer(inner);
Expand All @@ -74,23 +74,23 @@ impl<In, T, U, E> BoxLayer<In, T, U, E> {
}
}

impl<In, T, U, E> Layer<In> for BoxLayer<In, T, U, E> {
type Service = BoxService<T, U, E>;
impl<'a, In, T, U, E> Layer<In> 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<In, T, U, E> Clone for BoxLayer<In, T, U, E> {
impl<'a, In, T, U, E> Clone for BoxLayer<'a, In, T, U, E> {
fn clone(&self) -> Self {
Self {
boxed: Arc::clone(&self.boxed),
}
}
}

impl<In, T, U, E> fmt::Debug for BoxLayer<In, T, U, E> {
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()
}
Expand Down
28 changes: 14 additions & 14 deletions tower/src/util/boxed/layer_clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ use tower_service::Service;
/// # fn new() -> Self { Self }
/// # }
///
/// fn common_layer<S, T>() -> BoxCloneServiceLayer<S, T, S::Response, BoxError>
/// fn common_layer<'a, S, T>() -> BoxCloneServiceLayer<'a, S, T, S::Response, BoxError>
/// where
/// S: Service<T> + Clone + Send + 'static,
/// S::Future: Send + 'static,
/// S::Error: Into<BoxError> + 'static,
/// S: Service<T> + Clone + Send + 'a,
/// S::Future: Send + 'a,
/// S::Error: Into<BoxError> + 'a,
/// {
/// let builder = ServiceBuilder::new()
/// .concurrency_limit(100);
Expand Down Expand Up @@ -82,17 +82,17 @@ use tower_service::Service;
/// [`Service`]: tower_service::Service
/// [`BoxService`]: super::BoxService
/// [`Timeout`]: crate::timeout
pub struct BoxCloneServiceLayer<In, T, U, E> {
boxed: Arc<dyn Layer<In, Service = BoxCloneService<T, U, E>> + Send + Sync + 'static>,
pub struct BoxCloneServiceLayer<'a, In, T, U, E> {
boxed: Arc<dyn Layer<In, Service = BoxCloneService<'a, T, U, E>> + Send + Sync + 'a>,
}

impl<In, T, U, E> BoxCloneServiceLayer<In, T, U, E> {
impl<'a, In, T, U, E> BoxCloneServiceLayer<'a, In, T, U, E> {
/// Create a new [`BoxCloneServiceLayer`].
pub fn new<L>(inner_layer: L) -> Self
where
L: Layer<In> + Send + Sync + 'static,
L::Service: Service<T, Response = U, Error = E> + Send + Clone + 'static,
<L::Service as Service<T>>::Future: Send + 'static,
L: Layer<In> + Send + Sync + 'a,
L::Service: Service<T, Response = U, Error = E> + Send + Clone + 'a,
<L::Service as Service<T>>::Future: Send + 'a,
{
let layer = layer_fn(move |inner: In| {
let out = inner_layer.layer(inner);
Expand All @@ -105,23 +105,23 @@ impl<In, T, U, E> BoxCloneServiceLayer<In, T, U, E> {
}
}

impl<In, T, U, E> Layer<In> for BoxCloneServiceLayer<In, T, U, E> {
type Service = BoxCloneService<T, U, E>;
impl<'a, In, T, U, E> Layer<In> 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<In, T, U, E> Clone for BoxCloneServiceLayer<In, T, U, E> {
impl<'a, In, T, U, E> Clone for BoxCloneServiceLayer<'a, In, T, U, E> {
fn clone(&self) -> Self {
Self {
boxed: Arc::clone(&self.boxed),
}
}
}

impl<In, T, U, E> fmt::Debug for BoxCloneServiceLayer<In, T, U, E> {
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()
}
Expand Down
32 changes: 17 additions & 15 deletions tower/src/util/boxed/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,29 @@ use std::{
///
/// [`Service`]: crate::Service
/// [`Rc`]: std::rc::Rc
pub struct BoxService<T, U, E> {
inner:
SyncWrapper<Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send>>,
pub struct BoxService<'a, T, U, E> {
inner: SyncWrapper<
Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<'a, U, E>> + 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<T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + Send>>;
type BoxFuture<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'a>>;

impl<T, U, E> BoxService<T, U, E> {
impl<'a, T, U, E> BoxService<'a, T, U, E> {
#[allow(missing_docs)]
pub fn new<S>(inner: S) -> Self
where
S: Service<T, Response = U, Error = E> + Send + 'static,
S::Future: Send + 'static,
S: Service<T, Response = U, Error = E> + Send + 'a,
S::Future: Send + 'a,
{
// rust can't infer the type
let inner: Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send> =
Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _));
let inner: Box<
dyn Service<T, Response = U, Error = E, Future = BoxFuture<'a, U, E>> + Send + 'a,
> = Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _));
let inner = SyncWrapper::new(inner);
BoxService { inner }
}
Expand All @@ -76,28 +78,28 @@ impl<T, U, E> BoxService<T, U, E> {
/// [`Layer`]: crate::Layer
pub fn layer<S>() -> LayerFn<fn(S) -> Self>
where
S: Service<T, Response = U, Error = E> + Send + 'static,
S::Future: Send + 'static,
S: Service<T, Response = U, Error = E> + Send + 'a,
S::Future: Send + 'a,
{
layer_fn(Self::new)
}
}

impl<T, U, E> Service<T> for BoxService<T, U, E> {
impl<'a, T, U, E> Service<T> for BoxService<'a, T, U, E> {
type Response = U;
type Error = E;
type Future = BoxFuture<U, E>;
type Future = BoxFuture<'a, U, E>;

fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
self.inner.get_mut().poll_ready(cx)
}

fn call(&mut self, request: T) -> BoxFuture<U, E> {
fn call(&mut self, request: T) -> BoxFuture<'a, U, E> {
self.inner.get_mut().call(request)
}
}

impl<T, U, E> fmt::Debug for BoxService<T, U, E> {
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()
}
Expand Down
41 changes: 23 additions & 18 deletions tower/src/util/boxed/unsync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T, U, E> {
inner: Box<dyn Service<T, Response = U, Error = E, Future = UnsyncBoxFuture<U, E>>>,
pub struct UnsyncBoxService<'a, T, U, E> {
inner: Box<dyn Service<T, Response = U, Error = E, Future = UnsyncBoxFuture<'a, U, E>> + '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<T, E> = Pin<Box<dyn Future<Output = Result<T, E>>>>;
type UnsyncBoxFuture<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a>>;

#[derive(Debug)]
struct UnsyncBoxed<S> {
struct UnsyncBoxed<'a, S> {
inner: S,
_marker: PhantomData<&'a ()>,
}

impl<T, U, E> UnsyncBoxService<T, U, E> {
impl<'a, T, U, E> UnsyncBoxService<'a, T, U, E> {
#[allow(missing_docs)]
pub fn new<S>(inner: S) -> Self
where
S: Service<T, Response = U, Error = E> + 'static,
S::Future: 'static,
S: Service<T, Response = U, Error = E> + 'a,
S::Future: 'a,
{
let inner = Box::new(UnsyncBoxed { inner });
let inner = Box::new(UnsyncBoxed {
inner,
_marker: PhantomData,
});
UnsyncBoxService { inner }
}

Expand All @@ -40,41 +45,41 @@ impl<T, U, E> UnsyncBoxService<T, U, E> {
/// [`Layer`]: crate::Layer
pub fn layer<S>() -> LayerFn<fn(S) -> Self>
where
S: Service<T, Response = U, Error = E> + 'static,
S::Future: 'static,
S: Service<T, Response = U, Error = E> + 'a,
S::Future: 'a,
{
layer_fn(Self::new)
}
}

impl<T, U, E> Service<T> for UnsyncBoxService<T, U, E> {
impl<'a, T, U, E> Service<T> for UnsyncBoxService<'a, T, U, E> {
type Response = U;
type Error = E;
type Future = UnsyncBoxFuture<U, E>;
type Future = UnsyncBoxFuture<'a, U, E>;

fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
self.inner.poll_ready(cx)
}

fn call(&mut self, request: T) -> UnsyncBoxFuture<U, E> {
fn call(&mut self, request: T) -> UnsyncBoxFuture<'a, U, E> {
self.inner.call(request)
}
}

impl<T, U, E> fmt::Debug for UnsyncBoxService<T, U, E> {
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<S, Request> Service<Request> for UnsyncBoxed<S>
impl<'a, S, Request> Service<Request> for UnsyncBoxed<'a, S>
where
S: Service<Request> + 'static,
S::Future: 'static,
S: Service<Request> + 'a,
S::Future: 'a,
{
type Response = S::Response;
type Error = S::Error;
type Future = Pin<Box<dyn Future<Output = Result<S::Response, S::Error>>>>;
type Future = Pin<Box<dyn Future<Output = Result<S::Response, S::Error>> + 'a>>;

fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
Expand Down
Loading