mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 22:53:28 +00:00
Use #[rustc_inherit_overflow_checks]
instead of Add::add etc.
This commit is contained in:
parent
07194ffcd2
commit
053769dd53
@ -1,6 +1,6 @@
|
||||
use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
|
||||
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
|
||||
use crate::ops::{Add, AddAssign, Try};
|
||||
use crate::ops::Try;
|
||||
|
||||
/// An iterator that yields the current count and the element during iteration.
|
||||
///
|
||||
@ -39,11 +39,11 @@ where
|
||||
///
|
||||
/// Might panic if the index of the element overflows a `usize`.
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
|
||||
let a = self.iter.next()?;
|
||||
let i = self.count;
|
||||
// Possible undefined overflow.
|
||||
AddAssign::add_assign(&mut self.count, 1);
|
||||
self.count += 1;
|
||||
Some((i, a))
|
||||
}
|
||||
|
||||
@ -53,11 +53,11 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
|
||||
let a = self.iter.nth(n)?;
|
||||
// Possible undefined overflow.
|
||||
let i = Add::add(self.count, n);
|
||||
self.count = Add::add(i, 1);
|
||||
let i = self.count + n;
|
||||
self.count = i + 1;
|
||||
Some((i, a))
|
||||
}
|
||||
|
||||
@ -78,10 +78,10 @@ where
|
||||
count: &'a mut usize,
|
||||
mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
|
||||
) -> impl FnMut(Acc, T) -> R + 'a {
|
||||
#[rustc_inherit_overflow_checks]
|
||||
move |acc, item| {
|
||||
let acc = fold(acc, (*count, item));
|
||||
// Possible undefined overflow.
|
||||
AddAssign::add_assign(count, 1);
|
||||
*count += 1;
|
||||
acc
|
||||
}
|
||||
}
|
||||
@ -99,10 +99,10 @@ where
|
||||
mut count: usize,
|
||||
mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
|
||||
) -> impl FnMut(Acc, T) -> Acc {
|
||||
#[rustc_inherit_overflow_checks]
|
||||
move |acc, item| {
|
||||
let acc = fold(acc, (count, item));
|
||||
// Possible undefined overflow.
|
||||
AddAssign::add_assign(&mut count, 1);
|
||||
count += 1;
|
||||
acc
|
||||
}
|
||||
}
|
||||
@ -110,6 +110,7 @@ where
|
||||
self.iter.fold(init, enumerate(self.count, fold))
|
||||
}
|
||||
|
||||
#[rustc_inherit_overflow_checks]
|
||||
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
|
||||
where
|
||||
Self: TrustedRandomAccess,
|
||||
@ -117,7 +118,7 @@ where
|
||||
// SAFETY: the caller must uphold the contract for
|
||||
// `Iterator::__iterator_get_unchecked`.
|
||||
let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
|
||||
(Add::add(self.count, idx), value)
|
||||
(self.count + idx, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::char;
|
||||
use crate::convert::TryFrom;
|
||||
use crate::mem;
|
||||
use crate::ops::{self, Add, Sub, Try};
|
||||
use crate::ops::{self, Try};
|
||||
|
||||
use super::{FusedIterator, TrustedLen};
|
||||
|
||||
@ -201,11 +201,12 @@ macro_rules! step_identical_methods {
|
||||
|
||||
#[inline]
|
||||
#[allow(arithmetic_overflow)]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn forward(start: Self, n: usize) -> Self {
|
||||
// In debug builds, trigger a panic on overflow.
|
||||
// This should optimize completely out in release builds.
|
||||
if Self::forward_checked(start, n).is_none() {
|
||||
let _ = Add::add(Self::MAX, 1);
|
||||
let _ = Self::MAX + 1;
|
||||
}
|
||||
// Do wrapping math to allow e.g. `Step::forward(-128i8, 255)`.
|
||||
start.wrapping_add(n as Self)
|
||||
@ -213,11 +214,12 @@ macro_rules! step_identical_methods {
|
||||
|
||||
#[inline]
|
||||
#[allow(arithmetic_overflow)]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn backward(start: Self, n: usize) -> Self {
|
||||
// In debug builds, trigger a panic on overflow.
|
||||
// This should optimize completely out in release builds.
|
||||
if Self::backward_checked(start, n).is_none() {
|
||||
let _ = Sub::sub(Self::MIN, 1);
|
||||
let _ = Self::MIN - 1;
|
||||
}
|
||||
// Do wrapping math to allow e.g. `Step::backward(127i8, 255)`.
|
||||
start.wrapping_sub(n as Self)
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::iter;
|
||||
use crate::num::Wrapping;
|
||||
use crate::ops::{Add, Mul};
|
||||
|
||||
/// Trait to represent types that can be created by summing up an iterator.
|
||||
///
|
||||
@ -37,34 +36,49 @@ pub trait Product<A = Self>: Sized {
|
||||
fn product<I: Iterator<Item = A>>(iter: I) -> Self;
|
||||
}
|
||||
|
||||
// N.B., explicitly use Add and Mul here to inherit overflow checks
|
||||
macro_rules! integer_sum_product {
|
||||
(@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
|
||||
#[$attr]
|
||||
impl Sum for $a {
|
||||
fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
|
||||
iter.fold($zero, Add::add)
|
||||
iter.fold(
|
||||
$zero,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a + b,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[$attr]
|
||||
impl Product for $a {
|
||||
fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
|
||||
iter.fold($one, Mul::mul)
|
||||
iter.fold(
|
||||
$one,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a * b,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[$attr]
|
||||
impl<'a> Sum<&'a $a> for $a {
|
||||
fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
|
||||
iter.fold($zero, Add::add)
|
||||
iter.fold(
|
||||
$zero,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a + b,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[$attr]
|
||||
impl<'a> Product<&'a $a> for $a {
|
||||
fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
|
||||
iter.fold($one, Mul::mul)
|
||||
iter.fold(
|
||||
$one,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a * b,
|
||||
)
|
||||
}
|
||||
}
|
||||
)*);
|
||||
@ -83,28 +97,44 @@ macro_rules! float_sum_product {
|
||||
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
|
||||
impl Sum for $a {
|
||||
fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
|
||||
iter.fold(0.0, Add::add)
|
||||
iter.fold(
|
||||
0.0,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a + b,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
|
||||
impl Product for $a {
|
||||
fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
|
||||
iter.fold(1.0, Mul::mul)
|
||||
iter.fold(
|
||||
1.0,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a * b,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
|
||||
impl<'a> Sum<&'a $a> for $a {
|
||||
fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
|
||||
iter.fold(0.0, Add::add)
|
||||
iter.fold(
|
||||
0.0,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a + b,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
|
||||
impl<'a> Product<&'a $a> for $a {
|
||||
fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
|
||||
iter.fold(1.0, Mul::mul)
|
||||
iter.fold(
|
||||
1.0,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|a, b| a * b,
|
||||
)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
|
@ -3,7 +3,7 @@
|
||||
// can't split that into multiple files.
|
||||
|
||||
use crate::cmp::{self, Ordering};
|
||||
use crate::ops::{Add, ControlFlow, Try};
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
use super::super::TrustedRandomAccess;
|
||||
use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
|
||||
@ -242,13 +242,11 @@ pub trait Iterator {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#[inline]
|
||||
fn add1<T>(count: usize, _: T) -> usize {
|
||||
// Might overflow.
|
||||
Add::add(count, 1)
|
||||
}
|
||||
|
||||
self.fold(0, add1)
|
||||
self.fold(
|
||||
0,
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|count, _| count + 1,
|
||||
)
|
||||
}
|
||||
|
||||
/// Consumes the iterator, returning the last element.
|
||||
@ -2475,13 +2473,9 @@ pub trait Iterator {
|
||||
fn check<T>(
|
||||
mut predicate: impl FnMut(T) -> bool,
|
||||
) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
|
||||
// The addition might panic on overflow
|
||||
#[rustc_inherit_overflow_checks]
|
||||
move |i, x| {
|
||||
if predicate(x) {
|
||||
ControlFlow::Break(i)
|
||||
} else {
|
||||
ControlFlow::Continue(Add::add(i, 1))
|
||||
}
|
||||
if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i + 1) }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user