55#![ allow( dead_code) ]
66
77use std:: mem:: transmute;
8+ use std:: ptr:: NonNull ;
89
910fn a < T , U : ?Sized > ( x : & [ T ] ) -> & U {
1011 unsafe { transmute ( x) } //~ ERROR cannot transmute between types of different sizes
@@ -15,11 +16,11 @@ fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U {
1516}
1617
1718fn c < T , U > ( x : & T ) -> & U {
18- unsafe { transmute ( x) }
19+ unsafe { transmute ( x) } // Ok!
1920}
2021
2122fn d < T , U > ( x : & [ T ] ) -> & [ U ] {
22- unsafe { transmute ( x) }
23+ unsafe { transmute ( x) } // Ok!
2324}
2425
2526fn e < T : ?Sized , U > ( x : & T ) -> & U {
@@ -30,4 +31,23 @@ fn f<T, U: ?Sized>(x: &T) -> &U {
3031 unsafe { transmute ( x) } //~ ERROR cannot transmute between types of different sizes
3132}
3233
34+ // We can transmute even between pointers of unknown size as long as the metadata of
35+ // input and output type are the same. This even accounts for null pointer optimizations.
36+ fn g1 < T : ?Sized > ( x : & T ) -> Option < & T > {
37+ unsafe { transmute ( x) } // Ok!
38+ }
39+
40+ fn g2 < T : ?Sized > ( x : Option < NonNull < T > > ) -> NonNull < T > {
41+ unsafe { transmute ( x) } // Ok!
42+ }
43+
44+ fn g3 < T : ?Sized > ( x : * const T ) -> Option < NonNull < T > > {
45+ unsafe { transmute ( x) } // Ok!
46+ }
47+
48+ // Make sure we can see through all the layers of `Box`.
49+ fn h < T : ?Sized > ( x : Box < T > ) -> & ' static T {
50+ unsafe { transmute ( x) } // Ok!
51+ }
52+
3353fn main ( ) { }
0 commit comments