Skip to content
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
77 changes: 74 additions & 3 deletions library/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,68 @@ impl<'a> Request<'a> {
self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
}

/// Provides a mutable reference. The referee type must be bounded by `'static`,
/// but may be unsized.
///
/// # Examples
///
/// Provides a mutable reference to a field as a `&mut str`.
///
/// ```rust
/// #![feature(context_provider)]
///
/// use core::error::Request;
///
/// #[derive(Debug)]
/// struct SomeConcreteType { field: String }
///
/// impl std::task::Provider for SomeConcreteType {
/// fn provide_mut<'a>(&'a mut self, request: &mut Request<'a>) {
/// request.provide_mut::<str>(&mut self.field);
/// }
/// }
/// ```
#[unstable(feature = "context_provider", issue = "none")]
pub fn provide_mut<T: ?Sized + 'static>(&mut self, value: &'a mut T) -> &mut Self {
self.provide::<tags::RefMut<tags::MaybeSizedValue<T>>>(value)
}

/// Provides a mutable reference computed using a closure. The referee type
/// must be bounded by `'static`, but may be unsized.
///
/// # Examples
///
/// Provides a reference to a field as a `&mut str`.
///
/// ```rust
/// #![feature(context_provider)]
///
/// use core::error::Request;
///
/// #[derive(Debug)]
/// struct SomeConcreteType { business: String, party: String }
/// fn today_is_a_weekday() -> bool { true }
///
/// impl std::task::Provider for SomeConcreteType {
/// fn provide_mut<'a>(&'a mut self, request: &mut Request<'a>) {
/// request.provide_mut_with::<str>(|| {
/// if today_is_a_weekday() {
/// &mut self.business
/// } else {
/// &mut self.party
/// }
/// });
/// }
/// }
/// ```
#[unstable(feature = "context_provider", issue = "none")]
pub fn provide_mut_with<T: ?Sized + 'static>(
&mut self,
fulfil: impl FnOnce() -> &'a mut T,
) -> &mut Self {
self.provide_with::<tags::RefMut<tags::MaybeSizedValue<T>>>(fulfil)
}

/// Provides a value with the given `Type` tag.
fn provide<I>(&mut self, value: I::Reified) -> &mut Self
where
Expand Down Expand Up @@ -922,6 +984,15 @@ pub(crate) mod tags {
impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
type Reified = &'a I::Reified;
}

/// Type-based tag for mutable reference types (`&'a mut T`, where T is represented by
/// `<I as MaybeSizedType<'a>>::Reified`.
#[derive(Debug)]
pub(crate) struct RefMut<I>(PhantomData<I>);

impl<'a, I: MaybeSizedType<'a>> Type<'a> for RefMut<I> {
type Reified = &'a mut I::Reified;
}
}

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

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

struct Tagged<E: ?Sized> {
tag_id: TypeId,
value: E,
pub(crate) struct Tagged<E: ?Sized> {
pub tag_id: TypeId,
pub value: E,
}

impl<'a> Tagged<dyn Erased<'a> + 'a> {
Expand Down
4 changes: 3 additions & 1 deletion library/core/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ pub use self::poll::Poll;

mod wake;
#[stable(feature = "futures_api", since = "1.36.0")]
pub use self::wake::{Context, ContextBuilder, LocalWaker, RawWaker, RawWakerVTable, Waker};
pub use self::wake::{
Context, ContextBuilder, LocalWaker, Provider, RawWaker, RawWakerVTable, Waker,
};

mod ready;
#[stable(feature = "ready_macro", since = "1.64.0")]
Expand Down
Loading
Loading