Skip to content

Commit ea78d1e

Browse files
committed
Auto merge of rust-lang#85737 - scottmcm:vec-calloc-option-nonzero, r=m-ou-se
Enable Vec's calloc optimization for Option<NonZero> Someone on discord noticed that `vec![None::<NonZeroU32>; N]` wasn't getting the optimization, so here's a PR 🙃 We can certainly do this in the standard library because we know for sure this is ok, but I think it's also a necessary consequence of documented guarantees like those in https://doc.rust-lang.org/std/option/#representation and https://doc.rust-lang.org/core/num/struct.NonZeroU32.html It feels weird to do this without adding a test, but I wasn't sure where that would belong. Is it worth adding codegen tests for these?
2 parents 8d1e3d3 + 04d34a9 commit ea78d1e

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

library/alloc/src/vec/is_zero.rs

+33
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,36 @@ unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
6969
self.is_none()
7070
}
7171
}
72+
73+
// `Option<num::NonZeroU32>` and similar have a representation guarantee that
74+
// they're the same size as the corresponding `u32` type, as well as a guarantee
75+
// that transmuting between `NonZeroU32` and `Option<num::NonZeroU32>` works.
76+
// While the documentation officially makes in UB to transmute from `None`,
77+
// we're the standard library so we can make extra inferences, and we know that
78+
// the only niche available to represent `None` is the one that's all zeros.
79+
80+
macro_rules! impl_is_zero_option_of_nonzero {
81+
($($t:ident,)+) => {$(
82+
unsafe impl IsZero for Option<core::num::$t> {
83+
#[inline]
84+
fn is_zero(&self) -> bool {
85+
self.is_none()
86+
}
87+
}
88+
)+};
89+
}
90+
91+
impl_is_zero_option_of_nonzero!(
92+
NonZeroU8,
93+
NonZeroU16,
94+
NonZeroU32,
95+
NonZeroU64,
96+
NonZeroU128,
97+
NonZeroI8,
98+
NonZeroI16,
99+
NonZeroI32,
100+
NonZeroI64,
101+
NonZeroI128,
102+
NonZeroUsize,
103+
NonZeroIsize,
104+
);

0 commit comments

Comments
 (0)