Skip to content

Commit 63fecad

Browse files
committed
Inherit overflow checks for sum and product
1 parent f1f40f8 commit 63fecad

File tree

4 files changed

+69
-14
lines changed

4 files changed

+69
-14
lines changed

src/libcore/iter/iterator.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1867,7 +1867,8 @@ pub trait Iterator {
18671867
/// # Panics
18681868
///
18691869
/// When calling `sum` and a primitive integer type is being returned, this
1870-
/// method will panic if the computation overflows.
1870+
/// method will panic if the computation overflows and debug assertions are
1871+
/// enabled.
18711872
///
18721873
/// # Examples
18731874
///
@@ -1894,7 +1895,8 @@ pub trait Iterator {
18941895
/// # Panics
18951896
///
18961897
/// When calling `product` and a primitive integer type is being returned,
1897-
/// this method will panic if the computation overflows.
1898+
/// method will panic if the computation overflows and debug assertions are
1899+
/// enabled.
18981900
///
18991901
/// # Examples
19001902
///

src/libcore/iter/traits.rs

+7-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10+
use ops::{Mul, Add};
1011

1112
/// Conversion from an `Iterator`.
1213
///
@@ -581,41 +582,35 @@ pub trait Product<A = Self>: Sized {
581582
fn product<I: Iterator<Item=A>>(iter: I) -> Self;
582583
}
583584

585+
// NB: explicitly use Add and Mul here to inherit overflow checks
584586
macro_rules! integer_sum_product {
585587
($($a:ident)*) => ($(
586588
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
587589
impl Sum for $a {
590+
#[rustc_inherit_overflow_checks]
588591
fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
589-
iter.fold(0, |a, b| {
590-
a.checked_add(b).expect("overflow in sum")
591-
})
592+
iter.fold(0, Add::add)
592593
}
593594
}
594595

595596
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
596597
impl Product for $a {
597598
fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
598-
iter.fold(1, |a, b| {
599-
a.checked_mul(b).expect("overflow in product")
600-
})
599+
iter.fold(1, Mul::mul)
601600
}
602601
}
603602

604603
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
605604
impl<'a> Sum<&'a $a> for $a {
606605
fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
607-
iter.fold(0, |a, b| {
608-
a.checked_add(*b).expect("overflow in sum")
609-
})
606+
iter.cloned().fold(0, Add::add)
610607
}
611608
}
612609

613610
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
614611
impl<'a> Product<&'a $a> for $a {
615612
fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
616-
iter.fold(1, |a, b| {
617-
a.checked_mul(*b).expect("overflow in product")
618-
})
613+
iter.cloned().fold(1, Mul::mul)
619614
}
620615
}
621616
)*)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -C debug_assertions=yes
12+
13+
use std::panic;
14+
15+
fn main() {
16+
let r = panic::catch_unwind(|| {
17+
[1, i32::max_value()].iter().sum::<i32>();
18+
});
19+
assert!(r.is_err());
20+
21+
let r = panic::catch_unwind(|| {
22+
[2, i32::max_value()].iter().product::<i32>();
23+
});
24+
assert!(r.is_err());
25+
26+
let r = panic::catch_unwind(|| {
27+
[1, i32::max_value()].iter().cloned().sum::<i32>();
28+
});
29+
assert!(r.is_err());
30+
31+
let r = panic::catch_unwind(|| {
32+
[2, i32::max_value()].iter().cloned().product::<i32>();
33+
});
34+
assert!(r.is_err());
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -C debug_assertions=no
12+
13+
fn main() {
14+
assert_eq!([1i32, i32::max_value()].iter().sum::<i32>(),
15+
1i32.wrapping_add(i32::max_value()));
16+
assert_eq!([2i32, i32::max_value()].iter().product::<i32>(),
17+
2i32.wrapping_mul(i32::max_value()));
18+
19+
assert_eq!([1i32, i32::max_value()].iter().cloned().sum::<i32>(),
20+
1i32.wrapping_add(i32::max_value()));
21+
assert_eq!([2i32, i32::max_value()].iter().cloned().product::<i32>(),
22+
2i32.wrapping_mul(i32::max_value()));
23+
}

0 commit comments

Comments
 (0)