33use super :: { from_raw_parts, memchr} ;
44use crate :: ascii;
55use crate :: cmp:: { self , BytewiseEq , Ordering } ;
6+ use crate :: convert:: Infallible ;
67use crate :: intrinsics:: compare_bytes;
8+ use crate :: marker:: Destruct ;
79use crate :: num:: NonZero ;
810use crate :: ops:: ControlFlow ;
911
@@ -28,7 +30,8 @@ impl<T: [const] Eq> const Eq for [T] {}
2830
2931/// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
3032#[ 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 ] {
3235 fn cmp ( & self , other : & [ T ] ) -> Ordering {
3336 SliceOrd :: compare ( self , other)
3437 }
@@ -47,7 +50,8 @@ const fn as_underlying(x: ControlFlow<bool>) -> u8 {
4750
4851/// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
4952#[ 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 ] {
5155 #[ inline ]
5256 fn partial_cmp ( & self , other : & [ T ] ) -> Option < Ordering > {
5357 SlicePartialOrd :: partial_compare ( self , other )
@@ -155,39 +159,50 @@ where
155159}
156160
157161#[ doc( hidden) ]
158- #[ const_trait]
159162#[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
160163// intermediate trait for specialization of slice's PartialOrd
161- trait SlicePartialOrd : Sized {
164+ const trait SlicePartialOrd : Sized {
162165 fn partial_compare ( left : & [ Self ] , right : & [ Self ] ) -> Option < Ordering > ;
163166}
164167
165168#[ doc ( hidden ) ]
166- #[ const_trait]
167169#[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
168170// intermediate trait for specialization of slice's PartialOrd chaining methods
169- trait SliceChain : Sized {
171+ const trait SliceChain : Sized {
170172 fn chaining_lt ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
171173 fn chaining_le ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
172174 fn chaining_gt ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
173175 fn chaining_ge ( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > ;
174176}
175177
176- type AlwaysBreak < B > = ControlFlow < B , crate :: convert :: Infallible > ;
178+ type AlwaysBreak < B > = ControlFlow < B , Infallible > ;
177179
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 {
179182 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+
185199 let AlwaysBreak :: Break ( b ) = chaining_impl ( left , right , elem_chain , len_chain ) ;
186200 b
187201 }
188202}
189203
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 {
191206 default fn chaining_lt( left : & [ Self ] , right : & [ Self ] ) -> ControlFlow < bool > {
192207 chaining_impl( left, right, PartialOrd :: __chaining_lt, usize:: __chaining_lt)
193208 }
@@ -203,21 +218,28 @@ impl<A: PartialOrd> SliceChain for A {
203218}
204219
205220#[ 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 > (
207223 left: & ' l [ A ] ,
208224 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+ {
212232 let l = cmp:: min( left. len( ) , right. len( ) ) ;
213233
214234 // Slice to the loop iteration range to enable bound check
215235 // elimination in the compiler
216236 let lhs = & left[ ..l] ;
217237 let rhs = & right[ ..l] ;
218238
219- for i in 0 ..l {
239+ let mut i = 0 ;
240+ while i < l {
220241 elem_chain ( & lhs[ i] , & rhs[ i] ) ?;
242+ i += 1 ;
221243 }
222244
223245 len_chain ( & left. len ( ) , & right. len ( ) )
@@ -244,41 +266,56 @@ impl<A: [const] AlwaysApplicableOrd> const SlicePartialOrd for A {
244266}
245267
246268#[ rustc_specialization_trait ]
247- #[ const_trait ]
248269#[ rustc_const_unstable ( feature = "const_cmp" , issue = "143800" ) ]
249- trait AlwaysApplicableOrd : [ const ] SliceOrd + [ const ] Ord { }
270+ const trait AlwaysApplicableOrd : [ const ] SliceOrd + [ const ] Ord { }
250271
251272macro_rules! always_applicable_ord {
252273 ( $( [ $( $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+ ) *
254278 }
255279}
256280
257281always_applicable_ord! {
258282 [ ] u8 , [ ] u16 , [ ] u32 , [ ] u64 , [ ] u128 , [ ] usize ,
259283 [ ] i8 , [ ] i16 , [ ] i32 , [ ] i64 , [ ] i128 , [ ] isize ,
260284 [ ] 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 >,
265288}
266289
290+ impl <T : ?Sized > AlwaysApplicableOrd for * const T { }
291+ impl <T : ?Sized > AlwaysApplicableOrd for * mut T { }
292+
267293#[ doc( hidden) ]
268- #[ const_trait ]
269294#[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
270295// intermediate trait for specialization of slice's Ord
271- trait SliceOrd : Sized {
296+ const trait SliceOrd : Sized {
272297 fn compare( left: & [ Self ] , right: & [ Self ] ) -> Ordering ;
273298}
274299
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 {
276302 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+
282319 let AlwaysBreak :: Break ( b) = chaining_impl( left, right, elem_chain, len_chain) ;
283320 b
284321 }
@@ -334,7 +371,6 @@ impl<A: [const] Ord + [const] UnsignedBytewiseOrd> const SliceOrd for A {
334371}
335372
336373// Don't generate our own chaining loops for `memcmp`-able things either.
337-
338374#[ rustc_const_unstable( feature = "const_cmp" , issue = "143800" ) ]
339375impl <A : [ const ] PartialOrd + [ const ] UnsignedBytewiseOrd > const SliceChain for A {
340376 #[ inline]
0 commit comments