@@ -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