@@ -1413,32 +1413,37 @@ macro_rules! int_impl {
14131413 }
14141414 }
14151415
1416- /// Exact shift left. Computes `self << rhs`, returning `None` if any bits disagreeing with
1417- /// the resulting sign bit would be shifted out.
1416+ /// Exact shift left. Computes `self << rhs`, returning `None` if any bits that would be
1417+ /// shifted out differ from the resulting sign bit or if `rhs` >=
1418+ #[ doc = concat!( "`" , stringify!( $SelfT) , "::BITS`." ) ]
14181419 ///
14191420 /// # Examples
14201421 ///
14211422 /// ```
14221423 /// #![feature(exact_bitshifts)]
14231424 ///
14241425 #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(4), Some(0x10));" ) ]
1425- #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(129), None);" ) ]
1426+ #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(" , stringify!( $SelfT) , "::BITS - 2), Some(1 << " , stringify!( $SelfT) , "::BITS - 2));" ) ]
1427+ #[ doc = concat!( "assert_eq!(0x1" , stringify!( $SelfT) , ".exact_shl(" , stringify!( $SelfT) , "::BITS - 1), None);" ) ]
1428+ #[ doc = concat!( "assert_eq!((-0x2" , stringify!( $SelfT) , ").exact_shl(" , stringify!( $SelfT) , "::BITS - 2), Some(-0x2 << " , stringify!( $SelfT) , "::BITS - 2));" ) ]
1429+ #[ doc = concat!( "assert_eq!((-0x2" , stringify!( $SelfT) , ").exact_shl(" , stringify!( $SelfT) , "::BITS - 1), None);" ) ]
14261430 /// ```
14271431 #[ unstable( feature = "exact_bitshifts" , issue = "144336" ) ]
14281432 #[ must_use = "this returns the result of the operation, \
14291433 without modifying the original"]
14301434 #[ inline]
1431- pub fn exact_shl( self , rhs: u32 ) -> Option <$SelfT> {
1432- if rhs < self . leading_zeros( ) . max ( self . leading_ones( ) ) {
1435+ pub const fn exact_shl( self , rhs: u32 ) -> Option <$SelfT> {
1436+ if rhs < self . leading_zeros( ) || rhs < self . leading_ones( ) {
14331437 // SAFETY: rhs is checked above
14341438 Some ( unsafe { self . unchecked_shl( rhs) } )
14351439 } else {
14361440 None
14371441 }
14381442 }
14391443
1440- /// Unchecked exact shift left. Computes `self << rhs`, assuming bits disagreeing with the
1441- /// resulting sign bit cannot be shifted out.
1444+ /// Unchecked exact shift left. Computes `self << rhs`, assuming all bits that are shifted
1445+ /// out are the same as the resulting sign bit and rhs cannot be larger than
1446+ #[ doc = concat!( "`" , stringify!( $SelfT) , "::BITS`." ) ]
14421447 ///
14431448 /// # Safety
14441449 ///
@@ -1450,14 +1455,15 @@ macro_rules! int_impl {
14501455 #[ must_use = "this returns the result of the operation, \
14511456 without modifying the original"]
14521457 #[ inline]
1453- pub unsafe fn exact_shl_unchecked ( self , rhs: u32 ) -> $SelfT {
1458+ pub const unsafe fn unchecked_exact_shl ( self , rhs: u32 ) -> $SelfT {
14541459 assert_unsafe_precondition!(
14551460 check_language_ub,
1456- concat!( stringify!( $SelfT) , "::exact_shl_unchecked cannot shift out non-zero bits" ) ,
1461+ concat!( stringify!( $SelfT) , "::unchecked_exact_shl cannot shift out non-zero bits" ) ,
14571462 (
1458- len: u32 = self . leading_zeros( ) . max( self . leading_ones( ) ) ,
1463+ zeros: u32 = self . leading_zeros( ) ,
1464+ ones: u32 = self . leading_ones( ) ,
14591465 rhs: u32 = rhs,
1460- ) => rhs < len ,
1466+ ) => rhs < zeros || rhs < ones ,
14611467 ) ;
14621468
14631469 // SAFETY: this is guaranteed to be safe by the caller
@@ -1595,14 +1601,14 @@ macro_rules! int_impl {
15951601 /// #![feature(exact_bitshifts)]
15961602 ///
15971603 #[ doc = concat!( "assert_eq!(0x10" , stringify!( $SelfT) , ".exact_shr(4), Some(0x1));" ) ]
1598- #[ doc = concat!( "assert_eq!(0x10" , stringify!( $SelfT) , ".exact_shr(129 ), None);" ) ]
1604+ #[ doc = concat!( "assert_eq!(0x10" , stringify!( $SelfT) , ".exact_shr(5 ), None);" ) ]
15991605 /// ```
16001606 #[ unstable( feature = "exact_bitshifts" , issue = "144336" ) ]
16011607 #[ must_use = "this returns the result of the operation, \
16021608 without modifying the original"]
16031609 #[ inline]
1604- pub fn exact_shr( self , rhs: u32 ) -> Option <$SelfT> {
1605- if rhs <= self . trailing_zeros( ) . max ( < $SelfT>:: BITS - 1 ) {
1610+ pub const fn exact_shr( self , rhs: u32 ) -> Option <$SelfT> {
1611+ if rhs <= self . trailing_zeros( ) && rhs < < $SelfT>:: BITS {
16061612 // SAFETY: rhs is checked above
16071613 Some ( unsafe { self . unchecked_shr( rhs) } )
16081614 } else {
@@ -1625,14 +1631,15 @@ macro_rules! int_impl {
16251631 #[ must_use = "this returns the result of the operation, \
16261632 without modifying the original"]
16271633 #[ inline]
1628- pub unsafe fn exact_shr_unchecked ( self , rhs: u32 ) -> $SelfT {
1634+ pub const unsafe fn unchecked_exact_shr ( self , rhs: u32 ) -> $SelfT {
16291635 assert_unsafe_precondition!(
16301636 check_language_ub,
1631- concat!( stringify!( $SelfT) , "::exact_shr_unchecked cannot shift out non-zero bits" ) ,
1637+ concat!( stringify!( $SelfT) , "::unchecked_exact_shr cannot shift out non-zero bits" ) ,
16321638 (
1633- len: u32 = self . trailing_zeros( ) . max( <$SelfT>:: BITS - 1 ) ,
1639+ zeros: u32 = self . trailing_zeros( ) ,
1640+ bits: u32 = <$SelfT>:: BITS ,
16341641 rhs: u32 = rhs,
1635- ) => rhs <= len ,
1642+ ) => rhs <= zeros && rhs < bits ,
16361643 ) ;
16371644
16381645 // SAFETY: this is guaranteed to be safe by the caller
0 commit comments