@@ -8,9 +8,18 @@ use crate::convert::Infallible;
8
8
use crate::fmt;
9
9
use crate::intrinsics;
10
10
use crate::mem;
11
- use crate::ops;
12
11
use crate::str::FromStr;
13
12
13
+ // Used because the `?` operator is not allowed in a const context.
14
+ macro_rules! try_opt {
15
+ ($e:expr) => {
16
+ match $e {
17
+ Some(x) => x,
18
+ None => return None,
19
+ }
20
+ };
21
+ }
22
+
14
23
macro_rules! impl_nonzero_fmt {
15
24
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
16
25
$(
@@ -993,26 +1002,27 @@ $EndFeature, "
993
1002
```"),
994
1003
995
1004
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1005
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
996
1006
#[must_use = "this returns the result of the operation, \
997
1007
without modifying the original"]
998
1008
#[inline]
999
- pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
1009
+ pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
1000
1010
let mut base = self;
1001
1011
let mut acc: Self = 1;
1002
1012
1003
1013
while exp > 1 {
1004
1014
if (exp & 1) == 1 {
1005
- acc = acc.checked_mul(base)? ;
1015
+ acc = try_opt!( acc.checked_mul(base)) ;
1006
1016
}
1007
1017
exp /= 2;
1008
- base = base.checked_mul(base)? ;
1018
+ base = try_opt!( base.checked_mul(base)) ;
1009
1019
}
1010
1020
1011
1021
// Deal with the final bit of the exponent separately, since
1012
1022
// squaring the base afterwards is not necessary and may cause a
1013
1023
// needless overflow.
1014
1024
if exp == 1 {
1015
- acc = acc.checked_mul(base)? ;
1025
+ acc = try_opt!( acc.checked_mul(base)) ;
1016
1026
}
1017
1027
1018
1028
Some(acc)
@@ -1180,10 +1190,11 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT
1180
1190
$EndFeature, "
1181
1191
```"),
1182
1192
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1193
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
1183
1194
#[must_use = "this returns the result of the operation, \
1184
1195
without modifying the original"]
1185
1196
#[inline]
1186
- pub fn saturating_pow(self, exp: u32) -> Self {
1197
+ pub const fn saturating_pow(self, exp: u32) -> Self {
1187
1198
match self.checked_pow(exp) {
1188
1199
Some(x) => x,
1189
1200
None if self < 0 && exp % 2 == 1 => Self::min_value(),
@@ -1523,10 +1534,11 @@ assert_eq!(3i8.wrapping_pow(6), -39);",
1523
1534
$EndFeature, "
1524
1535
```"),
1525
1536
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1537
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
1526
1538
#[must_use = "this returns the result of the operation, \
1527
1539
without modifying the original"]
1528
1540
#[inline]
1529
- pub fn wrapping_pow(self, mut exp: u32) -> Self {
1541
+ pub const fn wrapping_pow(self, mut exp: u32) -> Self {
1530
1542
let mut base = self;
1531
1543
let mut acc: Self = 1;
1532
1544
@@ -1900,10 +1912,11 @@ assert_eq!(3i8.overflowing_pow(5), (-13, true));",
1900
1912
$EndFeature, "
1901
1913
```"),
1902
1914
#[stable(feature = "no_panic_pow", since = "1.34.0")]
1915
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
1903
1916
#[must_use = "this returns the result of the operation, \
1904
1917
without modifying the original"]
1905
1918
#[inline]
1906
- pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
1919
+ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
1907
1920
let mut base = self;
1908
1921
let mut acc: Self = 1;
1909
1922
let mut overflown = false;
@@ -1949,11 +1962,12 @@ assert_eq!(x.pow(5), 32);",
1949
1962
$EndFeature, "
1950
1963
```"),
1951
1964
#[stable(feature = "rust1", since = "1.0.0")]
1965
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
1952
1966
#[must_use = "this returns the result of the operation, \
1953
1967
without modifying the original"]
1954
1968
#[inline]
1955
1969
#[rustc_inherit_overflow_checks]
1956
- pub fn pow(self, mut exp: u32) -> Self {
1970
+ pub const fn pow(self, mut exp: u32) -> Self {
1957
1971
let mut base = self;
1958
1972
let mut acc = 1;
1959
1973
@@ -3119,26 +3133,27 @@ Basic usage:
3119
3133
assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, "
3120
3134
```"),
3121
3135
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3136
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
3122
3137
#[must_use = "this returns the result of the operation, \
3123
3138
without modifying the original"]
3124
3139
#[inline]
3125
- pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
3140
+ pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
3126
3141
let mut base = self;
3127
3142
let mut acc: Self = 1;
3128
3143
3129
3144
while exp > 1 {
3130
3145
if (exp & 1) == 1 {
3131
- acc = acc.checked_mul(base)? ;
3146
+ acc = try_opt!( acc.checked_mul(base)) ;
3132
3147
}
3133
3148
exp /= 2;
3134
- base = base.checked_mul(base)? ;
3149
+ base = try_opt!( base.checked_mul(base)) ;
3135
3150
}
3136
3151
3137
3152
// Deal with the final bit of the exponent separately, since
3138
3153
// squaring the base afterwards is not necessary and may cause a
3139
3154
// needless overflow.
3140
3155
if exp == 1 {
3141
- acc = acc.checked_mul(base)? ;
3156
+ acc = try_opt!( acc.checked_mul(base)) ;
3142
3157
}
3143
3158
3144
3159
Some(acc)
@@ -3234,10 +3249,11 @@ assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT
3234
3249
$EndFeature, "
3235
3250
```"),
3236
3251
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3252
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
3237
3253
#[must_use = "this returns the result of the operation, \
3238
3254
without modifying the original"]
3239
3255
#[inline]
3240
- pub fn saturating_pow(self, exp: u32) -> Self {
3256
+ pub const fn saturating_pow(self, exp: u32) -> Self {
3241
3257
match self.checked_pow(exp) {
3242
3258
Some(x) => x,
3243
3259
None => Self::max_value(),
@@ -3527,10 +3543,11 @@ Basic usage:
3527
3543
assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
3528
3544
```"),
3529
3545
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3546
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
3530
3547
#[must_use = "this returns the result of the operation, \
3531
3548
without modifying the original"]
3532
3549
#[inline]
3533
- pub fn wrapping_pow(self, mut exp: u32) -> Self {
3550
+ pub const fn wrapping_pow(self, mut exp: u32) -> Self {
3534
3551
let mut base = self;
3535
3552
let mut acc: Self = 1;
3536
3553
@@ -3853,10 +3870,11 @@ Basic usage:
3853
3870
assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
3854
3871
```"),
3855
3872
#[stable(feature = "no_panic_pow", since = "1.34.0")]
3873
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
3856
3874
#[must_use = "this returns the result of the operation, \
3857
3875
without modifying the original"]
3858
3876
#[inline]
3859
- pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
3877
+ pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
3860
3878
let mut base = self;
3861
3879
let mut acc: Self = 1;
3862
3880
let mut overflown = false;
@@ -3899,11 +3917,12 @@ Basic usage:
3899
3917
", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
3900
3918
```"),
3901
3919
#[stable(feature = "rust1", since = "1.0.0")]
3920
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
3902
3921
#[must_use = "this returns the result of the operation, \
3903
3922
without modifying the original"]
3904
3923
#[inline]
3905
3924
#[rustc_inherit_overflow_checks]
3906
- pub fn pow(self, mut exp: u32) -> Self {
3925
+ pub const fn pow(self, mut exp: u32) -> Self {
3907
3926
let mut base = self;
3908
3927
let mut acc = 1;
3909
3928
@@ -4014,7 +4033,8 @@ assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
4014
4033
// overflow cases it instead ends up returning the maximum value
4015
4034
// of the type, and can return 0 for 0.
4016
4035
#[inline]
4017
- fn one_less_than_next_power_of_two(self) -> Self {
4036
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4037
+ const fn one_less_than_next_power_of_two(self) -> Self {
4018
4038
if self <= 1 { return 0; }
4019
4039
4020
4040
let p = self - 1;
@@ -4042,10 +4062,11 @@ Basic usage:
4042
4062
assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, "
4043
4063
```"),
4044
4064
#[stable(feature = "rust1", since = "1.0.0")]
4065
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4045
4066
#[inline]
4046
- pub fn next_power_of_two(self) -> Self {
4047
- // Call the trait to get overflow checks
4048
- ops::Add::add( self.one_less_than_next_power_of_two(), 1)
4067
+ #[rustc_inherit_overflow_checks]
4068
+ pub const fn next_power_of_two(self) -> Self {
4069
+ self.one_less_than_next_power_of_two() + 1
4049
4070
}
4050
4071
}
4051
4072
@@ -4067,7 +4088,8 @@ $EndFeature, "
4067
4088
```"),
4068
4089
#[inline]
4069
4090
#[stable(feature = "rust1", since = "1.0.0")]
4070
- pub fn checked_next_power_of_two(self) -> Option<Self> {
4091
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4092
+ pub const fn checked_next_power_of_two(self) -> Option<Self> {
4071
4093
self.one_less_than_next_power_of_two().checked_add(1)
4072
4094
}
4073
4095
}
@@ -4091,7 +4113,8 @@ $EndFeature, "
4091
4113
```"),
4092
4114
#[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
4093
4115
reason = "needs decision on wrapping behaviour")]
4094
- pub fn wrapping_next_power_of_two(self) -> Self {
4116
+ #[rustc_const_unstable(feature = "const_int_pow", issue = "53718")]
4117
+ pub const fn wrapping_next_power_of_two(self) -> Self {
4095
4118
self.one_less_than_next_power_of_two().wrapping_add(1)
4096
4119
}
4097
4120
}
0 commit comments