@@ -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
9491020unsafe 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
9561027impl < ' a > Tagged < dyn Erased < ' a > + ' a > {
0 commit comments