From 853099f49c4680bf1f46802cb4f6a153717574dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Tue, 14 Oct 2025 20:54:40 +0200 Subject: [PATCH] Implement 'bit' and 'set_bit' for integral types; --- library/core/src/num/int_macros.rs | 59 ++++++++++++++++++ library/core/src/num/uint_macros.rs | 61 +++++++++++++++++++ tests/ui/const-generics/issues/issue-86820.rs | 2 +- 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index c3460a6409069..28fd9e1013c97 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -56,6 +56,65 @@ macro_rules! int_impl { #[stable(feature = "int_bits_const", since = "1.53.0")] pub const BITS: u32 = <$UnsignedT>::BITS; + /// Tests the value of a specific bit. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_set_bit)] + /// + #[doc = concat!("let n = 0b1000001", stringify!($SelfT), ";")] + /// + /// assert!(n.bit(0)); + /// assert!(!n.bit(1)); + /// assert!(!n.bit(2)); + /// assert!(!n.bit(3)); + /// assert!(!n.bit(4)); + /// assert!(!n.bit(5)); + /// assert!(n.bit(6)); + /// ``` + #[unstable(feature = "get_set_bit", issue = "147702")] + #[rustc_const_unstable(feature = "get_set_bit", issue = "147702")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[track_caller] + pub const fn bit(self, index: u32) -> bool { + self & (1 as $SelfT) << index != (0 as $SelfT) + } + + /// Sets the value of a specific bit. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_set_bit)] + /// + #[doc = concat!("let mut n = 0b1010101", stringify!($SelfT), ";")] + /// + /// n = n.set_bit(0, false); + /// n = n.set_bit(1, true); + /// n = n.set_bit(2, false); + /// n = n.set_bit(3, true); + /// n = n.set_bit(4, false); + /// n = n.set_bit(5, true); + /// n = n.set_bit(6, false); + /// + /// assert_eq!(n, 0b0101010); + /// ``` + #[unstable(feature = "get_set_bit", issue = "147702")] + #[rustc_const_unstable(feature = "get_set_bit", issue = "147702")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[track_caller] + pub const fn set_bit(mut self, index: u32, value: bool) -> Self { + self &= !((1 as $SelfT) << index); + self |= (value as $SelfT) << index; + + self + } + /// Returns the number of ones in the binary representation of `self`. /// /// # Examples diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index b5b768cf677aa..13077e98dbb40 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -57,6 +57,67 @@ macro_rules! uint_impl { #[stable(feature = "int_bits_const", since = "1.53.0")] pub const BITS: u32 = Self::MAX.count_ones(); + /// Tests the value of a specific bit. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_set_bit)] + /// + #[doc = concat!("let n = 0b10000001", stringify!($SelfT), ";")] + /// + /// assert!(n.bit(0)); + /// assert!(!n.bit(1)); + /// assert!(!n.bit(2)); + /// assert!(!n.bit(3)); + /// assert!(!n.bit(4)); + /// assert!(!n.bit(5)); + /// assert!(!n.bit(6)); + /// assert!(n.bit(7)); + /// ``` + #[unstable(feature = "get_set_bit", issue = "147702")] + #[rustc_const_unstable(feature = "get_set_bit", issue = "147702")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[track_caller] + pub const fn bit(self, index: u32) -> bool { + self & (1 as $SelfT) << index != (0 as $SelfT) + } + + /// Sets the value of a specific bit. + /// + /// # Examples + /// + /// ``` + /// #![feature(get_set_bit)] + /// + #[doc = concat!("let mut n = 0b01010101", stringify!($SelfT), ";")] + /// + /// n = n.set_bit(0, false); + /// n = n.set_bit(1, true); + /// n = n.set_bit(2, false); + /// n = n.set_bit(3, true); + /// n = n.set_bit(4, false); + /// n = n.set_bit(5, true); + /// n = n.set_bit(6, false); + /// n = n.set_bit(7, true); + /// + /// assert_eq!(n, 0b10101010); + /// ``` + #[unstable(feature = "get_set_bit", issue = "147702")] + #[rustc_const_unstable(feature = "get_set_bit", issue = "147702")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[track_caller] + pub const fn set_bit(mut self, index: u32, value: bool) -> Self { + self &= !((1 as $SelfT) << index); + self |= (value as $SelfT) << index; + + self + } + /// Returns the number of ones in the binary representation of `self`. /// /// # Examples diff --git a/tests/ui/const-generics/issues/issue-86820.rs b/tests/ui/const-generics/issues/issue-86820.rs index ae4bd943fd415..d20432ce27a4f 100644 --- a/tests/ui/const-generics/issues/issue-86820.rs +++ b/tests/ui/const-generics/issues/issue-86820.rs @@ -5,7 +5,7 @@ use std::ops::BitAnd; const C: fn() = || is_set(); fn is_set() { - 0xffu8.bit::<0>(); + Bits::bit::<0>(0xffu8); } trait Bits {