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