From 053769dd53b403e2723a56a9b0cdc8bff7814dcc Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 4 Feb 2021 00:20:08 +0100 Subject: [PATCH] Use `#[rustc_inherit_overflow_checks]` instead of Add::add etc. --- library/core/src/iter/adapters/enumerate.rs | 23 +++++----- library/core/src/iter/range.rs | 8 ++-- library/core/src/iter/traits/accum.rs | 50 ++++++++++++++++----- library/core/src/iter/traits/iterator.rs | 22 ++++----- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 5978c2da98c35..7522bb02c3dc0 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -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, ::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) -> ::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) } } diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 9e7055a370c9d..cc80e06decd48 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -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) diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs index dc0d8087ffbff..0a4210a78e3af 100644 --- a/library/core/src/iter/traits/accum.rs +++ b/library/core/src/iter/traits/accum.rs @@ -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: Sized { fn product>(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>(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>(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>(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>(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>(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>(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>(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>(iter: I) -> Self { - iter.fold(1.0, Mul::mul) + iter.fold( + 1.0, + #[rustc_inherit_overflow_checks] + |a, b| a * b, + ) } } )*) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 5faa4b825605f..f2249db12264f 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -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(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( mut predicate: impl FnMut(T) -> bool, ) -> impl FnMut(usize, T) -> ControlFlow { - // 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) } } }