-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use #[rustc_inherit_overflow_checks]
instead of Add::add etc.
#81732
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
Comment on lines
+46
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hah, does this work? I half-expected it not to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haha, this was your suggestion.. But yeah, it compiles. I think it works too, but I should check if it actually gets tested for this behaviour. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I was going off having seen |
||
) | ||
} | ||
} | ||
|
||
#[$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, | ||
) | ||
} | ||
} | ||
)*) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, so I initially thought "this seems wrong, don't we need it on the
fn sum
too? But it looks like in practice inherit is a bit wrong - this attribute just forces the MIR to contain overflow checks in all cases, and then when we codegen (potentially in a downstream crate) they'll get removed. So I think we're good -- not sure what a better name for the attribute is, but inherit definitely feels a bit off.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the
inherit
here is about crates rather than functions, in some sense.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, "inherit" refers to the crate it's codegen'd in. So it's more "defer"? Or we can go more explicit really:
#[rustc_use_overflow_checks_settings_from_user_crate]
We could also make the attribute warn/error if building the MIR doesn't end up making a decision based on it, because that's what usually happens if it's applied to the wrong thing (e.g. a function doing
iter.fold(...)
instead of a closure).