Skip to content

Commit a8460d0

Browse files
authored
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
2 parents d7a18fc + f9b830c commit a8460d0

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

library/core/src/num/int_macros.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,6 +2288,13 @@ macro_rules! int_impl {
22882288
/// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes
22892289
/// any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
22902290
///
2291+
/// Beware that, unlike most other `wrapping_*` methods on integers, this
2292+
/// does *not* give the same result as doing the shift in infinite precision
2293+
/// then truncating as needed. The behaviour matches what shift instructions
2294+
/// do on many processors, and is what the `<<` operator does when overflow
2295+
/// checks are disabled, but numerically it's weird. Consider, instead,
2296+
/// using [`Self::unbounded_shl`] which has nicer behaviour.
2297+
///
22912298
/// Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to
22922299
/// the range of the type, rather than the bits shifted out of the LHS being returned to the other end.
22932300
/// The primitive integer types all implement a [`rotate_left`](Self::rotate_left) function,
@@ -2296,8 +2303,11 @@ macro_rules! int_impl {
22962303
/// # Examples
22972304
///
22982305
/// ```
2299-
#[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);")]
2300-
#[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);")]
2306+
#[doc = concat!("assert_eq!((-1_", stringify!($SelfT), ").wrapping_shl(7), -128);")]
2307+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(", stringify!($BITS), "), 42);")]
2308+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(1).wrapping_shl(", stringify!($BITS_MINUS_ONE), "), 0);")]
2309+
#[doc = concat!("assert_eq!((-1_", stringify!($SelfT), ").wrapping_shl(128), -1);")]
2310+
#[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".wrapping_shl(1025), 10);")]
23012311
/// ```
23022312
#[stable(feature = "num_wrapping", since = "1.2.0")]
23032313
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
@@ -2315,6 +2325,13 @@ macro_rules! int_impl {
23152325
/// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask`
23162326
/// removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
23172327
///
2328+
/// Beware that, unlike most other `wrapping_*` methods on integers, this
2329+
/// does *not* give the same result as doing the shift in infinite precision
2330+
/// then truncating as needed. The behaviour matches what shift instructions
2331+
/// do on many processors, and is what the `>>` operator does when overflow
2332+
/// checks are disabled, but numerically it's weird. Consider, instead,
2333+
/// using [`Self::unbounded_shr`] which has nicer behaviour.
2334+
///
23182335
/// Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted
23192336
/// to the range of the type, rather than the bits shifted out of the LHS being returned to the other
23202337
/// end. The primitive integer types all implement a [`rotate_right`](Self::rotate_right) function,
@@ -2323,8 +2340,11 @@ macro_rules! int_impl {
23232340
/// # Examples
23242341
///
23252342
/// ```
2326-
#[doc = concat!("assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);")]
2327-
/// assert_eq!((-128i16).wrapping_shr(64), -128);
2343+
#[doc = concat!("assert_eq!((-128_", stringify!($SelfT), ").wrapping_shr(7), -1);")]
2344+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(", stringify!($BITS), "), 42);")]
2345+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(1).wrapping_shr(", stringify!($BITS_MINUS_ONE), "), 0);")]
2346+
/// assert_eq!((-128_i16).wrapping_shr(64), -128);
2347+
#[doc = concat!("assert_eq!(10_", stringify!($SelfT), ".wrapping_shr(1025), 5);")]
23282348
/// ```
23292349
#[stable(feature = "num_wrapping", since = "1.2.0")]
23302350
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]

