@@ -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