@@ -2,7 +2,8 @@ use crate::mir;
2
2
use crate :: query:: CyclePlaceholder ;
3
3
use crate :: traits;
4
4
use 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 } ;
6
7
7
8
#[ derive( Copy , Clone ) ]
8
9
pub struct Erased < T : Copy > {
@@ -29,31 +30,40 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> {
29
30
} ;
30
31
31
32
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
+ //
32
40
// 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) } ,
34
42
}
35
43
}
36
44
37
45
/// Restores an erased value.
38
46
#[ inline( always) ]
39
47
pub fn restore < T : EraseType > ( value : Erase < T > ) -> T {
40
48
let value: Erased < <T as EraseType >:: Result > = value;
49
+ // See comment in `erase` for why we use `transmute_unchecked`.
50
+ //
41
51
// SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance
42
52
// of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of
43
53
// the right size.
44
- unsafe { transmute_copy ( & value. data ) }
54
+ unsafe { transmute_unchecked :: < MaybeUninit < T :: Result > , T > ( value. data ) }
45
55
}
46
56
47
57
impl < T > EraseType for & ' _ T {
48
- type Result = [ u8 ; size_of :: < * const ( ) > ( ) ] ;
58
+ type Result = [ u8 ; size_of :: < & ' static ( ) > ( ) ] ;
49
59
}
50
60
51
61
impl < T > EraseType for & ' _ [ T ] {
52
- type Result = [ u8 ; size_of :: < * const [ ( ) ] > ( ) ] ;
62
+ type Result = [ u8 ; size_of :: < & ' static [ ( ) ] > ( ) ] ;
53
63
}
54
64
55
65
impl < T > EraseType for & ' _ ty:: List < T > {
56
- type Result = [ u8 ; size_of :: < * const ( ) > ( ) ] ;
66
+ type Result = [ u8 ; size_of :: < & ' static ty :: List < ( ) > > ( ) ] ;
57
67
}
58
68
59
69
impl < I : rustc_index:: Idx , T > EraseType for & ' _ rustc_index:: IndexSlice < I , T > {
0 commit comments