about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-24 18:00:36 +0200
committerGitHub <noreply@github.com>2024-07-24 18:00:36 +0200
commit720c6f19b7c11a31fe4f1efece12a8709c67b651 (patch)
tree224b791d32a8ce7c281505b9872e75fe8f709ba9
parent130d15e23e2f06e0d777ecdc078cc2b49fefb543 (diff)
parent91af6b51223625ea5cd34d77861648ca19566deb (diff)
downloadrust-720c6f19b7c11a31fe4f1efece12a8709c67b651.tar.gz
rust-720c6f19b7c11a31fe4f1efece12a8709c67b651.zip
Rollup merge of #127252 - fitzgen:edge-cases-for-bitwise-operations, r=m-ou-se
Add edge-case examples to `{count,leading,trailing}_{ones,zeros}` methods

Some architectures (i386) do not define a "count leading zeros" instruction, they define a "find first set bit" instruction (`bsf`) whose result is undefined when given zero (ie none of the bits are set). Of this family of bitwise operations, I always forget which of these things is potentially undefined for zero, and I'm also not 100% sure that Rust provides a hard guarantee for the results of these methods when given zero. So I figured there are others who have these same uncertainties, and it would be good to resolve them and answer the question via extending these doc examples/tests.

See https://en.wikipedia.org/wiki/Find_first_set#Hardware_support for more info on i386 and `bsf` on zero.
-rw-r--r--library/core/src/num/uint_macros.rs41
1 files changed, 35 insertions, 6 deletions
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index d50bcde0157..dba51b4f67e 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -65,8 +65,13 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("let n = 0b01001100", stringify!($SelfT), ";")]
-        ///
         /// assert_eq!(n.count_ones(), 3);
+        ///
+        #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
+        #[doc = concat!("assert_eq!(max.count_ones(), ", stringify!($BITS), ");")]
+        ///
+        #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
+        /// assert_eq!(zero.count_ones(), 0);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
@@ -86,7 +91,11 @@ macro_rules! uint_impl {
         /// Basic usage:
         ///
         /// ```
-        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 0);")]
+        #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
+        #[doc = concat!("assert_eq!(zero.count_zeros(), ", stringify!($BITS), ");")]
+        ///
+        #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
+        /// assert_eq!(max.count_zeros(), 0);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
@@ -108,8 +117,13 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("let n = ", stringify!($SelfT), "::MAX >> 2;")]
-        ///
         /// assert_eq!(n.leading_zeros(), 2);
+        ///
+        #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
+        #[doc = concat!("assert_eq!(zero.leading_zeros(), ", stringify!($BITS), ");")]
+        ///
+        #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
+        /// assert_eq!(max.leading_zeros(), 0);
         /// ```
         #[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")]
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -130,8 +144,13 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("let n = 0b0101000", stringify!($SelfT), ";")]
-        ///
         /// assert_eq!(n.trailing_zeros(), 3);
+        ///
+        #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
+        #[doc = concat!("assert_eq!(zero.trailing_zeros(), ", stringify!($BITS), ");")]
+        ///
+        #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
+        #[doc = concat!("assert_eq!(max.trailing_zeros(), 0);")]
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
@@ -150,8 +169,13 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("let n = !(", stringify!($SelfT), "::MAX >> 2);")]
-        ///
         /// assert_eq!(n.leading_ones(), 2);
+        ///
+        #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
+        /// assert_eq!(zero.leading_ones(), 0);
+        ///
+        #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
+        #[doc = concat!("assert_eq!(max.leading_ones(), ", stringify!($BITS), ");")]
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
@@ -171,8 +195,13 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("let n = 0b1010111", stringify!($SelfT), ";")]
-        ///
         /// assert_eq!(n.trailing_ones(), 3);
+        ///
+        #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
+        /// assert_eq!(zero.trailing_ones(), 0);
+        ///
+        #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
+        #[doc = concat!("assert_eq!(max.trailing_ones(), ", stringify!($BITS), ");")]
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]