about summary refs log tree commit diff
path: root/library/coretests
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-09-04 01:43:21 -0400
committerGitHub <noreply@github.com>2025-09-04 01:43:21 -0400
commit00d5dc5c9d0a304020c7eb75562a415cf0e23806 (patch)
treeceaf61ab42a3e214a3c719af9a2cf04a8626352c /library/coretests
parent4c091fb9edcde213e9652b27e762ba0da231581a (diff)
parent62b4347e80cc86314bd98749e95eff8cdf8ef005 (diff)
downloadrust-00d5dc5c9d0a304020c7eb75562a415cf0e23806.tar.gz
rust-00d5dc5c9d0a304020c7eb75562a415cf0e23806.zip
Rollup merge of #145690 - sayantn:integer-funnel-shift, r=tgross35
Implement Integer funnel shifts

Tracking issue: rust-lang/rust#145686
ACP: https://github.com/rust-lang/libs-team/issues/642

This implements funnel shifts on primitive integer types. Implements this for cg_llvm, with a fallback impl for everything else

Thanks `@folkertdev` for the fixes and tests

cc `@rust-lang/libs-api`
Diffstat (limited to 'library/coretests')
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/coretests/tests/num/uint_macros.rs36
2 files changed, 37 insertions, 0 deletions
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 642d28759ae..b5658a9970f 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -50,6 +50,7 @@
 #![feature(fmt_internals)]
 #![feature(formatting_options)]
 #![feature(freeze)]
+#![feature(funnel_shifts)]
 #![feature(future_join)]
 #![feature(generic_assert_internals)]
 #![feature(hasher_prefixfree_extras)]
diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs
index c7d10ea4d88..63be8a45b5c 100644
--- a/library/coretests/tests/num/uint_macros.rs
+++ b/library/coretests/tests/num/uint_macros.rs
@@ -104,6 +104,19 @@ macro_rules! uint_module {
                 assert_eq_const_safe!($T: C.rotate_left(128), C);
             }
 
+            fn test_funnel_shift() {
+                // Shifting by 0 should have no effect
+                assert_eq_const_safe!($T: <$T>::funnel_shl(A, B, 0), A);
+                assert_eq_const_safe!($T: <$T>::funnel_shr(A, B, 0), B);
+
+                assert_eq_const_safe!($T: <$T>::funnel_shl(_0, _1, 4), 0b1111);
+                assert_eq_const_safe!($T: <$T>::funnel_shr(_0, _1, 4), _1 >> 4);
+                assert_eq_const_safe!($T: <$T>::funnel_shl(_1, _0, 4), _1 << 4);
+
+                assert_eq_const_safe!($T: <$T>::funnel_shl(_1, _1, 4), <$T>::rotate_left(_1, 4));
+                assert_eq_const_safe!($T: <$T>::funnel_shr(_1, _1, 4), <$T>::rotate_right(_1, 4));
+            }
+
             fn test_swap_bytes() {
                 assert_eq_const_safe!($T: A.swap_bytes().swap_bytes(), A);
                 assert_eq_const_safe!($T: B.swap_bytes().swap_bytes(), B);
@@ -151,6 +164,29 @@ macro_rules! uint_module {
         }
 
         #[test]
+        #[should_panic = "attempt to funnel shift left with overflow"]
+        fn test_funnel_shl_overflow() {
+            let _ = <$T>::funnel_shl(A, B, $T::BITS);
+        }
+
+        #[test]
+        #[should_panic = "attempt to funnel shift right with overflow"]
+        fn test_funnel_shr_overflow() {
+            let _ = <$T>::funnel_shr(A, B, $T::BITS);
+        }
+
+        #[test]
+        fn test_funnel_shifts_runtime() {
+            for i in 0..$T::BITS - 1 {
+                assert_eq!(<$T>::funnel_shl(A, 0, i), A << i);
+                assert_eq!(<$T>::funnel_shl(A, A, i), A.rotate_left(i));
+
+                assert_eq!(<$T>::funnel_shr(0, A, i), A >> i);
+                assert_eq!(<$T>::funnel_shr(A, A, i), A.rotate_right(i));
+            }
+        }
+
+        #[test]
         fn test_isolate_highest_one() {
             const BITS: $T = <$T>::MAX;
             const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1);