From b94a29a25ff9ca4a8edfc0b6c7d1d309dc03d5cd Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 17 Jan 2023 15:42:53 +0000 Subject: [PATCH 1/2] Implement `alloc::vec::IsZero` for `Option<$NUM>` types --- library/alloc/src/lib.rs | 1 + library/alloc/src/vec/is_zero.rs | 17 +++++++++++++++++ tests/codegen/vec-calloc.rs | 17 +++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index afc3a3dc6a8..ca75c3895f4 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,6 +106,7 @@ #![feature(const_size_of_val)] #![feature(const_align_of_val)] #![feature(const_ptr_read)] +#![feature(const_maybe_uninit_zeroed)] #![feature(const_maybe_uninit_write)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_refs_to_cell)] diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs index 26120270c0c..2b6be14de79 100644 --- a/library/alloc/src/vec/is_zero.rs +++ b/library/alloc/src/vec/is_zero.rs @@ -147,6 +147,23 @@ impl_is_zero_option_of_nonzero!( NonZeroIsize, ); +macro_rules! impl_is_zero_option_of_num { + ($($t:ty,)+) => {$( + unsafe impl IsZero for Option<$t> { + #[inline] + fn is_zero(&self) -> bool { + const { + let none: Self = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; + assert!(none.is_none()); + } + self.is_none() + } + } + )+}; +} + +impl_is_zero_option_of_num!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize,); + unsafe impl IsZero for Wrapping { #[inline] fn is_zero(&self) -> bool { diff --git a/tests/codegen/vec-calloc.rs b/tests/codegen/vec-calloc.rs index ae6e448f172..9cc5bd4fd1a 100644 --- a/tests/codegen/vec-calloc.rs +++ b/tests/codegen/vec-calloc.rs @@ -161,6 +161,23 @@ pub fn vec_option_bool(n: usize) -> Vec> { vec![Some(false); n] } +// CHECK-LABEL: @vec_option_i32 +#[no_mangle] +pub fn vec_option_i32(n: usize) -> Vec> { + // CHECK-NOT: call {{.*}}alloc::vec::from_elem + // CHECK-NOT: call {{.*}}reserve + // CHECK-NOT: call {{.*}}__rust_alloc( + + // CHECK: call {{.*}}__rust_alloc_zeroed( + + // CHECK-NOT: call {{.*}}alloc::vec::from_elem + // CHECK-NOT: call {{.*}}reserve + // CHECK-NOT: call {{.*}}__rust_alloc( + + // CHECK: ret void + vec![None; n] +} + // Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away. // CHECK: declare noalias ptr @__rust_alloc_zeroed(i64, i64 allocalign) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]] From 50e9f2e6e87911659b6ae63230a5797f4cdf28e1 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 18 Jan 2023 15:48:53 +0000 Subject: [PATCH 2/2] Update `IsZero` documentation --- library/alloc/src/vec/is_zero.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs index 2b6be14de79..cb9adf05c25 100644 --- a/library/alloc/src/vec/is_zero.rs +++ b/library/alloc/src/vec/is_zero.rs @@ -4,7 +4,8 @@ use crate::boxed::Box; #[rustc_specialization_trait] pub(super) unsafe trait IsZero { - /// Whether this value's representation is all zeros + /// Whether this value's representation is all zeros, + /// or can be represented with all zeroes. fn is_zero(&self) -> bool; }