]>
Commit | Line | Data |
---|---|---|
92a42be0 SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | #![feature(rustc_attrs)] | |
12 | ||
54a0048b SL |
13 | // ignore-pretty : (#23623) problems when ending with // comments |
14 | ||
92a42be0 SL |
15 | // check raw fat pointer ops in mir |
16 | // FIXME: please improve this when we get monomorphization support | |
17 | ||
18 | use std::mem; | |
19 | ||
20 | #[derive(Debug, PartialEq, Eq)] | |
21 | struct ComparisonResults { | |
22 | lt: bool, | |
23 | le: bool, | |
24 | gt: bool, | |
25 | ge: bool, | |
26 | eq: bool, | |
27 | ne: bool | |
28 | } | |
29 | ||
30 | const LT: ComparisonResults = ComparisonResults { | |
31 | lt: true, | |
32 | le: true, | |
33 | gt: false, | |
34 | ge: false, | |
35 | eq: false, | |
36 | ne: true | |
37 | }; | |
38 | ||
39 | const EQ: ComparisonResults = ComparisonResults { | |
40 | lt: false, | |
41 | le: true, | |
42 | gt: false, | |
43 | ge: true, | |
44 | eq: true, | |
45 | ne: false | |
46 | }; | |
47 | ||
48 | const GT: ComparisonResults = ComparisonResults { | |
49 | lt: false, | |
50 | le: false, | |
51 | gt: true, | |
52 | ge: true, | |
53 | eq: false, | |
54 | ne: true | |
55 | }; | |
56 | ||
57 | #[rustc_mir] | |
58 | fn compare_su8(a: *const S<[u8]>, b: *const S<[u8]>) -> ComparisonResults { | |
59 | ComparisonResults { | |
60 | lt: a < b, | |
61 | le: a <= b, | |
62 | gt: a > b, | |
63 | ge: a >= b, | |
64 | eq: a == b, | |
65 | ne: a != b | |
66 | } | |
67 | } | |
68 | ||
69 | #[rustc_mir] | |
70 | fn compare_au8(a: *const [u8], b: *const [u8]) -> ComparisonResults { | |
71 | ComparisonResults { | |
72 | lt: a < b, | |
73 | le: a <= b, | |
74 | gt: a > b, | |
75 | ge: a >= b, | |
76 | eq: a == b, | |
77 | ne: a != b | |
78 | } | |
79 | } | |
80 | ||
81 | #[rustc_mir] | |
82 | fn compare_foo<'a>(a: *const (Foo+'a), b: *const (Foo+'a)) -> ComparisonResults { | |
83 | ComparisonResults { | |
84 | lt: a < b, | |
85 | le: a <= b, | |
86 | gt: a > b, | |
87 | ge: a >= b, | |
88 | eq: a == b, | |
89 | ne: a != b | |
90 | } | |
91 | } | |
92 | ||
93 | #[rustc_mir] | |
94 | fn simple_eq<'a>(a: *const (Foo+'a), b: *const (Foo+'a)) -> bool { | |
95 | let result = a == b; | |
96 | result | |
97 | } | |
98 | ||
99 | fn assert_inorder<T: Copy>(a: &[T], | |
100 | compare: fn(T, T) -> ComparisonResults) { | |
101 | for i in 0..a.len() { | |
102 | for j in 0..a.len() { | |
103 | let cres = compare(a[i], a[j]); | |
104 | if i < j { | |
105 | assert_eq!(cres, LT); | |
106 | } else if i == j { | |
107 | assert_eq!(cres, EQ); | |
108 | } else { | |
109 | assert_eq!(cres, GT); | |
110 | } | |
111 | } | |
112 | } | |
113 | } | |
114 | ||
115 | trait Foo { fn foo(&self) -> usize; } | |
116 | impl<T> Foo for T { | |
117 | fn foo(&self) -> usize { | |
118 | mem::size_of::<T>() | |
119 | } | |
120 | } | |
121 | ||
122 | struct S<T:?Sized>(u32, T); | |
123 | ||
54a0048b | 124 | #[rustc_no_mir] // FIXME #27840 MIR can't do rvalue promotion yet. |
92a42be0 SL |
125 | fn main() { |
126 | let array = [0,1,2,3,4]; | |
127 | let array2 = [5,6,7,8,9]; | |
128 | ||
129 | // fat ptr comparison: addr then extra | |
130 | ||
131 | // check ordering for arrays | |
132 | let mut ptrs: Vec<*const [u8]> = vec![ | |
133 | &array[0..0], &array[0..1], &array, &array[1..] | |
134 | ]; | |
135 | ||
136 | let array_addr = &array as *const [u8] as *const u8 as usize; | |
137 | let array2_addr = &array2 as *const [u8] as *const u8 as usize; | |
138 | if array2_addr < array_addr { | |
139 | ptrs.insert(0, &array2); | |
140 | } else { | |
141 | ptrs.push(&array2); | |
142 | } | |
143 | assert_inorder(&ptrs, compare_au8); | |
144 | ||
145 | let u8_ = (0u8, 1u8); | |
146 | let u32_ = (4u32, 5u32); | |
147 | ||
148 | // check ordering for ptrs | |
149 | let buf: &mut [*const Foo] = &mut [ | |
150 | &u8_, &u8_.0, | |
151 | &u32_, &u32_.0, | |
152 | ]; | |
153 | buf.sort_by(|u,v| { | |
154 | let u : [*const (); 2] = unsafe { mem::transmute(*u) }; | |
155 | let v : [*const (); 2] = unsafe { mem::transmute(*v) }; | |
156 | u.cmp(&v) | |
157 | }); | |
158 | assert_inorder(buf, compare_foo); | |
159 | ||
160 | // check ordering for structs containing arrays | |
161 | let ss: (S<[u8; 2]>, | |
162 | S<[u8; 3]>, | |
163 | S<[u8; 2]>) = ( | |
164 | S(7, [8, 9]), | |
165 | S(10, [11, 12, 13]), | |
166 | S(4, [5, 6]) | |
167 | ); | |
168 | assert_inorder(&[ | |
169 | &ss.0 as *const S<[u8]>, | |
170 | &ss.1 as *const S<[u8]>, | |
171 | &ss.2 as *const S<[u8]> | |
172 | ], compare_su8); | |
173 | ||
174 | assert!(simple_eq(&0u8 as *const _, &0u8 as *const _)); | |
175 | assert!(!simple_eq(&0u8 as *const _, &1u8 as *const _)); | |
176 | } |