Skip to content

Commit

Permalink
Rollup merge of #89876 - AlexApps99:const_ops, r=oli-obk
Browse files Browse the repository at this point in the history
Make most std::ops traits const on numeric types

This PR makes existing implementations of `std::ops` traits (`Add`, `Sub`, etc) [`impl const`](#67792) where possible.
This affects:
- All numeric primitives (`u*`, `i*`, `f*`)
- `NonZero*`
- `Wrapping`

This is under the `rustc_const_unstable` feature `const_ops`.
I will write tests once I know what can and can't be kept for the final version of this PR.

Since this is my first PR to rustc (and hopefully one of many), please give me feedback on how to better handle the PR process wherever possible. Thanks

[Zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Const.20std.3A.3Aops.20traits.20PR)
  • Loading branch information
matthiaskrgr committed Oct 30, 2021
2 parents 2b643e9 + 361c978 commit 20bb932
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 106 deletions.
71 changes: 71 additions & 0 deletions library/core/src/internal_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ macro_rules! forward_ref_unop {
forward_ref_unop!(impl $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl const $imp:ident, $method:ident for $t:ty) => {
forward_ref_unop!(impl const $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
};
// Equivalent to the non-const version, with the addition of `rustc_const_unstable`
(impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
#[$attr]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const $imp for &$t {
type Output = <$t as $imp>::Output;

#[inline]
fn $method(self) -> <$t as $imp>::Output {
$imp::$method(*self)
}
}
};
(impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
#[$attr]
impl $imp for &$t {
Expand All @@ -25,6 +42,45 @@ macro_rules! forward_ref_binop {
forward_ref_binop!(impl $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl const $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_binop!(impl const $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
};
// Equivalent to the non-const version, with the addition of `rustc_const_unstable`
(impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl<'a> const $imp<$u> for &'a $t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, other)
}
}

#[$attr]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(self, *other)
}
}

#[$attr]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, *other)
}
}
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<$u> for &'a $t {
Expand Down Expand Up @@ -65,6 +121,21 @@ macro_rules! forward_ref_op_assign {
forward_ref_op_assign!(impl $imp, $method for $t, $u,
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
};
(impl const $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_op_assign!(impl const $imp, $method for $t, $u,
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
};
// Equivalent to the non-const version, with the addition of `rustc_const_unstable`
(impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const $imp<&$u> for $t {
#[inline]
fn $method(&mut self, other: &$u) {
$imp::$method(self, *other);
}
}
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl $imp<&$u> for $t {
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
#![feature(const_maybe_uninit_as_ptr)]
#![feature(const_maybe_uninit_assume_init)]
#![feature(const_num_from_num)]
#![feature(const_ops)]
#![feature(const_option)]
#![feature(const_pin)]
#![feature(const_replace)]
Expand Down
21 changes: 14 additions & 7 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ macro_rules! nonzero_integers {
}

#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOr for $Ty {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOr for $Ty {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self::Output {
Expand All @@ -103,7 +104,8 @@ macro_rules! nonzero_integers {
}

#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOr<$Int> for $Ty {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOr<$Int> for $Ty {
type Output = Self;
#[inline]
fn bitor(self, rhs: $Int) -> Self::Output {
Expand All @@ -115,7 +117,8 @@ macro_rules! nonzero_integers {
}

#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOr<$Ty> for $Int {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOr<$Ty> for $Int {
type Output = $Ty;
#[inline]
fn bitor(self, rhs: $Ty) -> Self::Output {
Expand All @@ -127,15 +130,17 @@ macro_rules! nonzero_integers {
}

#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOrAssign for $Ty {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOrAssign for $Ty {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
*self = *self | rhs;
}
}

#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOrAssign<$Int> for $Ty {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOrAssign<$Int> for $Ty {
#[inline]
fn bitor_assign(&mut self, rhs: $Int) {
*self = *self | rhs;
Expand Down Expand Up @@ -257,7 +262,8 @@ macro_rules! nonzero_integers_div {
( $( $Ty: ident($Int: ty); )+ ) => {
$(
#[stable(feature = "nonzero_div", since = "1.51.0")]
impl Div<$Ty> for $Int {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Div<$Ty> for $Int {
type Output = $Int;
/// This operation rounds towards zero,
/// truncating any fractional part of the exact result, and cannot panic.
Expand All @@ -270,7 +276,8 @@ macro_rules! nonzero_integers_div {
}

#[stable(feature = "nonzero_div", since = "1.51.0")]
impl Rem<$Ty> for $Int {
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Rem<$Ty> for $Int {
type Output = $Int;
/// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
#[inline]
Expand Down
Loading

0 comments on commit 20bb932

Please sign in to comment.