@@ -31,9 +31,7 @@ pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive};
3131#[ doc( inline) ]
3232pub use crate :: iter:: Step ;
3333#[ 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 } ;
3735
3836/// A (half-open) range bounded inclusively below and exclusively above
3937/// (`start..end` in a future edition).
@@ -209,20 +207,20 @@ impl<T> const From<legacy::Range<T>> for Range<T> {
209207 }
210208}
211209
212- /// A range bounded inclusively below and above (`start..=end `).
210+ /// A range bounded inclusively below and above (`start..=last `).
213211///
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 `.
216214///
217215/// # Examples
218216///
219- /// The `start..=end ` syntax is a `RangeInclusive`:
217+ /// The `start..=last ` syntax is a `RangeInclusive`:
220218///
221219/// ```
222220/// #![feature(new_range_api)]
223221/// use core::range::RangeInclusive;
224222///
225- /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end : 5 });
223+ /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last : 5 });
226224/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
227225/// ```
228226#[ lang = "RangeInclusiveCopy" ]
@@ -234,15 +232,15 @@ pub struct RangeInclusive<Idx> {
234232 pub start : Idx ,
235233 /// The upper bound of the range (inclusive).
236234 #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
237- pub end : Idx ,
235+ pub last : Idx ,
238236}
239237
240238#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
241239impl < Idx : fmt:: Debug > fmt:: Debug for RangeInclusive < Idx > {
242240 fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
243241 self . start . fmt ( fmt) ?;
244242 write ! ( fmt, "..=" ) ?;
245- self . end . fmt ( fmt) ?;
243+ self . last . fmt ( fmt) ?;
246244 Ok ( ( ) )
247245 }
248246}
@@ -306,7 +304,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
306304 #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
307305 #[ inline]
308306 pub fn is_empty ( & self ) -> bool {
309- !( self . start <= self . end )
307+ !( self . start <= self . last )
310308 }
311309}
312310
@@ -335,10 +333,10 @@ impl<Idx: Step> RangeInclusive<Idx> {
335333
336334impl RangeInclusive < usize > {
337335 /// 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`.
339337 #[ inline]
340338 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 }
342340 }
343341}
344342
@@ -348,7 +346,7 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
348346 Included ( & self . start )
349347 }
350348 fn end_bound ( & self ) -> Bound < & T > {
351- Included ( & self . end )
349+ Included ( & self . last )
352350 }
353351}
354352
@@ -364,15 +362,15 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
364362 Included ( self . start )
365363 }
366364 fn end_bound ( & self ) -> Bound < & T > {
367- Included ( self . end )
365+ Included ( self . last )
368366 }
369367}
370368
371369// #[unstable(feature = "range_into_bounds", issue = "136903")]
372370#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
373371impl < T > IntoBounds < T > for RangeInclusive < T > {
374372 fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
375- ( Included ( self . start ) , Included ( self . end ) )
373+ ( Included ( self . start ) , Included ( self . last ) )
376374 }
377375}
378376
@@ -381,7 +379,7 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
381379impl < T > const From < RangeInclusive < T > > for legacy:: RangeInclusive < T > {
382380 #[ inline]
383381 fn from ( value : RangeInclusive < T > ) -> Self {
384- Self :: new ( value. start , value. end )
382+ Self :: new ( value. start , value. last )
385383 }
386384}
387385#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
@@ -393,8 +391,8 @@ impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
393391 "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
394392 ) ;
395393
396- let ( start, end ) = value. into_inner ( ) ;
397- RangeInclusive { start, end }
394+ let ( start, last ) = value. into_inner ( ) ;
395+ RangeInclusive { start, last }
398396 }
399397}
400398
@@ -543,3 +541,105 @@ impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
543541 Self { start : value. start }
544542 }
545543}
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