@@ -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).
@@ -203,20 +201,20 @@ impl<T> const From<legacy::Range<T>> for Range<T> {
203
201
}
204
202
}
205
203
206
- /// A range bounded inclusively below and above (`start..=end `).
204
+ /// A range bounded inclusively below and above (`start..=last `).
207
205
///
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 `.
210
208
///
211
209
/// # Examples
212
210
///
213
- /// The `start..=end ` syntax is a `RangeInclusive`:
211
+ /// The `start..=last ` syntax is a `RangeInclusive`:
214
212
///
215
213
/// ```
216
214
/// #![feature(new_range_api)]
217
215
/// use core::range::RangeInclusive;
218
216
///
219
- /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end : 5 });
217
+ /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last : 5 });
220
218
/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
221
219
/// ```
222
220
#[ lang = "RangeInclusiveCopy" ]
@@ -228,15 +226,15 @@ pub struct RangeInclusive<Idx> {
228
226
pub start : Idx ,
229
227
/// The upper bound of the range (inclusive).
230
228
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
231
- pub end : Idx ,
229
+ pub last : Idx ,
232
230
}
233
231
234
232
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
235
233
impl < Idx : fmt:: Debug > fmt:: Debug for RangeInclusive < Idx > {
236
234
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
237
235
self . start . fmt ( fmt) ?;
238
236
write ! ( fmt, "..=" ) ?;
239
- self . end . fmt ( fmt) ?;
237
+ self . last . fmt ( fmt) ?;
240
238
Ok ( ( ) )
241
239
}
242
240
}
@@ -300,7 +298,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
300
298
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
301
299
#[ inline]
302
300
pub fn is_empty ( & self ) -> bool {
303
- !( self . start <= self . end )
301
+ !( self . start <= self . last )
304
302
}
305
303
}
306
304
@@ -329,10 +327,10 @@ impl<Idx: Step> RangeInclusive<Idx> {
329
327
330
328
impl RangeInclusive < usize > {
331
329
/// 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`.
333
331
#[ inline]
334
332
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 }
336
334
}
337
335
}
338
336
@@ -342,7 +340,7 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
342
340
Included ( & self . start )
343
341
}
344
342
fn end_bound ( & self ) -> Bound < & T > {
345
- Included ( & self . end )
343
+ Included ( & self . last )
346
344
}
347
345
}
348
346
@@ -352,15 +350,15 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
352
350
Included ( self . start )
353
351
}
354
352
fn end_bound ( & self ) -> Bound < & T > {
355
- Included ( self . end )
353
+ Included ( self . last )
356
354
}
357
355
}
358
356
359
357
// #[unstable(feature = "range_into_bounds", issue = "136903")]
360
358
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
361
359
impl < T > IntoBounds < T > for RangeInclusive < T > {
362
360
fn into_bounds ( self ) -> ( Bound < T > , Bound < T > ) {
363
- ( Included ( self . start ) , Included ( self . end ) )
361
+ ( Included ( self . start ) , Included ( self . last ) )
364
362
}
365
363
}
366
364
@@ -369,7 +367,7 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
369
367
impl < T > const From < RangeInclusive < T > > for legacy:: RangeInclusive < T > {
370
368
#[ inline]
371
369
fn from ( value : RangeInclusive < T > ) -> Self {
372
- Self :: new ( value. start , value. end )
370
+ Self :: new ( value. start , value. last )
373
371
}
374
372
}
375
373
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
@@ -381,8 +379,8 @@ impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
381
379
"attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
382
380
) ;
383
381
384
- let ( start, end ) = value. into_inner ( ) ;
385
- RangeInclusive { start, end }
382
+ let ( start, last ) = value. into_inner ( ) ;
383
+ RangeInclusive { start, last }
386
384
}
387
385
}
388
386
@@ -525,3 +523,105 @@ impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
525
523
Self { start : value. start }
526
524
}
527
525
}
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