library/core/src/num/uint_macros.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,13 @@ macro_rules! uint_impl {
25932593
/// where `mask` removes any high-order bits of `rhs` that
25942594
/// would cause the shift to exceed the bitwidth of the type.
25952595
///
2596+
/// Beware that, unlike most other `wrapping_*` methods on integers, this
2597+
/// does *not* give the same result as doing the shift in infinite precision
2598+
/// then truncating as needed. The behaviour matches what shift instructions
2599+
/// do on many processors, and is what the `<<` operator does when overflow
2600+
/// checks are disabled, but numerically it's weird. Consider, instead,
2601+
/// using [`Self::unbounded_shl`] which has nicer behaviour.
2602+
///
25962603
/// Note that this is *not* the same as a rotate-left; the
25972604
/// RHS of a wrapping shift-left is restricted to the range
25982605
/// of the type, rather than the bits shifted out of the LHS
@@ -2603,8 +2610,15 @@ macro_rules! uint_impl {
26032610
/// # Examples
26042611
///
26052612
/// ```
2606-
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);")]
2607-
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);")]
2613+
#[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".wrapping_shl(7), 128);")]
2614+
#[doc = concat!("assert_eq!(0b101_", stringify!($SelfT), ".wrapping_shl(0), 0b101);")]
2615+
#[doc = concat!("assert_eq!(0b101_", stringify!($SelfT), ".wrapping_shl(1), 0b1010);")]
2616+
#[doc = concat!("assert_eq!(0b101_", stringify!($SelfT), ".wrapping_shl(2), 0b10100);")]
2617+
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_shl(2), ", stringify!($SelfT), "::MAX - 3);")]
2618+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(", stringify!($BITS), "), 42);")]
2619+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(1).wrapping_shl(", stringify!($BITS_MINUS_ONE), "), 0);")]
2620+
#[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".wrapping_shl(128), 1);")]
2621+
#[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".wrapping_shl(1025), 10);")]
26082622
/// ```
26092623
#[stable(feature = "num_wrapping", since = "1.2.0")]
26102624
#[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
@@ -2623,6 +2637,13 @@ macro_rules! uint_impl {
26232637
/// where `mask` removes any high-order bits of `rhs` that
26242638
/// would cause the shift to exceed the bitwidth of the type.
26252639
///
2640+
/// Beware that, unlike most other `wrapping_*` methods on integers, this
2641+
/// does *not* give the same result as doing the shift in infinite precision
2642+
/// then truncating as needed. The behaviour matches what shift instructions
2643+
/// do on many processors, and is what the `>>` operator does when overflow
2644+
/// checks are disabled, but numerically it's weird. Consider, instead,
2645+
/// using [`Self::unbounded_shr`] which has nicer behaviour.
2646+
///
26262647
/// Note that this is *not* the same as a rotate-right; the
26272648
/// RHS of a wrapping shift-right is restricted to the range
26282649
/// of the type, rather than the bits shifted out of the LHS
@@ -2633,8 +2654,15 @@ macro_rules! uint_impl {
26332654
/// # Examples
26342655
///
26352656
/// ```
2636-
#[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);")]
2637-
#[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);")]
2657+
#[doc = concat!("assert_eq!(128_", stringify!($SelfT), ".wrapping_shr(7), 1);")]
2658+
#[doc = concat!("assert_eq!(0b1010_", stringify!($SelfT), ".wrapping_shr(0), 0b1010);")]
2659+
#[doc = concat!("assert_eq!(0b1010_", stringify!($SelfT), ".wrapping_shr(1), 0b101);")]
2660+
#[doc = concat!("assert_eq!(0b1010_", stringify!($SelfT), ".wrapping_shr(2), 0b10);")]
2661+
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_shr(1), ", stringify!($SignedT), "::MAX.cast_unsigned());")]
2662+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(", stringify!($BITS), "), 42);")]
2663+
#[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(1).wrapping_shr(", stringify!($BITS_MINUS_ONE), "), 0);")]
2664+
#[doc = concat!("assert_eq!(128_", stringify!($SelfT), ".wrapping_shr(128), 128);")]
2665+
#[doc = concat!("assert_eq!(10_", stringify!($SelfT), ".wrapping_shr(1025), 5);")]
26382666
/// ```
26392667
#[stable(feature = "num_wrapping", since = "1.2.0")]
26402668
#[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]

0 commit comments

Comments
 (0)