@@ -1386,32 +1386,37 @@ macro_rules! int_impl {
13861386 }
13871387 }
13881388
1389- /// Exact shift left. Computes `self << rhs`, returning `None` if any bits disagreeing with
1390- /// the resulting sign bit would be shifted out.
1389+ /// Exact shift left. Computes `self << rhs`, returning `None` if the sign bit would be
1390+ /// flipped or if `rhs` >=
1391+ #[ doc = concat!( "`" , stringify!( $SelfT) , "::BITS`." ) ]
13911392 ///
13921393 /// # Examples
13931394 ///
13941395 /// ```
13951396 /// #![feature(exact_bitshifts)]
13961397 ///
13971398 #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(4), Some(0x10));" ) ]
1398- #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(129), None);" ) ]
1399+ #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(" , stringify!( $SelfT) , "::BITS - 2), Some(1 << " , stringify!( $SelfT) , "::BITS - 2));" ) ]
1400+ #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(" , stringify!( $SelfT) , "::BITS - 1), None);" ) ]
1401+ #[ doc = concat!( "assert_eq!((-0x2" , stringify!( $SelfT) , ").exact_shl(" , stringify!( $SelfT) , "::BITS - 2), Some(-0x2 << " , stringify!( $SelfT) , "::BITS - 2));" ) ]
1402+ #[ doc = concat!( "assert_eq!((-0x2" , stringify!( $SelfT) , ").exact_shl(" , stringify!( $SelfT) , "::BITS - 1), None);" ) ]
13991403 /// ```
14001404 #[ unstable( feature = "exact_bitshifts" , issue = "144336" ) ]
14011405 #[ must_use = "this returns the result of the operation, \
14021406 without modifying the original"]
14031407 #[ inline]
1404- pub fn exact_shl( self , rhs: u32 ) -> Option <$SelfT> {
1405- if rhs < self . leading_zeros( ) . max ( self . leading_ones( ) ) {
1408+ pub const fn exact_shl( self , rhs: u32 ) -> Option <$SelfT> {
1409+ if rhs < self . leading_zeros( ) || rhs < self . leading_ones( ) {
14061410 // SAFETY: rhs is checked above
14071411 Some ( unsafe { self . unchecked_shl( rhs) } )
14081412 } else {
14091413 None
14101414 }
14111415 }
14121416
1413- /// Unchecked exact shift left. Computes `self << rhs`, assuming bits disagreeing with the
1414- /// resulting sign bit cannot be shifted out.
1417+ /// Unchecked exact shift left. Computes `self << rhs`, assuming the sign bit cannot be
1418+ /// flipped and rhs cannot be larger than
1419+ #[ doc = concat!( "`" , stringify!( $SelfT) , "::BITS`." ) ]
14151420 ///
14161421 /// # Safety
14171422 ///
@@ -1423,14 +1428,15 @@ macro_rules! int_impl {
14231428 #[ must_use = "this returns the result of the operation, \
14241429 without modifying the original"]
14251430 #[ inline]
1426- pub unsafe fn exact_shl_unchecked ( self , rhs: u32 ) -> $SelfT {
1431+ pub const unsafe fn unchecked_exact_shl ( self , rhs: u32 ) -> $SelfT {
14271432 assert_unsafe_precondition!(
14281433 check_language_ub,
1429- concat!( stringify!( $SelfT) , "::exact_shl_unchecked cannot shift out non-zero bits" ) ,
1434+ concat!( stringify!( $SelfT) , "::unchecked_exact_shl cannot shift out non-zero bits" ) ,
14301435 (
1431- len: u32 = self . leading_zeros( ) . max( self . leading_ones( ) ) ,
1436+ zeros: u32 = self . leading_zeros( ) ,
1437+ ones: u32 = self . leading_ones( ) ,
14321438 rhs: u32 = rhs,
1433- ) => rhs < len ,
1439+ ) => rhs < zeros || rhs < ones ,
14341440 ) ;
14351441
14361442 // SAFETY: this is guaranteed to be safe by the caller
@@ -1569,14 +1575,14 @@ macro_rules! int_impl {
15691575 /// #![feature(exact_bitshifts)]
15701576 ///
15711577 #[ doc = concat!( "assert_eq!(0x10" , stringify!( $SelfT) , ".exact_shr(4), Some(0x1));" ) ]
1572- #[ doc = concat!( "assert_eq!(0x10" , stringify!( $SelfT) , ".exact_shr(129 ), None);" ) ]
1578+ #[ doc = concat!( "assert_eq!(0x10" , stringify!( $SelfT) , ".exact_shr(5 ), None);" ) ]
15731579 /// ```
15741580 #[ unstable( feature = "exact_bitshifts" , issue = "144336" ) ]
15751581 #[ must_use = "this returns the result of the operation, \
15761582 without modifying the original"]
15771583 #[ inline]
1578- pub fn exact_shr( self , rhs: u32 ) -> Option <$SelfT> {
1579- if rhs <= self . trailing_zeros( ) . max ( < $SelfT>:: BITS - 1 ) {
1584+ pub const fn exact_shr( self , rhs: u32 ) -> Option <$SelfT> {
1585+ if rhs <= self . trailing_zeros( ) && rhs < < $SelfT>:: BITS {
15801586 // SAFETY: rhs is checked above
15811587 Some ( unsafe { self . unchecked_shr( rhs) } )
15821588 } else {
@@ -1599,14 +1605,15 @@ macro_rules! int_impl {
15991605 #[ must_use = "this returns the result of the operation, \
16001606 without modifying the original"]
16011607 #[ inline]
1602- pub unsafe fn exact_shr_unchecked ( self , rhs: u32 ) -> $SelfT {
1608+ pub const unsafe fn unchecked_exact_shr ( self , rhs: u32 ) -> $SelfT {
16031609 assert_unsafe_precondition!(
16041610 check_language_ub,
1605- concat!( stringify!( $SelfT) , "::exact_shr_unchecked cannot shift out non-zero bits" ) ,
1611+ concat!( stringify!( $SelfT) , "::unchecked_exact_shr cannot shift out non-zero bits" ) ,
16061612 (
1607- len: u32 = self . trailing_zeros( ) . max( <$SelfT>:: BITS - 1 ) ,
1613+ zeros: u32 = self . trailing_zeros( ) ,
1614+ bits: u32 = <$SelfT>:: BITS ,
16081615 rhs: u32 = rhs,
1609- ) => rhs <= len ,
1616+ ) => rhs <= zeros && rhs < bits ,
16101617 ) ;
16111618
16121619 // SAFETY: this is guaranteed to be safe by the caller
0 commit comments