summary refs log tree commit diff
path: root/library/alloc/src/vec
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2021-05-26 23:19:35 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2021-05-26 23:19:35 -0700
commit04d34a97d1d47676331479e24e5afaf2583cb8e5 (patch)
treed09ee262201a3654235aeb21a37ee6a651ca270a /library/alloc/src/vec
parent3bcaeb0bf9e1c29d18abc32928fd2f23d1bed0bd (diff)
downloadrust-04d34a97d1d47676331479e24e5afaf2583cb8e5.tar.gz
rust-04d34a97d1d47676331479e24e5afaf2583cb8e5.zip
Enable Vec's calloc optimization for Option<NonZero>
Diffstat (limited to 'library/alloc/src/vec')
-rw-r--r--library/alloc/src/vec/is_zero.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs
index b5739970b6e..6fade636df9 100644
--- a/library/alloc/src/vec/is_zero.rs
+++ b/library/alloc/src/vec/is_zero.rs
@@ -69,3 +69,36 @@ unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
         self.is_none()
     }
 }
+
+// `Option<num::NonZeroU32>` and similar have a representation guarantee that
+// they're the same size as the corresponding `u32` type, as well as a guarantee
+// that transmuting between `NonZeroU32` and `Option<num::NonZeroU32>` works.
+// While the documentation officially makes in UB to transmute from `None`,
+// we're the standard library so we can make extra inferences, and we know that
+// the only niche available to represent `None` is the one that's all zeros.
+
+macro_rules! impl_is_zero_option_of_nonzero {
+    ($($t:ident,)+) => {$(
+        unsafe impl IsZero for Option<core::num::$t> {
+            #[inline]
+            fn is_zero(&self) -> bool {
+                self.is_none()
+            }
+        }
+    )+};
+}
+
+impl_is_zero_option_of_nonzero!(
+    NonZeroU8,
+    NonZeroU16,
+    NonZeroU32,
+    NonZeroU64,
+    NonZeroU128,
+    NonZeroI8,
+    NonZeroI16,
+    NonZeroI32,
+    NonZeroI64,
+    NonZeroI128,
+    NonZeroUsize,
+    NonZeroIsize,
+);