@@ -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,107 @@ 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
+ /// #![feature(new_range_api)]
556
+ /// #![feature(new_range)]
557
+ /// assert_eq!((..=5), std::range::RangeToInclusive{ last: 5 });
558
+ /// ```
559
+ ///
560
+ /// It does not have an [`IntoIterator`] implementation, so you can't use it in a
561
+ /// `for` loop directly. This won't compile:
562
+ ///
563
+ /// ```compile_fail,E0277
564
+ /// // error[E0277]: the trait bound `std::range::RangeToInclusive<{integer}>:
565
+ /// // std::iter::Iterator` is not satisfied
566
+ /// for i in ..=5 {
567
+ /// // ...
568
+ /// }
569
+ /// ```
570
+ ///
571
+ /// When used as a [slicing index], `RangeToInclusive` produces a slice of all
572
+ /// array elements up to and including the index indicated by `last`.
573
+ ///
574
+ /// ```
575
+ /// let arr = [0, 1, 2, 3, 4];
576
+ /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]);
577
+ /// assert_eq!(arr[ .. 3], [0, 1, 2 ]);
578
+ /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive`
579
+ /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]);
580
+ /// assert_eq!(arr[1.. 3], [ 1, 2 ]);
581
+ /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
582
+ /// ```
583
+ ///
584
+ /// [slicing index]: crate::slice::SliceIndex
585
+ #[ lang = "RangeToInclusiveCopy" ]
586
+ #[ doc( alias = "..=" ) ]
587
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
588
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
589
+ pub struct RangeToInclusive < Idx > {
590
+ /// The upper bound of the range (inclusive)
591
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
592
+ pub last : Idx ,
593
+ }
594
+
595
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
596
+ impl < Idx : fmt:: Debug > fmt:: Debug for RangeToInclusive < Idx > {
597
+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
598
+ write ! ( fmt, "..=" ) ?;
599
+ self . last . fmt ( fmt) ?;
600
+ Ok ( ( ) )
601
+ }
602
+ }
603
+
604
+ impl < Idx : PartialOrd < Idx > > RangeToInclusive < Idx > {
605
+ /// Returns `true` if `item` is contained in the range.
606
+ ///
607
+ /// # Examples
608
+ ///
609
+ /// ```
610
+ /// assert!( (..=5).contains(&-1_000_000_000));
611
+ /// assert!( (..=5).contains(&5));
612
+ /// assert!(!(..=5).contains(&6));
613
+ ///
614
+ /// assert!( (..=1.0).contains(&1.0));
615
+ /// assert!(!(..=1.0).contains(&f32::NAN));
616
+ /// assert!(!(..=f32::NAN).contains(&0.5));
617
+ /// ```
618
+ #[ inline]
619
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
620
+ pub fn contains < U > ( & self , item : & U ) -> bool
621
+ where
622
+ Idx : PartialOrd < U > ,
623
+ U : ?Sized + PartialOrd < Idx > ,
624
+ {
625
+ <Self as RangeBounds < Idx > >:: contains ( self , item)
626
+ }
627
+ }
628
+
629
+ // RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
630
+ // because underflow would be possible with (..0).into()
631
+
632
+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
633
+ impl < T > RangeBounds < T > for RangeToInclusive < T > {
634
+ fn start_bound ( & self ) -> Bound < & T > {
635
+ Unbounded
636
+ }
637
+ fn end_bound ( & self ) -> Bound < & T > {
638
+ Included ( & self . last )
639
+ }
640
+ }
641
+
642
+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
643
+ impl < T > IntoBounds < T > for RangeToInclusive < T > {
644
+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
645
+ ( Unbounded , Included ( self . last ) )
646
+ }
647
+ }
0 commit comments