@@ -404,9 +404,9 @@ fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reifi
404
404
where
405
405
I : tags:: Type < ' a > ,
406
406
{
407
- let mut tagged = TaggedOption :: < ' a , I > ( None ) ;
407
+ let mut tagged = Tagged { tag_id : TypeId :: of :: < I > ( ) , value : TaggedOption :: < ' a , I > ( None ) } ;
408
408
err. provide ( tagged. as_request ( ) ) ;
409
- tagged. 0
409
+ tagged. value . 0
410
410
}
411
411
412
412
///////////////////////////////////////////////////////////////////////////////
@@ -507,16 +507,9 @@ where
507
507
///
508
508
#[ unstable( feature = "error_generic_member_access" , issue = "99301" ) ]
509
509
#[ 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 > ) ;
511
511
512
512
impl < ' 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
-
520
513
/// Provide a value or other type with only static lifetimes.
521
514
///
522
515
/// # Examples
@@ -940,37 +933,38 @@ pub(crate) mod tags {
940
933
#[ repr( transparent) ]
941
934
pub ( crate ) struct TaggedOption < ' a , I : tags:: Type < ' a > > ( pub Option < I :: Reified > ) ;
942
935
943
- impl < ' a , I : tags:: Type < ' a > > TaggedOption < ' a , I > {
936
+ impl < ' a , I : tags:: Type < ' a > > Tagged < TaggedOption < ' a , I > > {
944
937
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 > ) }
946
942
}
947
943
}
948
944
949
945
/// Represents a type-erased but identifiable object.
950
946
///
951
947
/// 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 { }
956
949
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 ,
961
955
}
962
956
963
- impl < ' a > dyn Erased < ' a > + ' a {
957
+ impl < ' a > Tagged < dyn Erased < ' a > + ' a > {
964
958
/// Returns some reference to the dynamic value if it is tagged with `I`,
965
959
/// or `None` otherwise.
966
960
#[ inline]
967
961
fn downcast < I > ( & self ) -> Option < & TaggedOption < ' a , I > >
968
962
where
969
963
I : tags:: Type < ' a > ,
970
964
{
971
- if self . tag_id ( ) == TypeId :: of :: < I > ( ) {
965
+ if self . tag_id == TypeId :: of :: < I > ( ) {
972
966
// 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 )
974
968
} else {
975
969
None
976
970
}
@@ -983,9 +977,12 @@ impl<'a> dyn Erased<'a> + 'a {
983
977
where
984
978
I : tags:: Type < ' a > ,
985
979
{
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
+ )
989
986
} else {
990
987
None
991
988
}
0 commit comments