about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-10 18:42:40 +0000
committerbors <bors@rust-lang.org>2022-10-10 18:42:40 +0000
commita6b7274a462829f8ef08a1ddcdcec7ac80dbf3e1 (patch)
treeaa8d4d69987868dd1f3b7e8a1dd353f87c6c223b /library/alloc/src
parent0265a3e93bf1b89d97cae113ed214954d5c35e22 (diff)
parent31cd0aa823a379b6c0d0f66ba4172585d1780e8b (diff)
downloadrust-a6b7274a462829f8ef08a1ddcdcec7ac80dbf3e1.tar.gz
rust-a6b7274a462829f8ef08a1ddcdcec7ac80dbf3e1.zip
Auto merge of #102596 - scottmcm:option-bool-calloc, r=Mark-Simulacrum
Do the `calloc` optimization for `Option<bool>`

Inspired by <https://old.reddit.com/r/rust/comments/xtiqj8/why_is_this_functional_version_faster_than_my_for/iqqy37b/>.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/vec/is_zero.rs22
1 files changed, 22 insertions, 0 deletions
diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs
index 2e025c8a4a5..8e652d676dc 100644
--- a/library/alloc/src/vec/is_zero.rs
+++ b/library/alloc/src/vec/is_zero.rs
@@ -160,3 +160,25 @@ unsafe impl<T: IsZero> IsZero for Saturating<T> {
         self.0.is_zero()
     }
 }
+
+macro_rules! impl_for_optional_bool {
+    ($($t:ty,)+) => {$(
+        unsafe impl IsZero for $t {
+            #[inline]
+            fn is_zero(&self) -> bool {
+                // SAFETY: This is *not* a stable layout guarantee, but
+                // inside `core` we're allowed to rely on the current rustc
+                // behaviour that options of bools will be one byte with
+                // no padding, so long as they're nested less than 254 deep.
+                let raw: u8 = unsafe { core::mem::transmute(*self) };
+                raw == 0
+            }
+        }
+    )+};
+}
+impl_for_optional_bool! {
+    Option<bool>,
+    Option<Option<bool>>,
+    Option<Option<Option<bool>>>,
+    // Could go further, but not worth the metadata overhead
+}