@@ -31,9 +31,7 @@ pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive};
31
31
#[ doc( inline) ]
32
32
pub use crate :: iter:: Step ;
33
33
#[ doc( inline) ]
34
- pub use crate :: ops:: {
35
- Bound , IntoBounds , OneSidedRange , RangeBounds , RangeFull , RangeTo , RangeToInclusive ,
36
- } ;
34
+ pub use crate :: ops:: { Bound , IntoBounds , OneSidedRange , RangeBounds , RangeFull , RangeTo } ;
37
35
38
36
/// A (half-open) range bounded inclusively below and exclusively above
39
37
/// (`start..end` in a future edition).
@@ -209,20 +207,20 @@ impl<T> const From<legacy::Range<T>> for Range<T> {
209
207
}
210
208
}
211
209
212
- /// A range bounded inclusively below and above (`start..=end `).
210
+ /// A range bounded inclusively below and above (`start..=last `).
213
211
///
214
- /// The `RangeInclusive` `start..=end ` contains all values with `x >= start`
215
- /// and `x <= end `. It is empty unless `start <= end `.
212
+ /// The `RangeInclusive` `start..=last ` contains all values with `x >= start`
213
+ /// and `x <= last `. It is empty unless `start <= last `.
216
214
///
217
215
/// # Examples
218
216
///
219
- /// The `start..=end ` syntax is a `RangeInclusive`:
217
+ /// The `start..=last ` syntax is a `RangeInclusive`:
220
218
///
221
219
/// ```
222
220
/// #![feature(new_range_api)]
223
221
/// use core::range::RangeInclusive;
224
222
///
225
- /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end : 5 });
223
+ /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last : 5 });
226
224
/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
227
225
/// ```
228
226
#[ lang = "RangeInclusiveCopy" ]
@@ -234,15 +232,15 @@ pub struct RangeInclusive<Idx> {
234
232
pub start : Idx ,
235
233
/// The upper bound of the range (inclusive).
236
234
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
237
- pub end : Idx ,
235
+ pub last : Idx ,
238
236
}
239
237
240
238
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
241
239
impl < Idx : fmt:: Debug > fmt:: Debug for RangeInclusive < Idx > {
242
240
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
243
241
self . start . fmt ( fmt) ?;
244
242
write ! ( fmt, "..=" ) ?;
245
- self . end . fmt ( fmt) ?;
243
+ self . last . fmt ( fmt) ?;
246
244
Ok ( ( ) )
247
245
}
248
246
}
@@ -306,7 +304,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
306
304
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
307
305
#[ inline]
308
306
pub fn is_empty ( & self ) -> bool {
309
- !( self . start <= self . end )
307
+ !( self . start <= self . last )
310
308
}
311
309
}
312
310
@@ -335,10 +333,10 @@ impl<Idx: Step> RangeInclusive<Idx> {
335
333
336
334
impl RangeInclusive < usize > {
337
335
/// Converts to an exclusive `Range` for `SliceIndex` implementations.
338
- /// The caller is responsible for dealing with `end == usize::MAX`.
336
+ /// The caller is responsible for dealing with `last == usize::MAX`.
339
337
#[ inline]
340
338
pub ( crate ) const fn into_slice_range ( self ) -> Range < usize > {
341
- Range { start : self . start , end : self . end + 1 }
339
+ Range { start : self . start , end : self . last + 1 }
342
340
}
343
341
}
344
342
@@ -348,7 +346,7 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
348
346
Included ( & self . start )
349
347
}
350
348
fn end_bound ( & self ) -> Bound < & T > {
351
- Included ( & self . end )
349
+ Included ( & self . last )
352
350
}
353
351
}
354
352
@@ -364,15 +362,15 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
364
362
Included ( self . start )
365
363
}
366
364
fn end_bound ( & self ) -> Bound < & T > {
367
- Included ( self . end )
365
+ Included ( self . last )
368
366
}
369
367
}
370
368
371
369
// #[unstable(feature = "range_into_bounds", issue = "136903")]
372
370
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
373
371
impl < T > IntoBounds < T > for RangeInclusive < T > {
374
372
fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
375
- ( Included ( self . start ) , Included ( self . end ) )
373
+ ( Included ( self . start ) , Included ( self . last ) )
376
374
}
377
375
}
378
376
@@ -381,7 +379,7 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
381
379
impl < T > const From < RangeInclusive < T > > for legacy:: RangeInclusive < T > {
382
380
#[ inline]
383
381
fn from ( value : RangeInclusive < T > ) -> Self {
384
- Self :: new ( value. start , value. end )
382
+ Self :: new ( value. start , value. last )
385
383
}
386
384
}
387
385
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
@@ -393,8 +391,8 @@ impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
393
391
"attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
394
392
) ;
395
393
396
- let ( start, end ) = value. into_inner ( ) ;
397
- RangeInclusive { start, end }
394
+ let ( start, last ) = value. into_inner ( ) ;
395
+ RangeInclusive { start, last }
398
396
}
399
397
}
400
398
@@ -543,3 +541,105 @@ impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
543
541
Self { start : value. start }
544
542
}
545
543
}
544
+
545
+ /// A range only bounded inclusively above (`..=last`).
546
+ ///
547
+ /// The `RangeToInclusive` `..=last` contains all values with `x <= last`.
548
+ /// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
549
+ ///
550
+ /// # Examples
551
+ ///
552
+ /// The `..=last` syntax is a `RangeToInclusive`:
553
+ ///
554
+ /// ```
555
+ /// assert_eq!((..=5), std::ops::RangeToInclusive{ last: 5 });
556
+ /// ```
557
+ ///
558
+ /// It does not have an [`IntoIterator`] implementation, so you can't use it in a
559
+ /// `for` loop directly. This won't compile:
560
+ ///
561
+ /// ```compile_fail,E0277
562
+ /// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>:
563
+ /// // std::iter::Iterator` is not satisfied
564
+ /// for i in ..=5 {
565
+ /// // ...
566
+ /// }
567
+ /// ```
568
+ ///
569
+ /// When used as a [slicing index], `RangeToInclusive` produces a slice of all
570
+ /// array elements up to and including the index indicated by `last`.
571
+ ///
572
+ /// ```
573
+ /// let arr = [0, 1, 2, 3, 4];
574
+ /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]);
575
+ /// assert_eq!(arr[ .. 3], [0, 1, 2 ]);
576
+ /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive`
577
+ /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]);
578
+ /// assert_eq!(arr[1.. 3], [ 1, 2 ]);
579
+ /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
580
+ /// ```
581
+ ///
582
+ /// [slicing index]: crate::slice::SliceIndex
583
+ #[ lang = "RangeToInclusiveCopy" ]
584
+ #[ doc( alias = "..=" ) ]
585
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
586
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
587
+ pub struct RangeToInclusive < Idx > {
588
+ /// The upper bound of the range (inclusive)
589
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
590
+ pub last : Idx ,
591
+ }
592
+
593
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
594
+ impl < Idx : fmt:: Debug > fmt:: Debug for RangeToInclusive < Idx > {
595
+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
596
+ write ! ( fmt, "..=" ) ?;
597
+ self . last . fmt ( fmt) ?;
598
+ Ok ( ( ) )
599
+ }
600
+ }
601
+
602
+ impl < Idx : PartialOrd < Idx > > RangeToInclusive < Idx > {
603
+ /// Returns `true` if `item` is contained in the range.
604
+ ///
605
+ /// # Examples
606
+ ///
607
+ /// ```
608
+ /// assert!( (..=5).contains(&-1_000_000_000));
609
+ /// assert!( (..=5).contains(&5));
610
+ /// assert!(!(..=5).contains(&6));
611
+ ///
612
+ /// assert!( (..=1.0).contains(&1.0));
613
+ /// assert!(!(..=1.0).contains(&f32::NAN));
614
+ /// assert!(!(..=f32::NAN).contains(&0.5));
615
+ /// ```
616
+ #[ inline]
617
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
618
+ pub fn contains < U > ( & self , item : & U ) -> bool
619
+ where
620
+ Idx : PartialOrd < U > ,
621
+ U : ?Sized + PartialOrd < Idx > ,
622
+ {
623
+ <Self as RangeBounds < Idx > >:: contains ( self , item)
624
+ }
625
+ }
626
+
627
+ // RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
628
+ // because underflow would be possible with (..0).into()
629
+
630
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
631
+ impl < T > RangeBounds < T > for RangeToInclusive < T > {
632
+ fn start_bound ( & self ) -> Bound < & T > {
633
+ Unbounded
634
+ }
635
+ fn end_bound ( & self ) -> Bound < & T > {
636
+ Included ( & self . last )
637
+ }
638
+ }
639
+
640
+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
641
+ impl < T > IntoBounds < T > for RangeToInclusive < T > {
642
+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
643
+ ( Unbounded , Included ( self . last ) )
644
+ }
645
+ }
0 commit comments