Rollup merge of #149837 - scottmcm:wrapping-shift-docs, r=workingjubilee

Update `wrapping_sh[lr]` docs and examples

Inspired by [#general > `Source` link for `core` items is often inscrutable @ 💬][zulip-thread] I wanted to add some more examples of the actual wrapping as well as update the documentation to emphasize that the behaviour is unusual.

In particular, now that `unbounded_sh[lr]` is stable, point people trying to avoid panics to that instead, since it behaves less weirdly.

[zulip-thread]: https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/.60Source.60.20link.20for.20.60core.60.20items.20is.20often.20inscrutable/near/562774474
This commit is contained in:
Matthias Krüger 2025-12-14 20:04:55 +01:00 committed by GitHub
commit a8460d0cf2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 56 additions and 8 deletions

View file

@ -2288,6 +2288,13 @@ macro_rules! int_impl {
/// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes
/// any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
///
/// Beware that, unlike most other `wrapping_*` methods on integers, this
/// does *not* give the same result as doing the shift in infinite precision
/// then truncating as needed. The behaviour matches what shift instructions
/// do on many processors, and is what the `<<` operator does when overflow
/// checks are disabled, but numerically it's weird. Consider, instead,
/// using [`Self::unbounded_shl`] which has nicer behaviour.
///
/// Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to
/// the range of the type, rather than the bits shifted out of the LHS being returned to the other end.
/// The primitive integer types all implement a [`rotate_left`](Self::rotate_left) function,
@ -2296,8 +2303,11 @@ macro_rules! int_impl {
/// # Examples
///
/// ```
#[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);")]
#[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);")]
#[doc = concat!("assert_eq!((-1_", stringify!($SelfT), ").wrapping_shl(7), -128);")]
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(", stringify!($BITS), "), 42);")]
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(1).wrapping_shl(", stringify!($BITS_MINUS_ONE), "), 0);")]
#[doc = concat!("assert_eq!((-1_", stringify!($SelfT), ").wrapping_shl(128), -1);")]
#[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".wrapping_shl(1025), 10);")]
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
@ -2315,6 +2325,13 @@ macro_rules! int_impl {
/// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask`
/// removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
///
/// Beware that, unlike most other `wrapping_*` methods on integers, this
/// does *not* give the same result as doing the shift in infinite precision
/// then truncating as needed. The behaviour matches what shift instructions
/// do on many processors, and is what the `>>` operator does when overflow
/// checks are disabled, but numerically it's weird. Consider, instead,
/// using [`Self::unbounded_shr`] which has nicer behaviour.
///
/// Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted
/// to the range of the type, rather than the bits shifted out of the LHS being returned to the other
/// end. The primitive integer types all implement a [`rotate_right`](Self::rotate_right) function,
@ -2323,8 +2340,11 @@ macro_rules! int_impl {
/// # Examples
///
/// ```
#[doc = concat!("assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);")]
/// assert_eq!((-128i16).wrapping_shr(64), -128);
#[doc = concat!("assert_eq!((-128_", stringify!($SelfT), ").wrapping_shr(7), -1);")]
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(", stringify!($BITS), "), 42);")]
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(1).wrapping_shr(", stringify!($BITS_MINUS_ONE), "), 0);")]
/// assert_eq!((-128_i16).wrapping_shr(64), -128);
#[doc = concat!("assert_eq!(10_", stringify!($SelfT), ".wrapping_shr(1025), 5);")]
/// ```
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]