Skip to content

Commit d3b94c4

Browse files
authored
Rollup merge of rust-lang#148703 - pitaj:rangefrom-overflow_checks, r=Mark-Simulacrum
Use `overflow_checks` intrinsic so `IterRangeFrom` yields MAX before panicking in debug Based on rust-lang#128666. For your convenience, here is the [diff from that PR](pitaj/rust@intrinsic-overflow_checks...pitaj:rust:rangefrom-overflow_checks). When `overflow_checks` are enabled, the following code will output as shown ```rust for n in std::range::RangeFrom::from(253_u8..) { println!("{n}"); } // 253 // 254 // 255 // panic ``` Which is a change from the current behavior, where it will panic after printing 254. This behavior was [requested by the libs team](rust-lang#125687 (comment)) r? `@Mark-Simulacrum`
2 parents 0860ad8 + f7e9a77 commit d3b94c4

File tree

1 file changed

+52
-9
lines changed

1 file changed

+52
-9
lines changed

core/src/range/iter.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::iter::{
33
};
44
use crate::num::NonZero;
55
use crate::range::{Range, RangeFrom, RangeInclusive, legacy};
6+
use crate::{intrinsics, mem};
67

78
/// By-value [`Range`] iterator.
89
#[unstable(feature = "new_range_api", issue = "125687")]
@@ -168,7 +169,7 @@ impl<A: Step> IterRangeInclusive<A> {
168169
}
169170
}
170171

171-
#[unstable(feature = "trusted_random_access", issue = "none")]
172+
#[unstable(feature = "new_range_api", issue = "125687")]
172173
impl<A: Step> Iterator for IterRangeInclusive<A> {
173174
type Item = A;
174175

@@ -293,32 +294,74 @@ range_incl_exact_iter_impl! {
293294
/// By-value [`RangeFrom`] iterator.
294295
#[unstable(feature = "new_range_api", issue = "125687")]
295296
#[derive(Debug, Clone)]
296-
pub struct IterRangeFrom<A>(legacy::RangeFrom<A>);
297+
pub struct IterRangeFrom<A> {
298+
start: A,
299+
/// Whether the first element of the iterator has yielded.
300+
/// Only used when overflow checks are enabled.
301+
first: bool,
302+
}
297303

298-
impl<A> IterRangeFrom<A> {
304+
impl<A: Step> IterRangeFrom<A> {
299305
/// Returns the remainder of the range being iterated over.
306+
#[inline]
307+
#[rustc_inherit_overflow_checks]
300308
pub fn remainder(self) -> RangeFrom<A> {
301-
RangeFrom { start: self.0.start }
309+
if intrinsics::overflow_checks() {
310+
if !self.first {
311+
return RangeFrom { start: Step::forward(self.start, 1) };
312+
}
313+
}
314+
315+
RangeFrom { start: self.start }
302316
}
303317
}
304318

305-
#[unstable(feature = "trusted_random_access", issue = "none")]
319+
#[unstable(feature = "new_range_api", issue = "125687")]
306320
impl<A: Step> Iterator for IterRangeFrom<A> {
307321
type Item = A;
308322

309323
#[inline]
324+
#[rustc_inherit_overflow_checks]
310325
fn next(&mut self) -> Option<A> {
311-
self.0.next()
326+
if intrinsics::overflow_checks() {
327+
if self.first {
328+
self.first = false;
329+
return Some(self.start.clone());
330+
}
331+
332+
self.start = Step::forward(self.start.clone(), 1);
333+
return Some(self.start.clone());
334+
}
335+
336+
let n = Step::forward(self.start.clone(), 1);
337+
Some(mem::replace(&mut self.start, n))
312338
}
313339

314340
#[inline]
315341
fn size_hint(&self) -> (usize, Option<usize>) {
316-
self.0.size_hint()
342+
(usize::MAX, None)
317343
}
318344

319345
#[inline]
346+
#[rustc_inherit_overflow_checks]
320347
fn nth(&mut self, n: usize) -> Option<A> {
321-
self.0.nth(n)
348+
if intrinsics::overflow_checks() {
349+
if self.first {
350+
self.first = false;
351+
352+
let plus_n = Step::forward(self.start.clone(), n);
353+
self.start = plus_n.clone();
354+
return Some(plus_n);
355+
}
356+
357+
let plus_n = Step::forward(self.start.clone(), n);
358+
self.start = Step::forward(plus_n.clone(), 1);
359+
return Some(self.start.clone());
360+
}
361+
362+
let plus_n = Step::forward(self.start.clone(), n);
363+
self.start = Step::forward(plus_n.clone(), 1);
364+
Some(plus_n)
322365
}
323366
}
324367

@@ -334,6 +377,6 @@ impl<A: Step> IntoIterator for RangeFrom<A> {
334377
type IntoIter = IterRangeFrom<A>;
335378

336379
fn into_iter(self) -> Self::IntoIter {
337-
IterRangeFrom(self.into())
380+
IterRangeFrom { start: self.start, first: true }
338381
}
339382
}

0 commit comments

Comments
 (0)