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

Expose nameable future for TaskLocal::scope #3273

Merged
2 changes: 1 addition & 1 deletion tokio/src/task/mod.rs
Expand Up @@ -235,5 +235,5 @@ cfg_rt! {
pub use local::{spawn_local, LocalSet};

mod task_local;
pub use task_local::LocalKey;
pub use task_local::{LocalKey, TaskLocalFuture};
}
37 changes: 32 additions & 5 deletions tokio/src/task/task_local.rs
Expand Up @@ -115,7 +115,7 @@ impl<T: 'static> LocalKey<T> {
/// }).await;
/// # }
/// ```
pub async fn scope<F>(&'static self, value: T, f: F) -> F::Output
pub fn scope<F>(&'static self, value: T, f: F) -> TaskLocalFuture<T, F>
where
F: Future,
{
Expand All @@ -124,7 +124,6 @@ impl<T: 'static> LocalKey<T> {
slot: Some(value),
future: f,
}
.await
}

/// Accesses the current task-local and runs the provided closure.
Expand Down Expand Up @@ -177,7 +176,28 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
}

pin_project! {
struct TaskLocalFuture<T: StaticLifetime, F> {
/// A future that sets a value `T` of a task local for the future `F` during
/// its execution.
///
/// The value of the task-local must be `'static` and will be dropped on the
/// completion of the future.
///
/// Created by the function [`LocalKey::scope`](self::LocalKey::scope).
///
/// ### Examples
///
/// ```
/// # async fn dox() {
/// tokio::task_local! {
/// static NUMBER: u32;
/// }
///
/// NUMBER.scope(1, async move {
/// println!("task local value: {}", NUMBER.get());
/// }).await;
/// # }
/// ```
pub struct TaskLocalFuture<T: StaticLifetime, F> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we move forward, we would not want to expose StaticLifetime here. It is an implementation detail.

local: &'static LocalKey<T>,
slot: Option<T>,
#[pin]
Expand Down Expand Up @@ -217,8 +237,15 @@ impl<T: 'static, F: Future> Future for TaskLocalFuture<T, F> {
}
}

// Required to make `pin_project` happy.
trait StaticLifetime: 'static {}
mod sealed {
pub trait Sealed {}

impl<T: 'static> Sealed for T {}
}

/// Required to make `pin_project` happy.
#[doc(hidden)]
pub trait StaticLifetime: self::sealed::Sealed + 'static {}
impl<T: 'static> StaticLifetime for T {}

/// An error returned by [`LocalKey::try_with`](method@LocalKey::try_with).
Expand Down