@@ -2,7 +2,8 @@ use crate::mir;
22use  crate :: query:: CyclePlaceholder ; 
33use  crate :: traits; 
44use  crate :: ty:: { self ,  Ty } ; 
5- use  std:: mem:: { size_of,  transmute_copy,  MaybeUninit } ; 
5+ use  std:: intrinsics:: transmute_unchecked; 
6+ use  std:: mem:: { size_of,  MaybeUninit } ; 
67
78#[ derive( Copy ,  Clone ) ]  
89pub  struct  Erased < T :  Copy >  { 
@@ -29,31 +30,40 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> {
2930    } ; 
3031
3132    Erased :: < <T  as  EraseType >:: Result >  { 
33+         // `transmute_unchecked` is needed here because it does not have `transmute`'s size check 
34+         // (and thus allows to transmute between `T` and `MaybeUninit<T::Result>`) (we do the size 
35+         // check ourselves in the `const` block above). 
36+         // 
37+         // `transmute_copy` is also commonly used for this (and it would work here since 
38+         // `EraseType: Copy`), but `transmute_unchecked` better explains the intent. 
39+         // 
3240        // SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes. 
33-         data :  unsafe  {  transmute_copy ( & src)  } , 
41+         data :  unsafe  {  transmute_unchecked :: < T ,   MaybeUninit < T :: Result > > ( src)  } , 
3442    } 
3543} 
3644
3745/// Restores an erased value. 
3846#[ inline( always) ]  
3947pub  fn  restore < T :  EraseType > ( value :  Erase < T > )  -> T  { 
4048    let  value:  Erased < <T  as  EraseType >:: Result >  = value; 
49+     // See comment in `erase` for why we use `transmute_unchecked`. 
50+     // 
4151    // SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance 
4252    // of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of 
4353    // the right size. 
44-     unsafe  {  transmute_copy ( & value. data )  } 
54+     unsafe  {  transmute_unchecked :: < MaybeUninit < T :: Result > ,   T > ( value. data )  } 
4555} 
4656
4757impl < T >  EraseType  for  & ' _  T  { 
48-     type  Result  = [ u8 ;  size_of :: < * const  ( ) > ( ) ] ; 
58+     type  Result  = [ u8 ;  size_of :: < & ' static  ( ) > ( ) ] ; 
4959} 
5060
5161impl < T >  EraseType  for  & ' _  [ T ]  { 
52-     type  Result  = [ u8 ;  size_of :: < * const  [ ( ) ] > ( ) ] ; 
62+     type  Result  = [ u8 ;  size_of :: < & ' static  [ ( ) ] > ( ) ] ; 
5363} 
5464
5565impl < T >  EraseType  for  & ' _  ty:: List < T >  { 
56-     type  Result  = [ u8 ;  size_of :: < * const   ( ) > ( ) ] ; 
66+     type  Result  = [ u8 ;  size_of :: < & ' static  ty :: List < ( ) > > ( ) ] ; 
5767} 
5868
5969impl < I :  rustc_index:: Idx ,  T >  EraseType  for  & ' _  rustc_index:: IndexSlice < I ,  T >  { 
0 commit comments