@@ -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).
@@ -203,20 +201,20 @@ impl<T> const From<legacy::Range<T>> for Range<T> {
203201 }
204202}
205203
206- /// A range bounded inclusively below and above (`start..=end `).
204+ /// A range bounded inclusively below and above (`start..=last `).
207205///
208- /// The `RangeInclusive` `start..=end ` contains all values with `x >= start`
209- /// and `x <= end `. It is empty unless `start <= end `.
206+ /// The `RangeInclusive` `start..=last ` contains all values with `x >= start`
207+ /// and `x <= last `. It is empty unless `start <= last `.
210208///
211209/// # Examples
212210///
213- /// The `start..=end ` syntax is a `RangeInclusive`:
211+ /// The `start..=last ` syntax is a `RangeInclusive`:
214212///
215213/// ```
216214/// #![feature(new_range_api)]
217215/// use core::range::RangeInclusive;
218216///
219- /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end : 5 });
217+ /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last : 5 });
220218/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
221219/// ```
222220#[ lang = "RangeInclusiveCopy" ]
@@ -228,15 +226,15 @@ pub struct RangeInclusive<Idx> {
228226 pub start : Idx ,
229227 /// The upper bound of the range (inclusive).
230228 #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
231- pub end : Idx ,
229+ pub last : Idx ,
232230}
233231
234232#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
235233impl < Idx : fmt:: Debug > fmt:: Debug for RangeInclusive < Idx > {
236234 fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
237235 self . start . fmt ( fmt) ?;
238236 write ! ( fmt, "..=" ) ?;
239- self . end . fmt ( fmt) ?;
237+ self . last . fmt ( fmt) ?;
240238 Ok ( ( ) )
241239 }
242240}
@@ -300,7 +298,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
300298 #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
301299 #[ inline]
302300 pub fn is_empty ( & self ) -> bool {
303- !( self . start <= self . end )
301+ !( self . start <= self . last )
304302 }
305303}
306304
@@ -329,10 +327,10 @@ impl<Idx: Step> RangeInclusive<Idx> {
329327
330328impl RangeInclusive < usize > {
331329 /// Converts to an exclusive `Range` for `SliceIndex` implementations.
332- /// The caller is responsible for dealing with `end == usize::MAX`.
330+ /// The caller is responsible for dealing with `last == usize::MAX`.
333331 #[ inline]
334332 pub ( crate ) const fn into_slice_range ( self ) -> Range < usize > {
335- Range { start : self . start , end : self . end + 1 }
333+ Range { start : self . start , end : self . last + 1 }
336334 }
337335}
338336
@@ -342,7 +340,7 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
342340 Included ( & self . start )
343341 }
344342 fn end_bound ( & self ) -> Bound < & T > {
345- Included ( & self . end )
343+ Included ( & self . last )
346344 }
347345}
348346
@@ -352,15 +350,15 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
352350 Included ( self . start )
353351 }
354352 fn end_bound ( & self ) -> Bound < & T > {
355- Included ( self . end )
353+ Included ( self . last )
356354 }
357355}
358356
359357// #[unstable(feature = "range_into_bounds", issue = "136903")]
360358#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
361359impl < T > IntoBounds < T > for RangeInclusive < T > {
362360 fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
363- ( Included ( self . start ) , Included ( self . end ) )
361+ ( Included ( self . start ) , Included ( self . last ) )
364362 }
365363}
366364
@@ -369,7 +367,7 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
369367impl < T > const From < RangeInclusive < T > > for legacy:: RangeInclusive < T > {
370368 #[ inline]
371369 fn from ( value : RangeInclusive < T > ) -> Self {
372- Self :: new ( value. start , value. end )
370+ Self :: new ( value. start , value. last )
373371 }
374372}
375373#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
@@ -381,8 +379,8 @@ impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
381379 "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
382380 ) ;
383381
384- let ( start, end ) = value. into_inner ( ) ;
385- RangeInclusive { start, end }
382+ let ( start, last ) = value. into_inner ( ) ;
383+ RangeInclusive { start, last }
386384 }
387385}
388386
@@ -525,3 +523,105 @@ impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
525523 Self { start : value. start }
526524 }
527525}
526+
527+ /// A range only bounded inclusively above (`..=last`).
528+ ///
529+ /// The `RangeToInclusive` `..=last` contains all values with `x <= last`.
530+ /// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
531+ ///
532+ /// # Examples
533+ ///
534+ /// The `..=last` syntax is a `RangeToInclusive`:
535+ ///
536+ /// ```
537+ /// assert_eq!((..=5), std::ops::RangeToInclusive{ last: 5 });
538+ /// ```
539+ ///
540+ /// It does not have an [`IntoIterator`] implementation, so you can't use it in a
541+ /// `for` loop directly. This won't compile:
542+ ///
543+ /// ```compile_fail,E0277
544+ /// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>:
545+ /// // std::iter::Iterator` is not satisfied
546+ /// for i in ..=5 {
547+ /// // ...
548+ /// }
549+ /// ```
550+ ///
551+ /// When used as a [slicing index], `RangeToInclusive` produces a slice of all
552+ /// array elements up to and including the index indicated by `last`.
553+ ///
554+ /// ```
555+ /// let arr = [0, 1, 2, 3, 4];
556+ /// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]);
557+ /// assert_eq!(arr[ .. 3], [0, 1, 2 ]);
558+ /// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive`
559+ /// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]);
560+ /// assert_eq!(arr[1.. 3], [ 1, 2 ]);
561+ /// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
562+ /// ```
563+ ///
564+ /// [slicing index]: crate::slice::SliceIndex
565+ #[ lang = "RangeToInclusiveCopy" ]
566+ #[ doc( alias = "..=" ) ]
567+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
568+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
569+ pub struct RangeToInclusive < Idx > {
570+ /// The upper bound of the range (inclusive)
571+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
572+ pub last : Idx ,
573+ }
574+
575+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
576+ impl < Idx : fmt:: Debug > fmt:: Debug for RangeToInclusive < Idx > {
577+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
578+ write ! ( fmt, "..=" ) ?;
579+ self . last . fmt ( fmt) ?;
580+ Ok ( ( ) )
581+ }
582+ }
583+
584+ impl < Idx : PartialOrd < Idx > > RangeToInclusive < Idx > {
585+ /// Returns `true` if `item` is contained in the range.
586+ ///
587+ /// # Examples
588+ ///
589+ /// ```
590+ /// assert!( (..=5).contains(&-1_000_000_000));
591+ /// assert!( (..=5).contains(&5));
592+ /// assert!(!(..=5).contains(&6));
593+ ///
594+ /// assert!( (..=1.0).contains(&1.0));
595+ /// assert!(!(..=1.0).contains(&f32::NAN));
596+ /// assert!(!(..=f32::NAN).contains(&0.5));
597+ /// ```
598+ #[ inline]
599+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
600+ pub fn contains < U > ( & self , item : & U ) -> bool
601+ where
602+ Idx : PartialOrd < U > ,
603+ U : ?Sized + PartialOrd < Idx > ,
604+ {
605+ <Self as RangeBounds < Idx > >:: contains ( self , item)
606+ }
607+ }
608+
609+ // RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
610+ // because underflow would be possible with (..0).into()
611+
612+ #[ unstable( feature = "new_range_api" , issue = "125687" ) ]
613+ impl < T > RangeBounds < T > for RangeToInclusive < T > {
614+ fn start_bound ( & self ) -> Bound < & T > {
615+ Unbounded
616+ }
617+ fn end_bound ( & self ) -> Bound < & T > {
618+ Included ( & self . last )
619+ }
620+ }
621+
622+ #[ unstable( feature = "range_into_bounds" , issue = "136903" ) ]
623+ impl < T > IntoBounds < T > for RangeToInclusive < T > {
624+ fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
625+ ( Unbounded , Included ( self . last ) )
626+ }
627+ }
0 commit comments