9393//! trait for objects which can provide data, and the [`request_value`] and [`request_ref`]
9494//! functions for requesting data from an object which implements `Provider`. Generally, end users
9595//! should not call `request_*` directly, they are helper functions for intermediate implementers
96- //! to use to implement a user-facing interface.
96+ //! to use to implement a user-facing interface. This is purely for the sake of ergonomics, there is
97+ //! safety concern here; intermediate implementers can typically support methods rather than
98+ //! free functions and use more specific names.
9799//!
98100//! Typically, a data provider is a trait object of a trait which extends `Provider`. A user will
99101//! request data from a trait object by specifying the type of the data.
155157
156158use crate :: fmt;
157159use crate :: intrinsics;
158- use crate :: mem:: transmute;
159160
160161///////////////////////////////////////////////////////////////////////////////
161162// Any trait
@@ -781,18 +782,24 @@ pub trait Provider {
781782 /// Data providers should implement this method to provide *all* values they are able to
782783 /// provide by using `demand`.
783784 ///
785+ /// Note that the `provide_*` methods on `Demand` have short-circuit semantics: if an earlier
786+ /// method has successfully provided a value, then later methods will not get an opportunity to
787+ /// provide.
788+ ///
784789 /// # Examples
785790 ///
786- /// Provides a reference to a field with type `String` as a `&str`.
791+ /// Provides a reference to a field with type `String` as a `&str`, and a value of
792+ /// type `i32`.
787793 ///
788794 /// ```rust
789795 /// # #![feature(provide_any)]
790796 /// use std::any::{Provider, Demand};
791- /// # struct SomeConcreteType { field: String }
797+ /// # struct SomeConcreteType { field: String, num_field: i32 }
792798 ///
793799 /// impl Provider for SomeConcreteType {
794800 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
795- /// demand.provide_ref::<str>(&self.field);
801+ /// demand.provide_ref::<str>(&self.field)
802+ /// .provide_value::<i32, _>(|| self.num_field);
796803 /// }
797804 /// }
798805 /// ```
@@ -864,12 +871,18 @@ where
864871/// A helper object for providing data by type.
865872///
866873/// A data provider provides values by calling this type's provide methods.
867- #[ allow( missing_debug_implementations) ]
868874#[ unstable( feature = "provide_any" , issue = "96024" ) ]
869875#[ repr( transparent) ]
870876pub struct Demand < ' a > ( dyn Erased < ' a > + ' a ) ;
871877
872878impl < ' a > Demand < ' a > {
879+ /// Create a new `&mut Demand` from a `&mut dyn Erased` trait object.
880+ fn new < ' b > ( erased : & ' b mut ( dyn Erased < ' a > + ' a ) ) -> & ' b mut Demand < ' a > {
881+ // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Demand<'a>` is safe since
882+ // `Demand` is repr(transparent).
883+ unsafe { & mut * ( erased as * mut dyn Erased < ' a > as * mut Demand < ' a > ) }
884+ }
885+
873886 /// Provide a value or other type with only static lifetimes.
874887 ///
875888 /// # Examples
@@ -943,6 +956,13 @@ impl<'a> Demand<'a> {
943956 }
944957}
945958
959+ #[ unstable( feature = "provide_any" , issue = "96024" ) ]
960+ impl < ' a > fmt:: Debug for Demand < ' a > {
961+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
962+ f. debug_struct ( "Demand" ) . finish_non_exhaustive ( )
963+ }
964+ }
965+
946966///////////////////////////////////////////////////////////////////////////////
947967// Type tags
948968///////////////////////////////////////////////////////////////////////////////
@@ -951,9 +971,9 @@ mod tags {
951971 //! Type tags are used to identify a type using a separate value. This module includes type tags
952972 //! for some very common types.
953973 //!
954- //! Many users of the provider APIs will not need to use type tags at all. But if you want to
955- //! use them with more complex types (typically those including lifetime parameters), you will
956- //! need to write your own tags.
974+ //! Currently type tags are not exposed to the user. But in the future, if you want to use the
975+ //! Provider API with more complex types (typically those including lifetime parameters), you
976+ //! will need to write your own tags.
957977
958978 use crate :: marker:: PhantomData ;
959979
@@ -970,7 +990,7 @@ mod tags {
970990 }
971991
972992 /// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a
973- /// `' Sized` bound). E.g., `str`.
993+ /// `? Sized` bound). E.g., `str`.
974994 pub trait MaybeSizedType < ' a > : Sized + ' static {
975995 type Reified : ' a + ?Sized ;
976996 }
@@ -995,7 +1015,8 @@ mod tags {
9951015 type Reified = T ;
9961016 }
9971017
998- /// Type-based tag for `&'a T` types.
1018+ /// Type-based tag for reference types (`&'a T`, where T is represented by
1019+ /// `<I as MaybeSizedType<'a>>::Reified`.
9991020 #[ derive( Debug ) ]
10001021 pub struct Ref < I > ( PhantomData < I > ) ;
10011022
@@ -1014,28 +1035,26 @@ struct TaggedOption<'a, I: tags::Type<'a>>(Option<I::Reified>);
10141035
10151036impl < ' a , I : tags:: Type < ' a > > TaggedOption < ' a , I > {
10161037 fn as_demand ( & mut self ) -> & mut Demand < ' a > {
1017- // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Demand<'a>` is safe since
1018- // `Demand` is repr(transparent) and holds only a `dyn Erased<'a> + 'a`.
1019- unsafe { transmute ( self as & mut ( dyn Erased < ' a > + ' a ) ) }
1038+ Demand :: new ( self as & mut ( dyn Erased < ' a > + ' a ) )
10201039 }
10211040}
10221041
10231042/// Represents a type-erased but identifiable object.
10241043///
10251044/// This trait is exclusively implemented by the `TaggedOption` type.
1026- trait Erased < ' a > : ' a {
1045+ unsafe trait Erased < ' a > : ' a {
10271046 /// The `TypeId` of the erased type.
10281047 fn tag_id ( & self ) -> TypeId ;
10291048}
10301049
1031- impl < ' a , I : tags:: Type < ' a > > Erased < ' a > for TaggedOption < ' a , I > {
1050+ unsafe impl < ' a , I : tags:: Type < ' a > > Erased < ' a > for TaggedOption < ' a , I > {
10321051 fn tag_id ( & self ) -> TypeId {
10331052 TypeId :: of :: < I > ( )
10341053 }
10351054}
10361055
10371056#[ unstable( feature = "provide_any" , issue = "96024" ) ]
1038- impl < ' a > dyn Erased < ' a > {
1057+ impl < ' a > dyn Erased < ' a > + ' a {
10391058 /// Returns some reference to the dynamic value if it is tagged with `I`,
10401059 /// or `None` otherwise.
10411060 #[ inline]
@@ -1045,7 +1064,7 @@ impl<'a> dyn Erased<'a> {
10451064 {
10461065 if self . tag_id ( ) == TypeId :: of :: < I > ( ) {
10471066 // SAFETY: Just checked whether we're pointing to an I.
1048- Some ( unsafe { & mut * ( self as * mut Self as * mut TaggedOption < ' a , I > ) } )
1067+ Some ( unsafe { & mut * ( self as * mut Self ) . cast :: < TaggedOption < ' a , I > > ( ) } )
10491068 } else {
10501069 None
10511070 }
0 commit comments