3 #[rustc_specialization_trait]
4 pub(super) unsafe trait IsZero
{
5 /// Whether this value is zero
6 fn is_zero(&self) -> bool
;
9 macro_rules
! impl_is_zero
{
10 ($t
:ty
, $is_zero
:expr
) => {
11 unsafe impl IsZero
for $t
{
13 fn is_zero(&self) -> bool
{
20 impl_is_zero
!(i16, |x
| x
== 0);
21 impl_is_zero
!(i32, |x
| x
== 0);
22 impl_is_zero
!(i64, |x
| x
== 0);
23 impl_is_zero
!(i128
, |x
| x
== 0);
24 impl_is_zero
!(isize, |x
| x
== 0);
26 impl_is_zero
!(u16, |x
| x
== 0);
27 impl_is_zero
!(u32, |x
| x
== 0);
28 impl_is_zero
!(u64, |x
| x
== 0);
29 impl_is_zero
!(u128
, |x
| x
== 0);
30 impl_is_zero
!(usize, |x
| x
== 0);
32 impl_is_zero
!(bool
, |x
| x
== false);
33 impl_is_zero
!(char, |x
| x
== '
\0'
);
35 impl_is_zero
!(f32, |x
: f32| x
.to_bits() == 0);
36 impl_is_zero
!(f64, |x
: f64| x
.to_bits() == 0);
38 unsafe impl<T
> IsZero
for *const T
{
40 fn is_zero(&self) -> bool
{
45 unsafe impl<T
> IsZero
for *mut T
{
47 fn is_zero(&self) -> bool
{
52 // `Option<&T>` and `Option<Box<T>>` are guaranteed to represent `None` as null.
53 // For fat pointers, the bytes that would be the pointer metadata in the `Some`
54 // variant are padding in the `None` variant, so ignoring them and
55 // zero-initializing instead is ok.
56 // `Option<&mut T>` never implements `Clone`, so there's no need for an impl of
59 unsafe impl<T
: ?Sized
> IsZero
for Option
<&T
> {
61 fn is_zero(&self) -> bool
{
66 unsafe impl<T
: ?Sized
> IsZero
for Option
<Box
<T
>> {
68 fn is_zero(&self) -> bool
{
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 it 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.
80 macro_rules
! impl_is_zero_option_of_nonzero
{
81 ($
($t
:ident
,)+) => {$
(
82 unsafe impl IsZero
for Option
<core
::num
::$t
> {
84 fn is_zero(&self) -> bool
{
91 impl_is_zero_option_of_nonzero
!(