3
3
use super :: { from_raw_parts, memchr} ;
4
4
use crate :: ascii;
5
5
use crate :: cmp:: { self , BytewiseEq , Ordering } ;
6
+ use crate :: convert:: Infallible ;
6
7
use crate :: intrinsics:: compare_bytes;
8
+ use crate :: marker:: Destruct ;
7
9
use crate :: num:: NonZero ;
8
10
use crate :: ops:: ControlFlow ;
9
11
@@ -28,7 +30,8 @@ impl<T: [const] Eq> const Eq for [T] {}
28
30
29
31
/// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
30
32
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
31
- impl <T : Ord > Ord for [ T ] {
33
+ #[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
34
+ impl <T : [ const ] Ord > const Ord for [ T ] {
32
35
fn cmp ( & self , other : & [ T ] ) -> Ordering {
33
36
SliceOrd :: compare ( self , other)
34
37
}
@@ -47,7 +50,8 @@ const fn as_underlying(x: ControlFlow<bool>) -> u8 {
47
50
48
51
/// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
49
52
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
50
- impl < T : PartialOrd > PartialOrd for [ T ] {
53
+ #[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
54
+ impl <T : [ const ] PartialOrd > const PartialOrd for [ T ] {
51
55
#[ inline ]
52
56
fn partial_cmp ( & self , other : & [ T ] ) -> Option < Ordering > {
53
57
SlicePartialOrd :: partial_compare ( self , other )
@@ -155,39 +159,50 @@ where
155
159
}
156
160
157
161
#[ doc( hidden) ]
158
- #[ const_trait]
159
162
#[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
160
163
// intermediate trait for specialization of slice's PartialOrd
161
- trait SlicePartialOrd : Sized {
164
+ const trait SlicePartialOrd : Sized {
162
165
fn partial_compare ( left : & [ Self ] , right : & [ Self ] ) -> Option < Ordering > ;
163
166
}
164
167
165
168
#[ doc ( hidden ) ]
166
- #[ const_trait]
167
169
#[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
168
170
// intermediate trait for specialization of slice's PartialOrd chaining methods
169
- trait SliceChain : Sized {
171
+ const trait SliceChain : Sized {
170
172
fn chaining_lt ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
171
173
fn chaining_le ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
172
174
fn chaining_gt ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
173
175
fn chaining_ge ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
174
176
}
175
177
176
- type AlwaysBreak < B > = ControlFlow < B , crate :: convert :: Infallible > ;
178
+ type AlwaysBreak < B > = ControlFlow < B , Infallible > ;
177
179
178
- impl < A : PartialOrd > SlicePartialOrd for A {
180
+ #[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
181
+ impl <A : [ const ] PartialOrd > const SlicePartialOrd for A {
179
182
default fn partial_compare ( left : & [ A ] , right : & [ A ] ) -> Option < Ordering > {
180
- let elem_chain = |a, b| match PartialOrd :: partial_cmp ( a, b) {
181
- Some ( Ordering :: Equal ) => ControlFlow :: Continue ( ( ) ) ,
182
- non_eq => ControlFlow :: Break ( non_eq) ,
183
- } ;
184
- let len_chain = |a : & _ , b : & _ | ControlFlow :: Break ( usize:: partial_cmp ( a, b) ) ;
183
+ #[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
184
+ const fn elem_chain < B > ( a : & B , b : & B ) -> ControlFlow < Option < Ordering > >
185
+ where
186
+ B : [ const ] PartialOrd ,
187
+ {
188
+ match a. partial_cmp ( b ) {
189
+ Some ( Ordering :: Equal ) => ControlFlow :: Continue ( ( ) ) ,
190
+ non_eq => ControlFlow :: Break ( non_eq ) ,
191
+ }
192
+ }
193
+
194
+ #[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
195
+ const fn len_chain ( a : & usize , b : & usize ) -> ControlFlow < Option < Ordering > , Infallible > {
196
+ ControlFlow :: Break ( usize:: partial_cmp ( a , b ) )
197
+ }
198
+
185
199
let AlwaysBreak :: Break ( b ) = chaining_impl ( left , right , elem_chain , len_chain ) ;
186
200
b
187
201
}
188
202
}
189
203
190
- impl < A : PartialOrd > SliceChain for A {
204
+ #[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
205
+ impl<A : [ const ] PartialOrd > const SliceChain for A {
191
206
default fn chaining_lt( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > {
192
207
chaining_impl( left, right, PartialOrd :: __chaining_lt, usize:: __chaining_lt)
193
208
}
@@ -203,21 +218,28 @@ impl<A: PartialOrd> SliceChain for A {
203
218
}
204
219
205
220
#[ inline]
206
- fn chaining_impl < ' l , ' r , A : PartialOrd , B , C > (
221
+ #[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
222
+ const fn chaining_impl < ' l , ' r , A : PartialOrd , B , C , E , L > (
207
223
left: & ' l [ A ] ,
208
224
right: & ' r [ A ] ,
209
- elem_chain : impl Fn ( & ' l A , & ' r A ) -> ControlFlow < B > ,
210
- len_chain : impl for < ' a > FnOnce ( & ' a usize , & ' a usize ) -> ControlFlow < B , C > ,
211
- ) -> ControlFlow < B , C > {
225
+ elem_chain: E ,
226
+ len_chain: L ,
227
+ ) -> ControlFlow < B , C >
228
+ where
229
+ E : [ const ] Destruct + [ const ] Fn ( & ' l A , & ' r A ) -> ControlFlow < B > ,
230
+ L : [ const ] Destruct + for < ' a > [ const ] FnOnce ( & ' a usize, & ' a usize) -> ControlFlow < B , C > ,
231
+ {
212
232
let l = cmp:: min( left. len( ) , right. len( ) ) ;
213
233
214
234
// Slice to the loop iteration range to enable bound check
215
235
// elimination in the compiler
216
236
let lhs = & left[ ..l] ;
217
237
let rhs = & right[ ..l] ;
218
238
219
- for i in 0 ..l {
239
+ let mut i = 0 ;
240
+ while i < l {
220
241
elem_chain ( & lhs[ i] , & rhs[ i] ) ?;
242
+ i += 1 ;
221
243
}
222
244
223
245
len_chain ( & left. len ( ) , & right. len ( ) )
@@ -244,41 +266,56 @@ impl<A: [const] AlwaysApplicableOrd> const SlicePartialOrd for A {
244
266
}
245
267
246
268
#[ rustc_specialization_trait ]
247
- #[ const_trait ]
248
269
#[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
249
- trait AlwaysApplicableOrd : [ const ] SliceOrd + [ const ] Ord { }
270
+ const trait AlwaysApplicableOrd : [ const ] SliceOrd + [ const ] Ord { }
250
271
251
272
macro_rules! always_applicable_ord {
252
273
( $( [ $( $p: tt) * ] $t: ty, ) * ) => {
253
- $( impl <$( $p) * > AlwaysApplicableOrd for $t { } ) *
274
+ $(
275
+ #[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
276
+ impl <$( $p) * > const AlwaysApplicableOrd for $t { }
277
+ ) *
254
278
}
255
279
}
256
280
257
281
always_applicable_ord! {
258
282
[ ] u8 , [ ] u16 , [ ] u32 , [ ] u64 , [ ] u128 , [ ] usize ,
259
283
[ ] i8 , [ ] i16 , [ ] i32 , [ ] i64 , [ ] i128 , [ ] isize ,
260
284
[ ] bool , [ ] char ,
261
- [ T : ?Sized ] * const T , [ T : ?Sized ] * mut T ,
262
- [ T : AlwaysApplicableOrd ] & T ,
263
- [ T : AlwaysApplicableOrd ] & mut T ,
264
- [ T : AlwaysApplicableOrd ] Option < T > ,
285
+ [ T : [ const ] AlwaysApplicableOrd ] & T ,
286
+ [ T : [ const ] AlwaysApplicableOrd ] & mut T ,
287
+ [ T : [ const ] AlwaysApplicableOrd ] Option <T >,
265
288
}
266
289
290
+ impl <T : ?Sized > AlwaysApplicableOrd for * const T { }
291
+ impl <T : ?Sized > AlwaysApplicableOrd for * mut T { }
292
+
267
293
#[ doc( hidden) ]
268
- #[ const_trait ]
269
294
#[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
270
295
// intermediate trait for specialization of slice's Ord
271
- trait SliceOrd : Sized {
296
+ const trait SliceOrd : Sized {
272
297
fn compare( left: & [ Self ] , right: & [ Self ] ) -> Ordering ;
273
298
}
274
299
275
- impl <A : Ord > SliceOrd for A {
300
+ #[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
301
+ impl <A : [ const ] Ord > const SliceOrd for A {
276
302
default fn compare( left: & [ Self ] , right: & [ Self ] ) -> Ordering {
277
- let elem_chain = |a , b | match Ord :: cmp ( a , b ) {
278
- Ordering :: Equal => ControlFlow :: Continue ( ( ) ) ,
279
- non_eq => ControlFlow :: Break ( non_eq ) ,
280
- } ;
281
- let len_chain = |a : & _ , b : & _ | ControlFlow :: Break ( usize:: cmp ( a , b ) ) ;
303
+ #[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
304
+ const fn elem_chain<B >( a: & B , b: & B ) -> ControlFlow <Ordering >
305
+ where
306
+ B : [ const ] Ord ,
307
+ {
308
+ match a. cmp( b) {
309
+ Ordering :: Equal => ControlFlow :: Continue ( ( ) ) ,
310
+ non_eq => ControlFlow :: Break ( non_eq) ,
311
+ }
312
+ }
313
+
314
+ #[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
315
+ const fn len_chain( a: & usize , b: & usize ) -> ControlFlow <Ordering , Infallible > {
316
+ ControlFlow :: Break ( usize :: cmp( a, b) )
317
+ }
318
+
282
319
let AlwaysBreak :: Break ( b) = chaining_impl( left, right, elem_chain, len_chain) ;
283
320
b
284
321
}
@@ -334,7 +371,6 @@ impl<A: [const] Ord + [const] UnsignedBytewiseOrd> const SliceOrd for A {
334
371
}
335
372
336
373
// Don't generate our own chaining loops for `memcmp`-able things either.
337
-
338
374
#[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
339
375
impl <A : [ const ] PartialOrd + [ const ] UnsignedBytewiseOrd > const SliceChain for A {
340
376
#[ inline]
0 commit comments