1 #![allow(renamed_and_removed_lints)] // clippy::cyclomatic_complexity → clippy::cognitive_complexity
2 #![allow(clippy::cyclomatic_complexity)]
3 #![allow(clippy::cognitive_complexity)]
4 #![allow(clippy::trivially_copy_pass_by_ref)]
5 #![allow(clippy::unknown_clippy_lints)]
6 
7 #[cfg(feature = "use_core")]
8 extern crate core;
9 
10 #[macro_use]
11 extern crate derivative;
12 
13 #[derive(PartialEq, Eq, Derivative)]
14 #[derivative(PartialOrd, Ord)]
15 #[repr(C, packed)]
16 struct Foo {
17     foo: u8,
18 }
19 
20 #[derive(Derivative)]
21 #[derivative(PartialEq, PartialOrd, Ord, Eq)]
22 #[repr(C, packed)]
23 struct WithPtr<T: ?Sized> {
24     #[derivative(PartialEq(bound = ""))]
25     #[derivative(PartialOrd(bound = ""))]
26     #[derivative(Ord(bound = ""))]
27     #[derivative(Eq(bound = ""))]
28     foo: *const T,
29 }
30 
31 #[derive(PartialEq, Eq, Derivative)]
32 #[derivative(PartialOrd, Ord)]
33 #[repr(C, packed)]
34 struct Empty;
35 
36 #[derive(PartialEq, Eq, Derivative)]
37 #[derivative(PartialOrd, Ord)]
38 #[repr(C, packed)]
39 struct AllIgnored {
40     #[derivative(PartialOrd = "ignore")]
41     #[derivative(Ord = "ignore")]
42     foo: u8,
43 }
44 
45 #[derive(PartialEq, Eq, Derivative)]
46 #[derivative(PartialOrd, Ord)]
47 #[repr(C, packed)]
48 struct OneIgnored {
49     #[derivative(PartialOrd = "ignore")]
50     #[derivative(Ord = "ignore")]
51     foo: u8,
52     bar: u8,
53 }
54 
55 #[derive(PartialEq, Eq, Derivative)]
56 #[derivative(PartialOrd, Ord)]
57 #[repr(C, packed)]
58 struct Tenth(
59     #[derivative(
60         PartialOrd(compare_with = "partial_cmp_tenth"),
61         Ord(compare_with = "cmp_tenth")
62     )]
63     u8,
64 );
65 
partial_cmp_tenth(lhs: &u8, rhs: &u8) -> std::option::Option<std::cmp::Ordering>66 fn partial_cmp_tenth(lhs: &u8, rhs: &u8) -> std::option::Option<std::cmp::Ordering> {
67     if *lhs == 0 {
68         None
69     } else {
70         Some((lhs / 10).cmp(&(rhs / 10)))
71     }
72 }
cmp_tenth(lhs: &u8, rhs: &u8) -> std::cmp::Ordering73 fn cmp_tenth(lhs: &u8, rhs: &u8) -> std::cmp::Ordering {
74     (lhs / 10).cmp(&(rhs / 10))
75 }
76 
77 #[derive(Derivative)]
78 #[derivative(PartialOrd, Ord, PartialEq, Eq)]
79 #[repr(C, packed)]
80 struct Generic<T>(
81     #[derivative(
82         PartialEq = "ignore",
83         PartialOrd(compare_with = "dummy_partial_cmp", bound = ""),
84         Ord(compare_with = "dummy_cmp", bound = "")
85     )]
86     T,
87 );
88 
dummy_partial_cmp<T>(_: &T, _: &T) -> std::option::Option<std::cmp::Ordering>89 fn dummy_partial_cmp<T>(_: &T, _: &T) -> std::option::Option<std::cmp::Ordering> {
90     Some(std::cmp::Ordering::Less)
91 }
dummy_cmp<T>(_: &T, _: &T) -> std::cmp::Ordering92 fn dummy_cmp<T>(_: &T, _: &T) -> std::cmp::Ordering {
93     std::cmp::Ordering::Less
94 }
95 
96 struct NonPartialOrd;
97 
98 #[derive(Derivative)]
99 #[derivative(PartialEq, PartialOrd, Ord, Eq)]
100 #[repr(C, packed)]
101 struct GenericIgnore<T> {
102     f: u32,
103     #[derivative(PartialEq = "ignore")]
104     #[derivative(PartialOrd = "ignore")]
105     #[derivative(Ord = "ignore")]
106     t: T,
107 }
108 
109 trait SomeTrait {}
110 
111 #[derive(Clone, Copy)]
112 struct SomeType {
113     #[allow(dead_code)]
114     foo: u8,
115 }
116 impl SomeTrait for SomeType {}
117 
118 #[test]
main()119 fn main() {
120     use std::cmp::Ordering;
121 
122     assert_eq!(
123         Foo { foo: 7 }.partial_cmp(&Foo { foo: 42 }),
124         Some(Ordering::Less)
125     );
126     assert_eq!(
127         Foo { foo: 42 }.partial_cmp(&Foo { foo: 42 }),
128         Some(Ordering::Equal)
129     );
130     assert_eq!(
131         Foo { foo: 42 }.partial_cmp(&Foo { foo: 7 }),
132         Some(Ordering::Greater)
133     );
134     assert_eq!(Foo { foo: 7 }.cmp(&Foo { foo: 42 }), Ordering::Less);
135     assert_eq!(Foo { foo: 42 }.cmp(&Foo { foo: 42 }), Ordering::Equal);
136     assert_eq!(Foo { foo: 42 }.cmp(&Foo { foo: 7 }), Ordering::Greater);
137 
138     let pointers: [*const dyn SomeTrait; 2] = [&SomeType { foo: 1 }, &SomeType { foo: 0 }];
139     let ptr1: *const dyn SomeTrait = pointers[0];
140     let ptr2: *const dyn SomeTrait = pointers[1];
141     let (ptr1, ptr2) = (std::cmp::min(ptr1, ptr2), std::cmp::max(ptr1, ptr2));
142     assert_eq!(
143         WithPtr { foo: ptr1 }.partial_cmp(&WithPtr { foo: ptr1 }),
144         Some(Ordering::Equal)
145     );
146     assert_eq!(
147         WithPtr { foo: ptr1 }.cmp(&WithPtr { foo: ptr1 }),
148         Ordering::Equal
149     );
150     assert_eq!(
151         WithPtr { foo: ptr1 }.partial_cmp(&WithPtr { foo: ptr2 }),
152         Some(Ordering::Less)
153     );
154     assert_eq!(
155         WithPtr { foo: ptr1 }.cmp(&WithPtr { foo: ptr2 }),
156         Ordering::Less
157     );
158 
159     assert_eq!(Empty.partial_cmp(&Empty), Some(Ordering::Equal));
160     assert_eq!(
161         AllIgnored { foo: 0 }.partial_cmp(&AllIgnored { foo: 42 }),
162         Some(Ordering::Equal)
163     );
164     assert_eq!(
165         OneIgnored { foo: 0, bar: 6 }.partial_cmp(&OneIgnored { foo: 42, bar: 7 }),
166         Some(Ordering::Less)
167     );
168     assert_eq!(
169         OneIgnored { foo: 0, bar: 6 }.partial_cmp(&OneIgnored { foo: 42, bar: 6 }),
170         Some(Ordering::Equal)
171     );
172     assert_eq!(
173         OneIgnored { foo: 0, bar: 7 }.partial_cmp(&OneIgnored { foo: 42, bar: 6 }),
174         Some(Ordering::Greater)
175     );
176     assert_eq!(Empty.cmp(&Empty), Ordering::Equal);
177     assert_eq!(
178         AllIgnored { foo: 0 }.cmp(&AllIgnored { foo: 42 }),
179         Ordering::Equal
180     );
181     assert_eq!(
182         OneIgnored { foo: 0, bar: 6 }.cmp(&OneIgnored { foo: 42, bar: 7 }),
183         Ordering::Less
184     );
185     assert_eq!(
186         OneIgnored { foo: 0, bar: 6 }.cmp(&OneIgnored { foo: 42, bar: 6 }),
187         Ordering::Equal
188     );
189     assert_eq!(
190         OneIgnored { foo: 0, bar: 7 }.cmp(&OneIgnored { foo: 42, bar: 6 }),
191         Ordering::Greater
192     );
193 
194     assert_eq!(
195         Option::None::<u8>.partial_cmp(&Option::Some(7)),
196         Some(Ordering::Less)
197     );
198     assert_eq!(
199         Option::Some(6).partial_cmp(&Option::Some(7)),
200         Some(Ordering::Less)
201     );
202     assert_eq!(
203         Option::Some(42).partial_cmp(&Option::Some(42)),
204         Some(Ordering::Equal)
205     );
206     assert_eq!(
207         Option::None::<u8>.partial_cmp(&Option::None::<u8>),
208         Some(Ordering::Equal)
209     );
210     assert_eq!(
211         Option::Some(7).partial_cmp(&Option::Some(6)),
212         Some(Ordering::Greater)
213     );
214     assert_eq!(
215         Option::Some(7).partial_cmp(&Option::None::<u8>),
216         Some(Ordering::Greater)
217     );
218     assert_eq!(Option::None::<u8>.cmp(&Option::Some(7)), Ordering::Less);
219     assert_eq!(Option::Some(6).cmp(&Option::Some(7)), Ordering::Less);
220     assert_eq!(Option::Some(42).cmp(&Option::Some(42)), Ordering::Equal);
221     assert_eq!(Option::None::<u8>.cmp(&Option::None::<u8>), Ordering::Equal);
222     assert_eq!(Option::Some(7).cmp(&Option::Some(6)), Ordering::Greater);
223     assert_eq!(Option::Some(7).cmp(&Option::None::<u8>), Ordering::Greater);
224 
225     assert_eq!(Tenth(0).partial_cmp(&Tenth(67)), None);
226     assert_eq!(Tenth(42).partial_cmp(&Tenth(67)), Some(Ordering::Less));
227     assert_eq!(Tenth(60).partial_cmp(&Tenth(67)), Some(Ordering::Equal));
228     assert_eq!(Tenth(100).partial_cmp(&Tenth(67)), Some(Ordering::Greater));
229     assert_eq!(Tenth(42).cmp(&Tenth(67)), Ordering::Less);
230     assert_eq!(Tenth(60).cmp(&Tenth(67)), Ordering::Equal);
231     assert_eq!(Tenth(100).cmp(&Tenth(67)), Ordering::Greater);
232 
233     assert_eq!(
234         Generic(SomeType { foo: 0 }).partial_cmp(&Generic(SomeType { foo: 0 })),
235         Some(Ordering::Less)
236     );
237     assert_eq!(
238         Generic(SomeType { foo: 0 }).cmp(&Generic(SomeType { foo: 0 })),
239         Ordering::Less
240     );
241 
242     assert_eq!(
243         GenericIgnore {
244             f: 123,
245             t: NonPartialOrd
246         }
247         .cmp(&GenericIgnore {
248             f: 123,
249             t: NonPartialOrd
250         }),
251         Ordering::Equal
252     );
253     assert_eq!(
254         GenericIgnore {
255             f: 123,
256             t: NonPartialOrd
257         }
258         .partial_cmp(&GenericIgnore {
259             f: 123,
260             t: NonPartialOrd
261         }),
262         Some(Ordering::Equal)
263     );
264 }
265