• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::convert::TryFrom;
2 use crate::mem;
3 use crate::num::NonZeroUsize;
4 use crate::ops::{self, Try};
5 
6 use super::{
7     FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
8 };
9 
10 // Safety: All invariants are upheld.
11 macro_rules! unsafe_impl_trusted_step {
12     ($($type:ty)*) => {$(
13         #[unstable(feature = "trusted_step", issue = "85731")]
14         unsafe impl TrustedStep for $type {}
15     )*};
16 }
17 unsafe_impl_trusted_step![char i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize];
18 
19 /// Objects that have a notion of *successor* and *predecessor* operations.
20 ///
21 /// The *successor* operation moves towards values that compare greater.
22 /// The *predecessor* operation moves towards values that compare lesser.
23 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
24 pub trait Step: Clone + PartialOrd + Sized {
25     /// Returns the number of *successor* steps required to get from `start` to `end`.
26     ///
27     /// Returns `None` if the number of steps would overflow `usize`
28     /// (or is infinite, or if `end` would never be reached).
29     ///
30     /// # Invariants
31     ///
32     /// For any `a`, `b`, and `n`:
33     ///
34     /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)`
35     /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&b, n) == Some(a)`
36     /// * `steps_between(&a, &b) == Some(n)` only if `a <= b`
37     ///   * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b`
38     ///   * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
39     ///     this is the case when it would require more than `usize::MAX` steps to get to `b`
40     /// * `steps_between(&a, &b) == None` if `a > b`
steps_between(start: &Self, end: &Self) -> Option<usize>41     fn steps_between(start: &Self, end: &Self) -> Option<usize>;
42 
43     /// Returns the value that would be obtained by taking the *successor*
44     /// of `self` `count` times.
45     ///
46     /// If this would overflow the range of values supported by `Self`, returns `None`.
47     ///
48     /// # Invariants
49     ///
50     /// For any `a`, `n`, and `m`:
51     ///
52     /// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, m).and_then(|x| Step::forward_checked(x, n))`
53     ///
54     /// For any `a`, `n`, and `m` where `n + m` does not overflow:
55     ///
56     /// * `Step::forward_checked(a, n).and_then(|x| Step::forward_checked(x, m)) == Step::forward_checked(a, n + m)`
57     ///
58     /// For any `a` and `n`:
59     ///
60     /// * `Step::forward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::forward_checked(&x, 1))`
61     ///   * Corollary: `Step::forward_checked(&a, 0) == Some(a)`
forward_checked(start: Self, count: usize) -> Option<Self>62     fn forward_checked(start: Self, count: usize) -> Option<Self>;
63 
64     /// Returns the value that would be obtained by taking the *successor*
65     /// of `self` `count` times.
66     ///
67     /// If this would overflow the range of values supported by `Self`,
68     /// this function is allowed to panic, wrap, or saturate.
69     /// The suggested behavior is to panic when debug assertions are enabled,
70     /// and to wrap or saturate otherwise.
71     ///
72     /// Unsafe code should not rely on the correctness of behavior after overflow.
73     ///
74     /// # Invariants
75     ///
76     /// For any `a`, `n`, and `m`, where no overflow occurs:
77     ///
78     /// * `Step::forward(Step::forward(a, n), m) == Step::forward(a, n + m)`
79     ///
80     /// For any `a` and `n`, where no overflow occurs:
81     ///
82     /// * `Step::forward_checked(a, n) == Some(Step::forward(a, n))`
83     /// * `Step::forward(a, n) == (0..n).fold(a, |x, _| Step::forward(x, 1))`
84     ///   * Corollary: `Step::forward(a, 0) == a`
85     /// * `Step::forward(a, n) >= a`
86     /// * `Step::backward(Step::forward(a, n), n) == a`
forward(start: Self, count: usize) -> Self87     fn forward(start: Self, count: usize) -> Self {
88         Step::forward_checked(start, count).expect("overflow in `Step::forward`")
89     }
90 
91     /// Returns the value that would be obtained by taking the *successor*
92     /// of `self` `count` times.
93     ///
94     /// # Safety
95     ///
96     /// It is undefined behavior for this operation to overflow the
97     /// range of values supported by `Self`. If you cannot guarantee that this
98     /// will not overflow, use `forward` or `forward_checked` instead.
99     ///
100     /// # Invariants
101     ///
102     /// For any `a`:
103     ///
104     /// * if there exists `b` such that `b > a`, it is safe to call `Step::forward_unchecked(a, 1)`
105     /// * if there exists `b`, `n` such that `steps_between(&a, &b) == Some(n)`,
106     ///   it is safe to call `Step::forward_unchecked(a, m)` for any `m <= n`.
107     ///
108     /// For any `a` and `n`, where no overflow occurs:
109     ///
110     /// * `Step::forward_unchecked(a, n)` is equivalent to `Step::forward(a, n)`
forward_unchecked(start: Self, count: usize) -> Self111     unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
112         Step::forward(start, count)
113     }
114 
115     /// Returns the value that would be obtained by taking the *predecessor*
116     /// of `self` `count` times.
117     ///
118     /// If this would overflow the range of values supported by `Self`, returns `None`.
119     ///
120     /// # Invariants
121     ///
122     /// For any `a`, `n`, and `m`:
123     ///
124     /// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == n.checked_add(m).and_then(|x| Step::backward_checked(a, x))`
125     /// * `Step::backward_checked(a, n).and_then(|x| Step::backward_checked(x, m)) == try { Step::backward_checked(a, n.checked_add(m)?) }`
126     ///
127     /// For any `a` and `n`:
128     ///
129     /// * `Step::backward_checked(a, n) == (0..n).try_fold(a, |x, _| Step::backward_checked(&x, 1))`
130     ///   * Corollary: `Step::backward_checked(&a, 0) == Some(a)`
backward_checked(start: Self, count: usize) -> Option<Self>131     fn backward_checked(start: Self, count: usize) -> Option<Self>;
132 
133     /// Returns the value that would be obtained by taking the *predecessor*
134     /// of `self` `count` times.
135     ///
136     /// If this would overflow the range of values supported by `Self`,
137     /// this function is allowed to panic, wrap, or saturate.
138     /// The suggested behavior is to panic when debug assertions are enabled,
139     /// and to wrap or saturate otherwise.
140     ///
141     /// Unsafe code should not rely on the correctness of behavior after overflow.
142     ///
143     /// # Invariants
144     ///
145     /// For any `a`, `n`, and `m`, where no overflow occurs:
146     ///
147     /// * `Step::backward(Step::backward(a, n), m) == Step::backward(a, n + m)`
148     ///
149     /// For any `a` and `n`, where no overflow occurs:
150     ///
151     /// * `Step::backward_checked(a, n) == Some(Step::backward(a, n))`
152     /// * `Step::backward(a, n) == (0..n).fold(a, |x, _| Step::backward(x, 1))`
153     ///   * Corollary: `Step::backward(a, 0) == a`
154     /// * `Step::backward(a, n) <= a`
155     /// * `Step::forward(Step::backward(a, n), n) == a`
backward(start: Self, count: usize) -> Self156     fn backward(start: Self, count: usize) -> Self {
157         Step::backward_checked(start, count).expect("overflow in `Step::backward`")
158     }
159 
160     /// Returns the value that would be obtained by taking the *predecessor*
161     /// of `self` `count` times.
162     ///
163     /// # Safety
164     ///
165     /// It is undefined behavior for this operation to overflow the
166     /// range of values supported by `Self`. If you cannot guarantee that this
167     /// will not overflow, use `backward` or `backward_checked` instead.
168     ///
169     /// # Invariants
170     ///
171     /// For any `a`:
172     ///
173     /// * if there exists `b` such that `b < a`, it is safe to call `Step::backward_unchecked(a, 1)`
174     /// * if there exists `b`, `n` such that `steps_between(&b, &a) == Some(n)`,
175     ///   it is safe to call `Step::backward_unchecked(a, m)` for any `m <= n`.
176     ///
177     /// For any `a` and `n`, where no overflow occurs:
178     ///
179     /// * `Step::backward_unchecked(a, n)` is equivalent to `Step::backward(a, n)`
backward_unchecked(start: Self, count: usize) -> Self180     unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
181         Step::backward(start, count)
182     }
183 }
184 
185 // These are still macro-generated because the integer literals resolve to different types.
186 macro_rules! step_identical_methods {
187     () => {
188         #[inline]
189         unsafe fn forward_unchecked(start: Self, n: usize) -> Self {
190             // SAFETY: the caller has to guarantee that `start + n` doesn't overflow.
191             unsafe { start.unchecked_add(n as Self) }
192         }
193 
194         #[inline]
195         unsafe fn backward_unchecked(start: Self, n: usize) -> Self {
196             // SAFETY: the caller has to guarantee that `start - n` doesn't overflow.
197             unsafe { start.unchecked_sub(n as Self) }
198         }
199 
200         #[inline]
201         #[allow(arithmetic_overflow)]
202         #[rustc_inherit_overflow_checks]
203         fn forward(start: Self, n: usize) -> Self {
204             // In debug builds, trigger a panic on overflow.
205             // This should optimize completely out in release builds.
206             if Self::forward_checked(start, n).is_none() {
207                 let _ = Self::MAX + 1;
208             }
209             // Do wrapping math to allow e.g. `Step::forward(-128i8, 255)`.
210             start.wrapping_add(n as Self)
211         }
212 
213         #[inline]
214         #[allow(arithmetic_overflow)]
215         #[rustc_inherit_overflow_checks]
216         fn backward(start: Self, n: usize) -> Self {
217             // In debug builds, trigger a panic on overflow.
218             // This should optimize completely out in release builds.
219             if Self::backward_checked(start, n).is_none() {
220                 let _ = Self::MIN - 1;
221             }
222             // Do wrapping math to allow e.g. `Step::backward(127i8, 255)`.
223             start.wrapping_sub(n as Self)
224         }
225     };
226 }
227 
228 macro_rules! step_integer_impls {
229     {
230         narrower than or same width as usize:
231             $( [ $u_narrower:ident $i_narrower:ident ] ),+;
232         wider than usize:
233             $( [ $u_wider:ident $i_wider:ident ] ),+;
234     } => {
235         $(
236             #[allow(unreachable_patterns)]
237             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
238             impl Step for $u_narrower {
239                 step_identical_methods!();
240 
241                 #[inline]
242                 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
243                     if *start <= *end {
244                         // This relies on $u_narrower <= usize
245                         Some((*end - *start) as usize)
246                     } else {
247                         None
248                     }
249                 }
250 
251                 #[inline]
252                 fn forward_checked(start: Self, n: usize) -> Option<Self> {
253                     match Self::try_from(n) {
254                         Ok(n) => start.checked_add(n),
255                         Err(_) => None, // if n is out of range, `unsigned_start + n` is too
256                     }
257                 }
258 
259                 #[inline]
260                 fn backward_checked(start: Self, n: usize) -> Option<Self> {
261                     match Self::try_from(n) {
262                         Ok(n) => start.checked_sub(n),
263                         Err(_) => None, // if n is out of range, `unsigned_start - n` is too
264                     }
265                 }
266             }
267 
268             #[allow(unreachable_patterns)]
269             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
270             impl Step for $i_narrower {
271                 step_identical_methods!();
272 
273                 #[inline]
274                 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
275                     if *start <= *end {
276                         // This relies on $i_narrower <= usize
277                         //
278                         // Casting to isize extends the width but preserves the sign.
279                         // Use wrapping_sub in isize space and cast to usize to compute
280                         // the difference that might not fit inside the range of isize.
281                         Some((*end as isize).wrapping_sub(*start as isize) as usize)
282                     } else {
283                         None
284                     }
285                 }
286 
287                 #[inline]
288                 fn forward_checked(start: Self, n: usize) -> Option<Self> {
289                     match $u_narrower::try_from(n) {
290                         Ok(n) => {
291                             // Wrapping handles cases like
292                             // `Step::forward(-120_i8, 200) == Some(80_i8)`,
293                             // even though 200 is out of range for i8.
294                             let wrapped = start.wrapping_add(n as Self);
295                             if wrapped >= start {
296                                 Some(wrapped)
297                             } else {
298                                 None // Addition overflowed
299                             }
300                         }
301                         // If n is out of range of e.g. u8,
302                         // then it is bigger than the entire range for i8 is wide
303                         // so `any_i8 + n` necessarily overflows i8.
304                         Err(_) => None,
305                     }
306                 }
307 
308                 #[inline]
309                 fn backward_checked(start: Self, n: usize) -> Option<Self> {
310                     match $u_narrower::try_from(n) {
311                         Ok(n) => {
312                             // Wrapping handles cases like
313                             // `Step::forward(-120_i8, 200) == Some(80_i8)`,
314                             // even though 200 is out of range for i8.
315                             let wrapped = start.wrapping_sub(n as Self);
316                             if wrapped <= start {
317                                 Some(wrapped)
318                             } else {
319                                 None // Subtraction overflowed
320                             }
321                         }
322                         // If n is out of range of e.g. u8,
323                         // then it is bigger than the entire range for i8 is wide
324                         // so `any_i8 - n` necessarily overflows i8.
325                         Err(_) => None,
326                     }
327                 }
328             }
329         )+
330 
331         $(
332             #[allow(unreachable_patterns)]
333             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
334             impl Step for $u_wider {
335                 step_identical_methods!();
336 
337                 #[inline]
338                 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
339                     if *start <= *end {
340                         usize::try_from(*end - *start).ok()
341                     } else {
342                         None
343                     }
344                 }
345 
346                 #[inline]
347                 fn forward_checked(start: Self, n: usize) -> Option<Self> {
348                     start.checked_add(n as Self)
349                 }
350 
351                 #[inline]
352                 fn backward_checked(start: Self, n: usize) -> Option<Self> {
353                     start.checked_sub(n as Self)
354                 }
355             }
356 
357             #[allow(unreachable_patterns)]
358             #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
359             impl Step for $i_wider {
360                 step_identical_methods!();
361 
362                 #[inline]
363                 fn steps_between(start: &Self, end: &Self) -> Option<usize> {
364                     if *start <= *end {
365                         match end.checked_sub(*start) {
366                             Some(result) => usize::try_from(result).ok(),
367                             // If the difference is too big for e.g. i128,
368                             // it's also gonna be too big for usize with fewer bits.
369                             None => None,
370                         }
371                     } else {
372                         None
373                     }
374                 }
375 
376                 #[inline]
377                 fn forward_checked(start: Self, n: usize) -> Option<Self> {
378                     start.checked_add(n as Self)
379                 }
380 
381                 #[inline]
382                 fn backward_checked(start: Self, n: usize) -> Option<Self> {
383                     start.checked_sub(n as Self)
384                 }
385             }
386         )+
387     };
388 }
389 
390 #[cfg(target_pointer_width = "64")]
391 step_integer_impls! {
392     narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [u64 i64], [usize isize];
393     wider than usize: [u128 i128];
394 }
395 
396 #[cfg(target_pointer_width = "32")]
397 step_integer_impls! {
398     narrower than or same width as usize: [u8 i8], [u16 i16], [u32 i32], [usize isize];
399     wider than usize: [u64 i64], [u128 i128];
400 }
401 
402 #[cfg(target_pointer_width = "16")]
403 step_integer_impls! {
404     narrower than or same width as usize: [u8 i8], [u16 i16], [usize isize];
405     wider than usize: [u32 i32], [u64 i64], [u128 i128];
406 }
407 
408 #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")]
409 impl Step for char {
410     #[inline]
steps_between(&start: &char, &end: &char) -> Option<usize>411     fn steps_between(&start: &char, &end: &char) -> Option<usize> {
412         let start = start as u32;
413         let end = end as u32;
414         if start <= end {
415             let count = end - start;
416             if start < 0xD800 && 0xE000 <= end {
417                 usize::try_from(count - 0x800).ok()
418             } else {
419                 usize::try_from(count).ok()
420             }
421         } else {
422             None
423         }
424     }
425 
426     #[inline]
forward_checked(start: char, count: usize) -> Option<char>427     fn forward_checked(start: char, count: usize) -> Option<char> {
428         let start = start as u32;
429         let mut res = Step::forward_checked(start, count)?;
430         if start < 0xD800 && 0xD800 <= res {
431             res = Step::forward_checked(res, 0x800)?;
432         }
433         if res <= char::MAX as u32 {
434             // SAFETY: res is a valid unicode scalar
435             // (below 0x110000 and not in 0xD800..0xE000)
436             Some(unsafe { char::from_u32_unchecked(res) })
437         } else {
438             None
439         }
440     }
441 
442     #[inline]
backward_checked(start: char, count: usize) -> Option<char>443     fn backward_checked(start: char, count: usize) -> Option<char> {
444         let start = start as u32;
445         let mut res = Step::backward_checked(start, count)?;
446         if start >= 0xE000 && 0xE000 > res {
447             res = Step::backward_checked(res, 0x800)?;
448         }
449         // SAFETY: res is a valid unicode scalar
450         // (below 0x110000 and not in 0xD800..0xE000)
451         Some(unsafe { char::from_u32_unchecked(res) })
452     }
453 
454     #[inline]
forward_unchecked(start: char, count: usize) -> char455     unsafe fn forward_unchecked(start: char, count: usize) -> char {
456         let start = start as u32;
457         // SAFETY: the caller must guarantee that this doesn't overflow
458         // the range of values for a char.
459         let mut res = unsafe { Step::forward_unchecked(start, count) };
460         if start < 0xD800 && 0xD800 <= res {
461             // SAFETY: the caller must guarantee that this doesn't overflow
462             // the range of values for a char.
463             res = unsafe { Step::forward_unchecked(res, 0x800) };
464         }
465         // SAFETY: because of the previous contract, this is guaranteed
466         // by the caller to be a valid char.
467         unsafe { char::from_u32_unchecked(res) }
468     }
469 
470     #[inline]
backward_unchecked(start: char, count: usize) -> char471     unsafe fn backward_unchecked(start: char, count: usize) -> char {
472         let start = start as u32;
473         // SAFETY: the caller must guarantee that this doesn't overflow
474         // the range of values for a char.
475         let mut res = unsafe { Step::backward_unchecked(start, count) };
476         if start >= 0xE000 && 0xE000 > res {
477             // SAFETY: the caller must guarantee that this doesn't overflow
478             // the range of values for a char.
479             res = unsafe { Step::backward_unchecked(res, 0x800) };
480         }
481         // SAFETY: because of the previous contract, this is guaranteed
482         // by the caller to be a valid char.
483         unsafe { char::from_u32_unchecked(res) }
484     }
485 }
486 
487 macro_rules! range_exact_iter_impl {
488     ($($t:ty)*) => ($(
489         #[stable(feature = "rust1", since = "1.0.0")]
490         impl ExactSizeIterator for ops::Range<$t> { }
491     )*)
492 }
493 
494 /// Safety: This macro must only be used on types that are `Copy` and result in ranges
495 /// which have an exact `size_hint()` where the upper bound must not be `None`.
496 macro_rules! unsafe_range_trusted_random_access_impl {
497     ($($t:ty)*) => ($(
498         #[doc(hidden)]
499         #[unstable(feature = "trusted_random_access", issue = "none")]
500         unsafe impl TrustedRandomAccess for ops::Range<$t> {}
501 
502         #[doc(hidden)]
503         #[unstable(feature = "trusted_random_access", issue = "none")]
504         unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
505             const MAY_HAVE_SIDE_EFFECT: bool = false;
506         }
507     )*)
508 }
509 
510 macro_rules! range_incl_exact_iter_impl {
511     ($($t:ty)*) => ($(
512         #[stable(feature = "inclusive_range", since = "1.26.0")]
513         impl ExactSizeIterator for ops::RangeInclusive<$t> { }
514     )*)
515 }
516 
517 /// Specialization implementations for `Range`.
518 trait RangeIteratorImpl {
519     type Item;
520 
521     // Iterator
spec_next(&mut self) -> Option<Self::Item>522     fn spec_next(&mut self) -> Option<Self::Item>;
spec_nth(&mut self, n: usize) -> Option<Self::Item>523     fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>524     fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>;
525 
526     // DoubleEndedIterator
spec_next_back(&mut self) -> Option<Self::Item>527     fn spec_next_back(&mut self) -> Option<Self::Item>;
spec_nth_back(&mut self, n: usize) -> Option<Self::Item>528     fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>529     fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>;
530 }
531 
532 impl<A: Step> RangeIteratorImpl for ops::Range<A> {
533     type Item = A;
534 
535     #[inline]
spec_next(&mut self) -> Option<A>536     default fn spec_next(&mut self) -> Option<A> {
537         if self.start < self.end {
538             let n =
539                 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
540             Some(mem::replace(&mut self.start, n))
541         } else {
542             None
543         }
544     }
545 
546     #[inline]
spec_nth(&mut self, n: usize) -> Option<A>547     default fn spec_nth(&mut self, n: usize) -> Option<A> {
548         if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
549             if plus_n < self.end {
550                 self.start =
551                     Step::forward_checked(plus_n.clone(), 1).expect("`Step` invariants not upheld");
552                 return Some(plus_n);
553             }
554         }
555 
556         self.start = self.end.clone();
557         None
558     }
559 
560     #[inline]
spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>561     default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
562         let available = if self.start <= self.end {
563             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
564         } else {
565             0
566         };
567 
568         let taken = available.min(n);
569 
570         self.start =
571             Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
572 
573         NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
574     }
575 
576     #[inline]
spec_next_back(&mut self) -> Option<A>577     default fn spec_next_back(&mut self) -> Option<A> {
578         if self.start < self.end {
579             self.end =
580                 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
581             Some(self.end.clone())
582         } else {
583             None
584         }
585     }
586 
587     #[inline]
spec_nth_back(&mut self, n: usize) -> Option<A>588     default fn spec_nth_back(&mut self, n: usize) -> Option<A> {
589         if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
590             if minus_n > self.start {
591                 self.end =
592                     Step::backward_checked(minus_n, 1).expect("`Step` invariants not upheld");
593                 return Some(self.end.clone());
594             }
595         }
596 
597         self.end = self.start.clone();
598         None
599     }
600 
601     #[inline]
spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>602     default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
603         let available = if self.start <= self.end {
604             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
605         } else {
606             0
607         };
608 
609         let taken = available.min(n);
610 
611         self.end =
612             Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
613 
614         NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
615     }
616 }
617 
618 impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
619     #[inline]
spec_next(&mut self) -> Option<T>620     fn spec_next(&mut self) -> Option<T> {
621         if self.start < self.end {
622             let old = self.start;
623             // SAFETY: just checked precondition
624             self.start = unsafe { Step::forward_unchecked(old, 1) };
625             Some(old)
626         } else {
627             None
628         }
629     }
630 
631     #[inline]
spec_nth(&mut self, n: usize) -> Option<T>632     fn spec_nth(&mut self, n: usize) -> Option<T> {
633         if let Some(plus_n) = Step::forward_checked(self.start, n) {
634             if plus_n < self.end {
635                 // SAFETY: just checked precondition
636                 self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
637                 return Some(plus_n);
638             }
639         }
640 
641         self.start = self.end;
642         None
643     }
644 
645     #[inline]
spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>646     fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
647         let available = if self.start <= self.end {
648             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
649         } else {
650             0
651         };
652 
653         let taken = available.min(n);
654 
655         // SAFETY: the conditions above ensure that the count is in bounds. If start <= end
656         // then steps_between either returns a bound to which we clamp or returns None which
657         // together with the initial inequality implies more than usize::MAX steps.
658         // Otherwise 0 is returned which always safe to use.
659         self.start = unsafe { Step::forward_unchecked(self.start, taken) };
660 
661         NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
662     }
663 
664     #[inline]
spec_next_back(&mut self) -> Option<T>665     fn spec_next_back(&mut self) -> Option<T> {
666         if self.start < self.end {
667             // SAFETY: just checked precondition
668             self.end = unsafe { Step::backward_unchecked(self.end, 1) };
669             Some(self.end)
670         } else {
671             None
672         }
673     }
674 
675     #[inline]
spec_nth_back(&mut self, n: usize) -> Option<T>676     fn spec_nth_back(&mut self, n: usize) -> Option<T> {
677         if let Some(minus_n) = Step::backward_checked(self.end, n) {
678             if minus_n > self.start {
679                 // SAFETY: just checked precondition
680                 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
681                 return Some(self.end);
682             }
683         }
684 
685         self.end = self.start;
686         None
687     }
688 
689     #[inline]
spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>690     fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
691         let available = if self.start <= self.end {
692             Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
693         } else {
694             0
695         };
696 
697         let taken = available.min(n);
698 
699         // SAFETY: same as the spec_advance_by() implementation
700         self.end = unsafe { Step::backward_unchecked(self.end, taken) };
701 
702         NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
703     }
704 }
705 
706 #[stable(feature = "rust1", since = "1.0.0")]
707 impl<A: Step> Iterator for ops::Range<A> {
708     type Item = A;
709 
710     #[inline]
next(&mut self) -> Option<A>711     fn next(&mut self) -> Option<A> {
712         self.spec_next()
713     }
714 
715     #[inline]
size_hint(&self) -> (usize, Option<usize>)716     fn size_hint(&self) -> (usize, Option<usize>) {
717         if self.start < self.end {
718             let hint = Step::steps_between(&self.start, &self.end);
719             (hint.unwrap_or(usize::MAX), hint)
720         } else {
721             (0, Some(0))
722         }
723     }
724 
725     #[inline]
nth(&mut self, n: usize) -> Option<A>726     fn nth(&mut self, n: usize) -> Option<A> {
727         self.spec_nth(n)
728     }
729 
730     #[inline]
last(mut self) -> Option<A>731     fn last(mut self) -> Option<A> {
732         self.next_back()
733     }
734 
735     #[inline]
min(mut self) -> Option<A> where A: Ord,736     fn min(mut self) -> Option<A>
737     where
738         A: Ord,
739     {
740         self.next()
741     }
742 
743     #[inline]
max(mut self) -> Option<A> where A: Ord,744     fn max(mut self) -> Option<A>
745     where
746         A: Ord,
747     {
748         self.next_back()
749     }
750 
751     #[inline]
is_sorted(self) -> bool752     fn is_sorted(self) -> bool {
753         true
754     }
755 
756     #[inline]
advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>757     fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
758         self.spec_advance_by(n)
759     }
760 
761     #[inline]
__iterator_get_unchecked(&mut self, idx: usize) -> Self::Item where Self: TrustedRandomAccessNoCoerce,762     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
763     where
764         Self: TrustedRandomAccessNoCoerce,
765     {
766         // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
767         // that is in bounds.
768         // Additionally Self: TrustedRandomAccess is only implemented for Copy types
769         // which means even repeated reads of the same index would be safe.
770         unsafe { Step::forward_unchecked(self.start.clone(), idx) }
771     }
772 }
773 
774 // These macros generate `ExactSizeIterator` impls for various range types.
775 //
776 // * `ExactSizeIterator::len` is required to always return an exact `usize`,
777 //   so no range can be longer than `usize::MAX`.
778 // * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
779 //   For integer types in `RangeInclusive<_>`
780 //   this is the case for types *strictly narrower* than `usize`
781 //   since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
782 range_exact_iter_impl! {
783     usize u8 u16
784     isize i8 i16
785 
786     // These are incorrect per the reasoning above,
787     // but removing them would be a breaking change as they were stabilized in Rust 1.0.0.
788     // So e.g. `(0..66_000_u32).len()` for example will compile without error or warnings
789     // on 16-bit platforms, but continue to give a wrong result.
790     u32
791     i32
792 }
793 
794 unsafe_range_trusted_random_access_impl! {
795     usize u8 u16
796     isize i8 i16
797 }
798 
799 #[cfg(target_pointer_width = "32")]
800 unsafe_range_trusted_random_access_impl! {
801     u32 i32
802 }
803 
804 #[cfg(target_pointer_width = "64")]
805 unsafe_range_trusted_random_access_impl! {
806     u32 i32
807     u64 i64
808 }
809 
810 range_incl_exact_iter_impl! {
811     u8
812     i8
813 
814     // These are incorrect per the reasoning above,
815     // but removing them would be a breaking change as they were stabilized in Rust 1.26.0.
816     // So e.g. `(0..=u16::MAX).len()` for example will compile without error or warnings
817     // on 16-bit platforms, but continue to give a wrong result.
818     u16
819     i16
820 }
821 
822 #[stable(feature = "rust1", since = "1.0.0")]
823 impl<A: Step> DoubleEndedIterator for ops::Range<A> {
824     #[inline]
next_back(&mut self) -> Option<A>825     fn next_back(&mut self) -> Option<A> {
826         self.spec_next_back()
827     }
828 
829     #[inline]
nth_back(&mut self, n: usize) -> Option<A>830     fn nth_back(&mut self, n: usize) -> Option<A> {
831         self.spec_nth_back(n)
832     }
833 
834     #[inline]
advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>835     fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
836         self.spec_advance_back_by(n)
837     }
838 }
839 
840 // Safety:
841 // The following invariants for `Step::steps_between` exist:
842 //
843 // > * `steps_between(&a, &b) == Some(n)` only if `a <= b`
844 // >   * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
845 // >     this is the case when it would require more than `usize::MAX` steps to
846 // >     get to `b`
847 // > * `steps_between(&a, &b) == None` if `a > b`
848 //
849 // The first invariant is what is generally required for `TrustedLen` to be
850 // sound. The note addendum satisfies an additional `TrustedLen` invariant.
851 //
852 // > The upper bound must only be `None` if the actual iterator length is larger
853 // > than `usize::MAX`
854 //
855 // The second invariant logically follows the first so long as the `PartialOrd`
856 // implementation is correct; regardless it is explicitly stated. If `a < b`
857 // then `(0, Some(0))` is returned by `ops::Range<A: Step>::size_hint`. As such
858 // the second invariant is upheld.
859 #[unstable(feature = "trusted_len", issue = "37572")]
860 unsafe impl<A: TrustedStep> TrustedLen for ops::Range<A> {}
861 
862 #[stable(feature = "fused", since = "1.26.0")]
863 impl<A: Step> FusedIterator for ops::Range<A> {}
864 
865 #[stable(feature = "rust1", since = "1.0.0")]
866 impl<A: Step> Iterator for ops::RangeFrom<A> {
867     type Item = A;
868 
869     #[inline]
next(&mut self) -> Option<A>870     fn next(&mut self) -> Option<A> {
871         let n = Step::forward(self.start.clone(), 1);
872         Some(mem::replace(&mut self.start, n))
873     }
874 
875     #[inline]
size_hint(&self) -> (usize, Option<usize>)876     fn size_hint(&self) -> (usize, Option<usize>) {
877         (usize::MAX, None)
878     }
879 
880     #[inline]
nth(&mut self, n: usize) -> Option<A>881     fn nth(&mut self, n: usize) -> Option<A> {
882         let plus_n = Step::forward(self.start.clone(), n);
883         self.start = Step::forward(plus_n.clone(), 1);
884         Some(plus_n)
885     }
886 }
887 
888 // Safety: See above implementation for `ops::Range<A>`
889 #[unstable(feature = "trusted_len", issue = "37572")]
890 unsafe impl<A: TrustedStep> TrustedLen for ops::RangeFrom<A> {}
891 
892 #[stable(feature = "fused", since = "1.26.0")]
893 impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
894 
895 trait RangeInclusiveIteratorImpl {
896     type Item;
897 
898     // Iterator
spec_next(&mut self) -> Option<Self::Item>899     fn spec_next(&mut self) -> Option<Self::Item>;
spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>900     fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
901     where
902         Self: Sized,
903         F: FnMut(B, Self::Item) -> R,
904         R: Try<Output = B>;
905 
906     // DoubleEndedIterator
spec_next_back(&mut self) -> Option<Self::Item>907     fn spec_next_back(&mut self) -> Option<Self::Item>;
spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>908     fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
909     where
910         Self: Sized,
911         F: FnMut(B, Self::Item) -> R,
912         R: Try<Output = B>;
913 }
914 
915 impl<A: Step> RangeInclusiveIteratorImpl for ops::RangeInclusive<A> {
916     type Item = A;
917 
918     #[inline]
spec_next(&mut self) -> Option<A>919     default fn spec_next(&mut self) -> Option<A> {
920         if self.is_empty() {
921             return None;
922         }
923         let is_iterating = self.start < self.end;
924         Some(if is_iterating {
925             let n =
926                 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
927             mem::replace(&mut self.start, n)
928         } else {
929             self.exhausted = true;
930             self.start.clone()
931         })
932     }
933 
934     #[inline]
spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, A) -> R, R: Try<Output = B>,935     default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
936     where
937         Self: Sized,
938         F: FnMut(B, A) -> R,
939         R: Try<Output = B>,
940     {
941         if self.is_empty() {
942             return try { init };
943         }
944 
945         let mut accum = init;
946 
947         while self.start < self.end {
948             let n =
949                 Step::forward_checked(self.start.clone(), 1).expect("`Step` invariants not upheld");
950             let n = mem::replace(&mut self.start, n);
951             accum = f(accum, n)?;
952         }
953 
954         self.exhausted = true;
955 
956         if self.start == self.end {
957             accum = f(accum, self.start.clone())?;
958         }
959 
960         try { accum }
961     }
962 
963     #[inline]
spec_next_back(&mut self) -> Option<A>964     default fn spec_next_back(&mut self) -> Option<A> {
965         if self.is_empty() {
966             return None;
967         }
968         let is_iterating = self.start < self.end;
969         Some(if is_iterating {
970             let n =
971                 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
972             mem::replace(&mut self.end, n)
973         } else {
974             self.exhausted = true;
975             self.end.clone()
976         })
977     }
978 
979     #[inline]
spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, A) -> R, R: Try<Output = B>,980     default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
981     where
982         Self: Sized,
983         F: FnMut(B, A) -> R,
984         R: Try<Output = B>,
985     {
986         if self.is_empty() {
987             return try { init };
988         }
989 
990         let mut accum = init;
991 
992         while self.start < self.end {
993             let n =
994                 Step::backward_checked(self.end.clone(), 1).expect("`Step` invariants not upheld");
995             let n = mem::replace(&mut self.end, n);
996             accum = f(accum, n)?;
997         }
998 
999         self.exhausted = true;
1000 
1001         if self.start == self.end {
1002             accum = f(accum, self.start.clone())?;
1003         }
1004 
1005         try { accum }
1006     }
1007 }
1008 
1009 impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> {
1010     #[inline]
spec_next(&mut self) -> Option<T>1011     fn spec_next(&mut self) -> Option<T> {
1012         if self.is_empty() {
1013             return None;
1014         }
1015         let is_iterating = self.start < self.end;
1016         Some(if is_iterating {
1017             // SAFETY: just checked precondition
1018             let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
1019             mem::replace(&mut self.start, n)
1020         } else {
1021             self.exhausted = true;
1022             self.start.clone()
1023         })
1024     }
1025 
1026     #[inline]
spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, T) -> R, R: Try<Output = B>,1027     fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
1028     where
1029         Self: Sized,
1030         F: FnMut(B, T) -> R,
1031         R: Try<Output = B>,
1032     {
1033         if self.is_empty() {
1034             return try { init };
1035         }
1036 
1037         let mut accum = init;
1038 
1039         while self.start < self.end {
1040             // SAFETY: just checked precondition
1041             let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
1042             let n = mem::replace(&mut self.start, n);
1043             accum = f(accum, n)?;
1044         }
1045 
1046         self.exhausted = true;
1047 
1048         if self.start == self.end {
1049             accum = f(accum, self.start.clone())?;
1050         }
1051 
1052         try { accum }
1053     }
1054 
1055     #[inline]
spec_next_back(&mut self) -> Option<T>1056     fn spec_next_back(&mut self) -> Option<T> {
1057         if self.is_empty() {
1058             return None;
1059         }
1060         let is_iterating = self.start < self.end;
1061         Some(if is_iterating {
1062             // SAFETY: just checked precondition
1063             let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
1064             mem::replace(&mut self.end, n)
1065         } else {
1066             self.exhausted = true;
1067             self.end.clone()
1068         })
1069     }
1070 
1071     #[inline]
spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, T) -> R, R: Try<Output = B>,1072     fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
1073     where
1074         Self: Sized,
1075         F: FnMut(B, T) -> R,
1076         R: Try<Output = B>,
1077     {
1078         if self.is_empty() {
1079             return try { init };
1080         }
1081 
1082         let mut accum = init;
1083 
1084         while self.start < self.end {
1085             // SAFETY: just checked precondition
1086             let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
1087             let n = mem::replace(&mut self.end, n);
1088             accum = f(accum, n)?;
1089         }
1090 
1091         self.exhausted = true;
1092 
1093         if self.start == self.end {
1094             accum = f(accum, self.start.clone())?;
1095         }
1096 
1097         try { accum }
1098     }
1099 }
1100 
1101 #[stable(feature = "inclusive_range", since = "1.26.0")]
1102 impl<A: Step> Iterator for ops::RangeInclusive<A> {
1103     type Item = A;
1104 
1105     #[inline]
next(&mut self) -> Option<A>1106     fn next(&mut self) -> Option<A> {
1107         self.spec_next()
1108     }
1109 
1110     #[inline]
size_hint(&self) -> (usize, Option<usize>)1111     fn size_hint(&self) -> (usize, Option<usize>) {
1112         if self.is_empty() {
1113             return (0, Some(0));
1114         }
1115 
1116         match Step::steps_between(&self.start, &self.end) {
1117             Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
1118             None => (usize::MAX, None),
1119         }
1120     }
1121 
1122     #[inline]
nth(&mut self, n: usize) -> Option<A>1123     fn nth(&mut self, n: usize) -> Option<A> {
1124         if self.is_empty() {
1125             return None;
1126         }
1127 
1128         if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
1129             use crate::cmp::Ordering::*;
1130 
1131             match plus_n.partial_cmp(&self.end) {
1132                 Some(Less) => {
1133                     self.start = Step::forward(plus_n.clone(), 1);
1134                     return Some(plus_n);
1135                 }
1136                 Some(Equal) => {
1137                     self.start = plus_n.clone();
1138                     self.exhausted = true;
1139                     return Some(plus_n);
1140                 }
1141                 _ => {}
1142             }
1143         }
1144 
1145         self.start = self.end.clone();
1146         self.exhausted = true;
1147         None
1148     }
1149 
1150     #[inline]
try_fold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>,1151     fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1152     where
1153         Self: Sized,
1154         F: FnMut(B, Self::Item) -> R,
1155         R: Try<Output = B>,
1156     {
1157         self.spec_try_fold(init, f)
1158     }
1159 
1160     impl_fold_via_try_fold! { fold -> try_fold }
1161 
1162     #[inline]
last(mut self) -> Option<A>1163     fn last(mut self) -> Option<A> {
1164         self.next_back()
1165     }
1166 
1167     #[inline]
min(mut self) -> Option<A> where A: Ord,1168     fn min(mut self) -> Option<A>
1169     where
1170         A: Ord,
1171     {
1172         self.next()
1173     }
1174 
1175     #[inline]
max(mut self) -> Option<A> where A: Ord,1176     fn max(mut self) -> Option<A>
1177     where
1178         A: Ord,
1179     {
1180         self.next_back()
1181     }
1182 
1183     #[inline]
is_sorted(self) -> bool1184     fn is_sorted(self) -> bool {
1185         true
1186     }
1187 }
1188 
1189 #[stable(feature = "inclusive_range", since = "1.26.0")]
1190 impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
1191     #[inline]
next_back(&mut self) -> Option<A>1192     fn next_back(&mut self) -> Option<A> {
1193         self.spec_next_back()
1194     }
1195 
1196     #[inline]
nth_back(&mut self, n: usize) -> Option<A>1197     fn nth_back(&mut self, n: usize) -> Option<A> {
1198         if self.is_empty() {
1199             return None;
1200         }
1201 
1202         if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
1203             use crate::cmp::Ordering::*;
1204 
1205             match minus_n.partial_cmp(&self.start) {
1206                 Some(Greater) => {
1207                     self.end = Step::backward(minus_n.clone(), 1);
1208                     return Some(minus_n);
1209                 }
1210                 Some(Equal) => {
1211                     self.end = minus_n.clone();
1212                     self.exhausted = true;
1213                     return Some(minus_n);
1214                 }
1215                 _ => {}
1216             }
1217         }
1218 
1219         self.end = self.start.clone();
1220         self.exhausted = true;
1221         None
1222     }
1223 
1224     #[inline]
try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>,1225     fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
1226     where
1227         Self: Sized,
1228         F: FnMut(B, Self::Item) -> R,
1229         R: Try<Output = B>,
1230     {
1231         self.spec_try_rfold(init, f)
1232     }
1233 
1234     impl_fold_via_try_fold! { rfold -> try_rfold }
1235 }
1236 
1237 // Safety: See above implementation for `ops::Range<A>`
1238 #[unstable(feature = "trusted_len", issue = "37572")]
1239 unsafe impl<A: TrustedStep> TrustedLen for ops::RangeInclusive<A> {}
1240 
1241 #[stable(feature = "fused", since = "1.26.0")]
1242 impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
1243