]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/transmute_undefined_repr.rs
5aad0b44270a3cc5b9e72a5dd1405e9d52fee5e7
[rust.git] / src / tools / clippy / tests / ui / transmute_undefined_repr.rs
1 #![warn(clippy::transmute_undefined_repr)]
2 #![allow(clippy::unit_arg, clippy::transmute_ptr_to_ref, clippy::useless_transmute)]
3
4 use core::any::TypeId;
5 use core::ffi::c_void;
6 use core::mem::{size_of, transmute, MaybeUninit};
7 use core::ptr::NonNull;
8
9 fn value<T>() -> T {
10     unimplemented!()
11 }
12
13 struct Empty;
14 struct Ty<T>(T);
15 struct Ty2<T, U>(T, U);
16
17 #[repr(C)]
18 struct Ty2C<T, U>(T, U);
19
20 fn main() {
21     unsafe {
22         let _: () = transmute(value::<Empty>());
23         let _: Empty = transmute(value::<()>());
24
25         let _: Ty<u32> = transmute(value::<u32>());
26         let _: Ty<u32> = transmute(value::<u32>());
27
28         let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
29         let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
30
31         let _: Ty2<u32, i32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Ok, Ty2 types are the same
32         let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
33
34         let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
35         let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
36
37         let _: Ty<&()> = transmute(value::<&()>());
38         let _: &() = transmute(value::<Ty<&()>>());
39
40         let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
41         let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
42
43         let _: Ty<usize> = transmute(value::<&Ty2<u32, i32>>()); // Ok, pointer to usize conversion
44         let _: &Ty2<u32, i32> = transmute(value::<Ty<usize>>()); // Ok, pointer to usize conversion
45
46         let _: Ty<[u8; 8]> = transmute(value::<Ty2<u32, i32>>()); // Ok, transmute to byte array
47         let _: Ty2<u32, i32> = transmute(value::<Ty<[u8; 8]>>()); // Ok, transmute from byte array
48
49         // issue #8417
50         let _: Ty2C<Ty2<u32, i32>, ()> = transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
51         let _: Ty2<u32, i32> = transmute(value::<Ty2C<Ty2<u32, i32>, ()>>()); // Ok, Ty2 types are the same
52
53         let _: &'static mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Ok, Ty2 types are the same
54         let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, u32>>()); // Ok, Ty2 types are the same
55         let _: *mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Ok, Ty2 types are the same
56         let _: Box<Ty2<u32, u32>> = transmute(value::<*mut Ty2<u32, u32>>()); // Ok, Ty2 types are the same
57
58         let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances
59         let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances
60
61         let _: *const () = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
62         let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const ()>()); // Ok, reverse type erasure
63
64         let _: *const c_void = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
65         let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const c_void>()); // Ok, reverse type erasure
66
67         enum Erase {}
68         let _: *const Erase = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
69         let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase>()); // Ok, reverse type erasure
70
71         struct Erase2(
72             [u8; 0],
73             core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
74         );
75         let _: *const Erase2 = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
76         let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase2>()); // Ok, reverse type erasure
77
78         let _: *const () = transmute(value::<&&[u8]>()); // Ok, type erasure
79         let _: &&[u8] = transmute(value::<*const ()>()); // Ok, reverse type erasure
80
81         let _: *mut c_void = transmute(value::<&mut &[u8]>()); // Ok, type erasure
82         let _: &mut &[u8] = transmute(value::<*mut c_void>()); // Ok, reverse type erasure
83
84         let _: [u8; size_of::<&[u8]>()] = transmute(value::<&[u8]>()); // Ok, transmute to byte array
85         let _: &[u8] = transmute(value::<[u8; size_of::<&[u8]>()]>()); // Ok, transmute from byte array
86
87         let _: [usize; 2] = transmute(value::<&[u8]>()); // Ok, transmute to int array
88         let _: &[u8] = transmute(value::<[usize; 2]>()); // Ok, transmute from int array
89
90         let _: *const [u8] = transmute(value::<Box<[u8]>>()); // Ok
91         let _: Box<[u8]> = transmute(value::<*mut [u8]>()); // Ok
92
93         let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>,)>()); // Ok
94         let _: (Ty2<u32, u32>,) = transmute(value::<Ty2<u32, u32>>()); // Ok
95
96         let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>, ())>()); // Ok
97         let _: (Ty2<u32, u32>, ()) = transmute(value::<Ty2<u32, u32>>()); // Ok
98
99         let _: Ty2<u32, u32> = transmute(value::<((), Ty2<u32, u32>)>()); // Ok
100         let _: ((), Ty2<u32, u32>) = transmute(value::<Ty2<u32, u32>>()); // Ok
101
102         let _: (usize, usize) = transmute(value::<&[u8]>()); // Ok
103         let _: &[u8] = transmute(value::<(usize, usize)>()); // Ok
104
105         trait Trait {}
106         let _: (isize, isize) = transmute(value::<&dyn Trait>()); // Ok
107         let _: &dyn Trait = transmute(value::<(isize, isize)>()); // Ok
108
109         let _: MaybeUninit<Ty2<u32, u32>> = transmute(value::<Ty2<u32, u32>>()); // Ok
110         let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>()); // Ok
111
112         let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>()); // Ok
113
114         let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>()); // Ok
115         let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
116         let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>()); // Ok
117         let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
118
119         let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
120         let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
121
122         let _: NonNull<u8> = transmute(value::<NonNull<(String, String)>>()); // Ok
123         let _: NonNull<(String, String)> = transmute(value::<NonNull<u8>>()); // Ok
124     }
125 }
126
127 fn _with_generics<T: 'static, U: 'static>() {
128     if TypeId::of::<T>() != TypeId::of::<u32>() || TypeId::of::<T>() != TypeId::of::<U>() {
129         return;
130     }
131     unsafe {
132         let _: &u32 = transmute(value::<&T>()); // Ok
133         let _: &T = transmute(value::<&u32>()); // Ok
134
135         let _: Vec<U> = transmute(value::<Vec<T>>()); // Ok
136         let _: Vec<T> = transmute(value::<Vec<U>>()); // Ok
137
138         let _: Ty<&u32> = transmute(value::<&T>()); // Ok
139         let _: Ty<&T> = transmute(value::<&u32>()); // Ok
140
141         let _: Vec<u32> = transmute(value::<Vec<T>>()); // Ok
142         let _: Vec<T> = transmute(value::<Vec<u32>>()); // Ok
143
144         let _: &Ty2<u32, u32> = transmute(value::<&Ty2<T, U>>()); // Ok
145         let _: &Ty2<T, U> = transmute(value::<&Ty2<u32, u32>>()); // Ok
146
147         let _: Vec<Vec<u32>> = transmute(value::<Vec<Vec<T>>>()); // Ok
148         let _: Vec<Vec<T>> = transmute(value::<Vec<Vec<u32>>>()); // Ok
149
150         let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); // Err
151         let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>()); // Err
152
153         let _: *const u32 = transmute(value::<Box<T>>()); // Ok
154         let _: Box<T> = transmute(value::<*const u32>()); // Ok
155     }
156 }