@@ -404,9 +404,9 @@ fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reifi
404404where
405405 I : tags:: Type < ' a > ,
406406{
407- let mut tagged = TaggedOption :: < ' a , I > ( None ) ;
407+ let mut tagged = Tagged { tag_id : TypeId :: of :: < I > ( ) , value : TaggedOption :: < ' a , I > ( None ) } ;
408408 err. provide ( tagged. as_request ( ) ) ;
409- tagged. 0
409+ tagged. value . 0
410410}
411411
412412///////////////////////////////////////////////////////////////////////////////
@@ -507,16 +507,9 @@ where
507507///
508508#[ unstable( feature = "error_generic_member_access" , issue = "99301" ) ]
509509#[ cfg_attr( not( doc) , repr( transparent) ) ] // work around https://github.com/rust-lang/rust/issues/90435
510- pub struct Request < ' a > ( dyn Erased < ' a > + ' a ) ;
510+ pub struct Request < ' a > ( Tagged < dyn Erased < ' a > + ' a > ) ;
511511
512512impl < ' a > Request < ' a > {
513- /// Create a new `&mut Request` from a `&mut dyn Erased` trait object.
514- fn new < ' b > ( erased : & ' b mut ( dyn Erased < ' a > + ' a ) ) -> & ' b mut Request < ' a > {
515- // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Request<'a>` is safe since
516- // `Request` is repr(transparent).
517- unsafe { & mut * ( erased as * mut dyn Erased < ' a > as * mut Request < ' a > ) }
518- }
519-
520513 /// Provide a value or other type with only static lifetimes.
521514 ///
522515 /// # Examples
@@ -940,37 +933,38 @@ pub(crate) mod tags {
940933#[ repr( transparent) ]
941934pub ( crate ) struct TaggedOption < ' a , I : tags:: Type < ' a > > ( pub Option < I :: Reified > ) ;
942935
943- impl < ' a , I : tags:: Type < ' a > > TaggedOption < ' a , I > {
936+ impl < ' a , I : tags:: Type < ' a > > Tagged < TaggedOption < ' a , I > > {
944937 pub ( crate ) fn as_request ( & mut self ) -> & mut Request < ' a > {
945- Request :: new ( self as & mut ( dyn Erased < ' a > + ' a ) )
938+ let erased = self as & mut Tagged < dyn Erased < ' a > + ' a > ;
939+ // SAFETY: transmuting `&mut Tagged<dyn Erased<'a> + 'a>` to `&mut Request<'a>` is safe since
940+ // `Request` is repr(transparent).
941+ unsafe { & mut * ( erased as * mut Tagged < dyn Erased < ' a > > as * mut Request < ' a > ) }
946942 }
947943}
948944
949945/// Represents a type-erased but identifiable object.
950946///
951947/// This trait is exclusively implemented by the `TaggedOption` type.
952- unsafe trait Erased < ' a > : ' a {
953- /// The `TypeId` of the erased type.
954- fn tag_id ( & self ) -> TypeId ;
955- }
948+ unsafe trait Erased < ' a > : ' a { }
956949
957- unsafe impl < ' a , I : tags:: Type < ' a > > Erased < ' a > for TaggedOption < ' a , I > {
958- fn tag_id ( & self ) -> TypeId {
959- TypeId :: of :: < I > ( )
960- }
950+ unsafe impl < ' a , I : tags:: Type < ' a > > Erased < ' a > for TaggedOption < ' a , I > { }
951+
952+ struct Tagged < E : ?Sized > {
953+ tag_id : TypeId ,
954+ value : E ,
961955}
962956
963- impl < ' a > dyn Erased < ' a > + ' a {
957+ impl < ' a > Tagged < dyn Erased < ' a > + ' a > {
964958 /// Returns some reference to the dynamic value if it is tagged with `I`,
965959 /// or `None` otherwise.
966960 #[ inline]
967961 fn downcast < I > ( & self ) -> Option < & TaggedOption < ' a , I > >
968962 where
969963 I : tags:: Type < ' a > ,
970964 {
971- if self . tag_id ( ) == TypeId :: of :: < I > ( ) {
965+ if self . tag_id == TypeId :: of :: < I > ( ) {
972966 // SAFETY: Just checked whether we're pointing to an I.
973- Some ( unsafe { & * ( self as * const Self ) . cast :: < TaggedOption < ' a , I > > ( ) } )
967+ Some ( & unsafe { & * ( self as * const Self ) . cast :: < Tagged < TaggedOption < ' a , I > > > ( ) } . value )
974968 } else {
975969 None
976970 }
@@ -983,9 +977,12 @@ impl<'a> dyn Erased<'a> + 'a {
983977 where
984978 I : tags:: Type < ' a > ,
985979 {
986- if self . tag_id ( ) == TypeId :: of :: < I > ( ) {
987- // SAFETY: Just checked whether we're pointing to an I.
988- Some ( unsafe { & mut * ( self as * mut Self ) . cast :: < TaggedOption < ' a , I > > ( ) } )
980+ if self . tag_id == TypeId :: of :: < I > ( ) {
981+ Some (
982+ // SAFETY: Just checked whether we're pointing to an I.
983+ & mut unsafe { & mut * ( self as * mut Self ) . cast :: < Tagged < TaggedOption < ' a , I > > > ( ) }
984+ . value ,
985+ )
989986 } else {
990987 None
991988 }
0 commit comments