]> git.lizzy.rs Git - rust.git/blob - src/test/ui/mir/mir_raw_fat_ptr.rs
Merge commit '61eb38aeda6cb54b93b872bf503d70084c4d621c' into clippyup
[rust.git] / src / test / ui / mir / mir_raw_fat_ptr.rs
1 // run-pass
2 // check raw fat pointer ops in mir
3 // FIXME: please improve this when we get monomorphization support
4 #![feature(raw_ref_op)]
5
6 use std::mem;
7
8 #[derive(Debug, PartialEq, Eq)]
9 struct ComparisonResults {
10     lt: bool,
11     le: bool,
12     gt: bool,
13     ge: bool,
14     eq: bool,
15     ne: bool
16 }
17
18 const LT: ComparisonResults = ComparisonResults {
19     lt: true,
20     le: true,
21     gt: false,
22     ge: false,
23     eq: false,
24     ne: true
25 };
26
27 const EQ: ComparisonResults = ComparisonResults {
28     lt: false,
29     le: true,
30     gt: false,
31     ge: true,
32     eq: true,
33     ne: false
34 };
35
36 const GT: ComparisonResults = ComparisonResults {
37     lt: false,
38     le: false,
39     gt: true,
40     ge: true,
41     eq: false,
42     ne: true
43 };
44
45 fn compare_su8(a: *const S<[u8]>, b: *const S<[u8]>) -> ComparisonResults {
46     ComparisonResults {
47         lt: a < b,
48         le: a <= b,
49         gt: a > b,
50         ge: a >= b,
51         eq: a == b,
52         ne: a != b
53     }
54 }
55
56 fn compare_au8(a: *const [u8], b: *const [u8]) -> ComparisonResults {
57     ComparisonResults {
58         lt: a < b,
59         le: a <= b,
60         gt: a > b,
61         ge: a >= b,
62         eq: a == b,
63         ne: a != b
64     }
65 }
66
67 fn compare_foo<'a>(a: *const (dyn Foo+'a), b: *const (dyn Foo+'a)) -> ComparisonResults {
68     ComparisonResults {
69         lt: a < b,
70         le: a <= b,
71         gt: a > b,
72         ge: a >= b,
73         eq: a == b,
74         ne: a != b
75     }
76 }
77
78 fn simple_eq<'a>(a: *const (dyn Foo+'a), b: *const (dyn Foo+'a)) -> bool {
79     let result = a == b;
80     result
81 }
82
83 fn assert_inorder<T: Copy>(a: &[T],
84                            compare: fn(T, T) -> ComparisonResults) {
85     for i in 0..a.len() {
86         for j in 0..a.len() {
87             let cres = compare(a[i], a[j]);
88             if i < j {
89                 assert_eq!(cres, LT);
90             } else if i == j {
91                 assert_eq!(cres, EQ);
92             } else {
93                 assert_eq!(cres, GT);
94             }
95         }
96     }
97 }
98
99 trait Foo { fn foo(&self) -> usize; }
100 impl<T> Foo for T {
101     fn foo(&self) -> usize {
102         mem::size_of::<T>()
103     }
104 }
105
106 struct S<T:?Sized>(u32, T);
107
108 fn main_ref() {
109     let array = [0,1,2,3,4];
110     let array2 = [5,6,7,8,9];
111
112     // fat ptr comparison: addr then extra
113
114     // check ordering for arrays
115     let mut ptrs: Vec<*const [u8]> = vec![
116         &array[0..0], &array[0..1], &array, &array[1..]
117     ];
118
119     let array_addr = &array as *const [u8] as *const u8 as usize;
120     let array2_addr = &array2 as *const [u8] as *const u8 as usize;
121     if array2_addr < array_addr {
122         ptrs.insert(0, &array2);
123     } else {
124         ptrs.push(&array2);
125     }
126     assert_inorder(&ptrs, compare_au8);
127
128     let u8_ = (0u8, 1u8);
129     let u32_ = (4u32, 5u32);
130
131     // check ordering for ptrs
132     let buf: &mut [*const dyn Foo] = &mut [
133         &u8_, &u8_.0,
134         &u32_, &u32_.0,
135     ];
136     buf.sort_by(|u,v| {
137         let u : [*const (); 2] = unsafe { mem::transmute(*u) };
138         let v : [*const (); 2] = unsafe { mem::transmute(*v) };
139         u.cmp(&v)
140     });
141     assert_inorder(buf, compare_foo);
142
143     // check ordering for structs containing arrays
144     let ss: (S<[u8; 2]>,
145              S<[u8; 3]>,
146              S<[u8; 2]>) = (
147         S(7, [8, 9]),
148         S(10, [11, 12, 13]),
149         S(4, [5, 6])
150     );
151     assert_inorder(&[
152         &ss.0 as *const S<[u8]>,
153         &ss.1 as *const S<[u8]>,
154         &ss.2 as *const S<[u8]>
155             ], compare_su8);
156
157     assert!(simple_eq(&0u8 as *const _, &0u8 as *const _));
158     assert!(!simple_eq(&0u8 as *const _, &1u8 as *const _));
159 }
160
161 // similar to above, but using &raw
162 fn main_raw() {
163     let array = [0,1,2,3,4];
164     let array2 = [5,6,7,8,9];
165
166     // fat ptr comparison: addr then extra
167
168     // check ordering for arrays
169     let mut ptrs: Vec<*const [u8]> = vec![
170         &raw const array[0..0], &raw const array[0..1], &raw const array, &raw const array[1..]
171     ];
172
173     let array_addr = &raw const array as *const u8 as usize;
174     let array2_addr = &raw const array2 as *const u8 as usize;
175     if array2_addr < array_addr {
176         ptrs.insert(0, &raw const array2);
177     } else {
178         ptrs.push(&raw const array2);
179     }
180     assert_inorder(&ptrs, compare_au8);
181
182     let u8_ = (0u8, 1u8);
183     let u32_ = (4u32, 5u32);
184
185     // check ordering for ptrs
186     let buf: &mut [*const dyn Foo] = &mut [
187         &raw const u8_, &raw const u8_.0,
188         &raw const u32_, &raw const u32_.0,
189     ];
190     buf.sort_by(|u,v| {
191         let u : [*const (); 2] = unsafe { mem::transmute(*u) };
192         let v : [*const (); 2] = unsafe { mem::transmute(*v) };
193         u.cmp(&v)
194     });
195     assert_inorder(buf, compare_foo);
196
197     // check ordering for structs containing arrays
198     let ss: (S<[u8; 2]>,
199              S<[u8; 3]>,
200              S<[u8; 2]>) = (
201         S(7, [8, 9]),
202         S(10, [11, 12, 13]),
203         S(4, [5, 6])
204     );
205     assert_inorder(&[
206         &raw const ss.0 as *const S<[u8]>,
207         &raw const ss.1 as *const S<[u8]>,
208         &raw const ss.2 as *const S<[u8]>
209             ], compare_su8);
210 }
211
212 fn main() {
213     main_ref();
214     main_raw();
215 }