Skip to content

Commit 9098cc4

Browse files
committed
Add provider-style API to Context
1 parent 4363f9b commit 9098cc4

File tree

5 files changed

+390
-9
lines changed

5 files changed

+390
-9
lines changed

library/core/src/error.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,68 @@ impl<'a> Request<'a> {
650650
self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
651651
}
652652

653+
/// Provides a mutable reference. The referee type must be bounded by `'static`,
654+
/// but may be unsized.
655+
///
656+
/// # Examples
657+
///
658+
/// Provides a mutable reference to a field as a `&mut str`.
659+
///
660+
/// ```rust
661+
/// #![feature(context_provider)]
662+
///
663+
/// use core::error::Request;
664+
///
665+
/// #[derive(Debug)]
666+
/// struct SomeConcreteType { field: String }
667+
///
668+
/// impl std::task::Provider for SomeConcreteType {
669+
/// fn provide_mut<'a>(&'a mut self, request: &mut Request<'a>) {
670+
/// request.provide_mut::<str>(&mut self.field);
671+
/// }
672+
/// }
673+
/// ```
674+
#[unstable(feature = "context_provider", issue = "none")]
675+
pub fn provide_mut<T: ?Sized + 'static>(&mut self, value: &'a mut T) -> &mut Self {
676+
self.provide::<tags::RefMut<tags::MaybeSizedValue<T>>>(value)
677+
}
678+
679+
/// Provides a mutable reference computed using a closure. The referee type
680+
/// must be bounded by `'static`, but may be unsized.
681+
///
682+
/// # Examples
683+
///
684+
/// Provides a reference to a field as a `&mut str`.
685+
///
686+
/// ```rust
687+
/// #![feature(context_provider)]
688+
///
689+
/// use core::error::Request;
690+
///
691+
/// #[derive(Debug)]
692+
/// struct SomeConcreteType { business: String, party: String }
693+
/// fn today_is_a_weekday() -> bool { true }
694+
///
695+
/// impl std::task::Provider for SomeConcreteType {
696+
/// fn provide_mut<'a>(&'a mut self, request: &mut Request<'a>) {
697+
/// request.provide_mut_with::<str>(|| {
698+
/// if today_is_a_weekday() {
699+
/// &mut self.business
700+
/// } else {
701+
/// &mut self.party
702+
/// }
703+
/// });
704+
/// }
705+
/// }
706+
/// ```
707+
#[unstable(feature = "context_provider", issue = "none")]
708+
pub fn provide_mut_with<T: ?Sized + 'static>(
709+
&mut self,
710+
fulfil: impl FnOnce() -> &'a mut T,
711+
) -> &mut Self {
712+
self.provide_with::<tags::RefMut<tags::MaybeSizedValue<T>>>(fulfil)
713+
}
714+
653715
/// Provides a value with the given `Type` tag.
654716
fn provide<I>(&mut self, value: I::Reified) -> &mut Self
655717
where
@@ -922,6 +984,15 @@ pub(crate) mod tags {
922984
impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
923985
type Reified = &'a I::Reified;
924986
}
987+
988+
/// Type-based tag for mutable reference types (`&'a mut T`, where T is represented by
989+
/// `<I as MaybeSizedType<'a>>::Reified`.
990+
#[derive(Debug)]
991+
pub(crate) struct RefMut<I>(PhantomData<I>);
992+
993+
impl<'a, I: MaybeSizedType<'a>> Type<'a> for RefMut<I> {
994+
type Reified = &'a mut I::Reified;
995+
}
925996
}
926997

927998
/// An `Option` with a type tag `I`.
@@ -948,9 +1019,9 @@ unsafe trait Erased<'a>: 'a {}
9481019

9491020
unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {}
9501021

951-
struct Tagged<E: ?Sized> {
952-
tag_id: TypeId,
953-
value: E,
1022+
pub(crate) struct Tagged<E: ?Sized> {
1023+
pub tag_id: TypeId,
1024+
pub value: E,
9541025
}
9551026

9561027
impl<'a> Tagged<dyn Erased<'a> + 'a> {

library/core/src/task/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ pub use self::poll::Poll;
88

99
mod wake;
1010
#[stable(feature = "futures_api", since = "1.36.0")]
11-
pub use self::wake::{Context, ContextBuilder, LocalWaker, RawWaker, RawWakerVTable, Waker};
11+
pub use self::wake::{
12+
Context, ContextBuilder, LocalWaker, Provider, RawWaker, RawWakerVTable, Waker,
13+
};
1214

1315
mod ready;
1416
#[stable(feature = "ready_macro", since = "1.64.0")]

0 commit comments

Comments
 (0)