@@ -1374,59 +1374,26 @@ macro_rules! int_impl {
13741374 #[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
13751375 #[ must_use = "this returns the result of the operation, \
13761376 without modifying the original"]
1377- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
13781377 #[ inline]
13791378 pub const fn checked_pow( self , mut exp: u32 ) -> Option <Self > {
1380- // SAFETY: This path has the same behavior as the other.
1381- if unsafe { intrinsics:: is_val_statically_known( self ) }
1382- && self . unsigned_abs( ) . is_power_of_two( )
1383- {
1384- if self == 1 { // Avoid divide by zero
1385- return Some ( 1 ) ;
1386- }
1387- if self == -1 { // Avoid divide by zero
1388- return Some ( if exp & 1 != 0 { -1 } else { 1 } ) ;
1389- }
1390- // SAFETY: We just checked this is a power of two. and above zero.
1391- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
1392- if exp > Self :: BITS / power_used { return None ; } // Division of constants is free
1393-
1394- // SAFETY: exp <= Self::BITS / power_used
1395- let res = unsafe { intrinsics:: unchecked_shl(
1396- 1 as Self ,
1397- intrinsics:: unchecked_mul( power_used, exp) as Self
1398- ) } ;
1399- // LLVM doesn't always optimize out the checks
1400- // at the ir level.
1401-
1402- let sign = self . is_negative( ) && exp & 1 != 0 ;
1403- if !sign && res == Self :: MIN {
1404- None
1405- } else if sign {
1406- Some ( res. wrapping_neg( ) )
1407- } else {
1408- Some ( res)
1409- }
1410- } else {
1411- if exp == 0 {
1412- return Some ( 1 ) ;
1413- }
1414- let mut base = self ;
1415- let mut acc: Self = 1 ;
1416-
1417- while exp > 1 {
1418- if ( exp & 1 ) == 1 {
1419- acc = try_opt!( acc. checked_mul( base) ) ;
1420- }
1421- exp /= 2 ;
1422- base = try_opt!( base. checked_mul( base) ) ;
1379+ if exp == 0 {
1380+ return Some ( 1 ) ;
1381+ }
1382+ let mut base = self ;
1383+ let mut acc: Self = 1 ;
1384+
1385+ while exp > 1 {
1386+ if ( exp & 1 ) == 1 {
1387+ acc = try_opt!( acc. checked_mul( base) ) ;
14231388 }
1424- // since exp!=0, finally the exp must be 1.
1425- // Deal with the final bit of the exponent separately, since
1426- // squaring the base afterwards is not necessary and may cause a
1427- // needless overflow.
1428- acc. checked_mul( base)
1389+ exp /= 2 ;
1390+ base = try_opt!( base. checked_mul( base) ) ;
14291391 }
1392+ // since exp!=0, finally the exp must be 1.
1393+ // Deal with the final bit of the exponent separately, since
1394+ // squaring the base afterwards is not necessary and may cause a
1395+ // needless overflow.
1396+ acc. checked_mul( base)
14301397 }
14311398
14321399 /// Strict exponentiation. Computes `self.pow(exp)`, panicking if
@@ -2091,58 +2058,27 @@ macro_rules! int_impl {
20912058 #[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
20922059 #[ must_use = "this returns the result of the operation, \
20932060 without modifying the original"]
2094- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
20952061 #[ inline]
20962062 pub const fn wrapping_pow( self , mut exp: u32 ) -> Self {
2097- // SAFETY: This path has the same behavior as the other.
2098- if unsafe { intrinsics:: is_val_statically_known( self ) }
2099- && self . unsigned_abs( ) . is_power_of_two( )
2100- {
2101- if self == 1 { // Avoid divide by zero
2102- return 1 ;
2103- }
2104- if self == -1 { // Avoid divide by zero
2105- return if exp & 1 != 0 { -1 } else { 1 } ;
2106- }
2107- // SAFETY: We just checked this is a power of two. and above zero.
2108- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
2109- if exp > Self :: BITS / power_used { return 0 ; } // Division of constants is free
2110-
2111- // SAFETY: exp <= Self::BITS / power_used
2112- let res = unsafe { intrinsics:: unchecked_shl(
2113- 1 as Self ,
2114- intrinsics:: unchecked_mul( power_used, exp) as Self
2115- ) } ;
2116- // LLVM doesn't always optimize out the checks
2117- // at the ir level.
2118-
2119- let sign = self . is_negative( ) && exp & 1 != 0 ;
2120- if sign {
2121- res. wrapping_neg( )
2122- } else {
2123- res
2124- }
2125- } else {
2126- if exp == 0 {
2127- return 1 ;
2128- }
2129- let mut base = self ;
2130- let mut acc: Self = 1 ;
2131-
2132- while exp > 1 {
2133- if ( exp & 1 ) == 1 {
2134- acc = acc. wrapping_mul( base) ;
2135- }
2136- exp /= 2 ;
2137- base = base. wrapping_mul( base) ;
2138- }
2063+ if exp == 0 {
2064+ return 1 ;
2065+ }
2066+ let mut base = self ;
2067+ let mut acc: Self = 1 ;
21392068
2140- // since exp!=0, finally the exp must be 1.
2141- // Deal with the final bit of the exponent separately, since
2142- // squaring the base afterwards is not necessary and may cause a
2143- // needless overflow.
2144- acc. wrapping_mul( base)
2069+ while exp > 1 {
2070+ if ( exp & 1 ) == 1 {
2071+ acc = acc. wrapping_mul( base) ;
2072+ }
2073+ exp /= 2 ;
2074+ base = base. wrapping_mul( base) ;
21452075 }
2076+
2077+ // since exp!=0, finally the exp must be 1.
2078+ // Deal with the final bit of the exponent separately, since
2079+ // squaring the base afterwards is not necessary and may cause a
2080+ // needless overflow.
2081+ acc. wrapping_mul( base)
21462082 }
21472083
21482084 /// Calculates `self` + `rhs`
@@ -2625,68 +2561,36 @@ macro_rules! int_impl {
26252561 #[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
26262562 #[ must_use = "this returns the result of the operation, \
26272563 without modifying the original"]
2628- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
26292564 #[ inline]
26302565 pub const fn overflowing_pow( self , mut exp: u32 ) -> ( Self , bool ) {
2631- // SAFETY: This path has the same behavior as the other.
2632- if unsafe { intrinsics:: is_val_statically_known( self ) }
2633- && self . unsigned_abs( ) . is_power_of_two( )
2634- {
2635- if self == 1 { // Avoid divide by zero
2636- return ( 1 , false ) ;
2637- }
2638- if self == -1 { // Avoid divide by zero
2639- return ( if exp & 1 != 0 { -1 } else { 1 } , false ) ;
2640- }
2641- // SAFETY: We just checked this is a power of two. and above zero.
2642- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
2643- if exp > Self :: BITS / power_used { return ( 0 , true ) ; } // Division of constants is free
2644-
2645- // SAFETY: exp <= Self::BITS / power_used
2646- let res = unsafe { intrinsics:: unchecked_shl(
2647- 1 as Self ,
2648- intrinsics:: unchecked_mul( power_used, exp) as Self
2649- ) } ;
2650- // LLVM doesn't always optimize out the checks
2651- // at the ir level.
2652-
2653- let sign = self . is_negative( ) && exp & 1 != 0 ;
2654- let overflow = res == Self :: MIN ;
2655- if sign {
2656- ( res. wrapping_neg( ) , overflow)
2657- } else {
2658- ( res, overflow)
2659- }
2660- } else {
2661- if exp == 0 {
2662- return ( 1 , false ) ;
2663- }
2664- let mut base = self ;
2665- let mut acc: Self = 1 ;
2666- let mut overflown = false ;
2667- // Scratch space for storing results of overflowing_mul.
2668- let mut r;
2669-
2670- while exp > 1 {
2671- if ( exp & 1 ) == 1 {
2672- r = acc. overflowing_mul( base) ;
2673- acc = r. 0 ;
2674- overflown |= r. 1 ;
2675- }
2676- exp /= 2 ;
2677- r = base. overflowing_mul( base) ;
2678- base = r. 0 ;
2566+ if exp == 0 {
2567+ return ( 1 , false ) ;
2568+ }
2569+ let mut base = self ;
2570+ let mut acc: Self = 1 ;
2571+ let mut overflown = false ;
2572+ // Scratch space for storing results of overflowing_mul.
2573+ let mut r;
2574+
2575+ while exp > 1 {
2576+ if ( exp & 1 ) == 1 {
2577+ r = acc. overflowing_mul( base) ;
2578+ acc = r. 0 ;
26792579 overflown |= r. 1 ;
26802580 }
2681-
2682- // since exp!=0, finally the exp must be 1.
2683- // Deal with the final bit of the exponent separately, since
2684- // squaring the base afterwards is not necessary and may cause a
2685- // needless overflow.
2686- r = acc. overflowing_mul( base) ;
2687- r. 1 |= overflown;
2688- r
2581+ exp /= 2 ;
2582+ r = base. overflowing_mul( base) ;
2583+ base = r. 0 ;
2584+ overflown |= r. 1 ;
26892585 }
2586+
2587+ // since exp!=0, finally the exp must be 1.
2588+ // Deal with the final bit of the exponent separately, since
2589+ // squaring the base afterwards is not necessary and may cause a
2590+ // needless overflow.
2591+ r = acc. overflowing_mul( base) ;
2592+ r. 1 |= overflown;
2593+ r
26902594 }
26912595
26922596 /// Raises self to the power of `exp`, using exponentiation by squaring.
@@ -2704,68 +2608,28 @@ macro_rules! int_impl {
27042608 #[ rustc_const_stable( feature = "const_int_pow" , since = "1.50.0" ) ]
27052609 #[ must_use = "this returns the result of the operation, \
27062610 without modifying the original"]
2707- #[ rustc_allow_const_fn_unstable( is_val_statically_known, const_int_unchecked_arith) ]
27082611 #[ inline]
27092612 #[ rustc_inherit_overflow_checks]
2710- #[ track_caller] // Hides the hackish overflow check for powers of two.
27112613 pub const fn pow( self , mut exp: u32 ) -> Self {
2712- // SAFETY: This path has the same behavior as the other.
2713- if unsafe { intrinsics:: is_val_statically_known( self ) }
2714- && self . unsigned_abs( ) . is_power_of_two( )
2715- {
2716- if self == 1 { // Avoid divide by zero
2717- return 1 ;
2718- }
2719- if self == -1 { // Avoid divide by zero
2720- return if exp & 1 != 0 { -1 } else { 1 } ;
2721- }
2722- // SAFETY: We just checked this is a power of two. and above zero.
2723- let power_used = unsafe { intrinsics:: cttz_nonzero( self . wrapping_abs( ) ) as u32 } ;
2724- if exp > Self :: BITS / power_used { // Division of constants is free
2725- #[ allow( arithmetic_overflow) ]
2726- return Self :: MAX * Self :: MAX * 0 ;
2727- }
2614+ if exp == 0 {
2615+ return 1 ;
2616+ }
2617+ let mut base = self ;
2618+ let mut acc = 1 ;
27282619
2729- // SAFETY: exp <= Self::BITS / power_used
2730- let res = unsafe { intrinsics:: unchecked_shl(
2731- 1 as Self ,
2732- intrinsics:: unchecked_mul( power_used, exp) as Self
2733- ) } ;
2734- // LLVM doesn't always optimize out the checks
2735- // at the ir level.
2736-
2737- let sign = self . is_negative( ) && exp & 1 != 0 ;
2738- #[ allow( arithmetic_overflow) ]
2739- if !sign && res == Self :: MIN {
2740- // So it panics.
2741- _ = Self :: MAX * Self :: MAX ;
2742- }
2743- if sign {
2744- res. wrapping_neg( )
2745- } else {
2746- res
2747- }
2748- } else {
2749- if exp == 0 {
2750- return 1 ;
2751- }
2752- let mut base = self ;
2753- let mut acc = 1 ;
2754-
2755- while exp > 1 {
2756- if ( exp & 1 ) == 1 {
2757- acc = acc * base;
2758- }
2759- exp /= 2 ;
2760- base = base * base;
2620+ while exp > 1 {
2621+ if ( exp & 1 ) == 1 {
2622+ acc = acc * base;
27612623 }
2762-
2763- // since exp!=0, finally the exp must be 1.
2764- // Deal with the final bit of the exponent separately, since
2765- // squaring the base afterwards is not necessary and may cause a
2766- // needless overflow.
2767- acc * base
2624+ exp /= 2 ;
2625+ base = base * base;
27682626 }
2627+
2628+ // since exp!=0, finally the exp must be 1.
2629+ // Deal with the final bit of the exponent separately, since
2630+ // squaring the base afterwards is not necessary and may cause a
2631+ // needless overflow.
2632+ acc * base
27692633 }
27702634
27712635 /// Returns the square root of the number, rounded down.
0 commit comments