Skip to content

Commit 705a96d

Browse files
committed
Auto merge of rust-lang#106989 - clubby789:is-zero-num, r=scottmcm
Implement `alloc::vec::IsZero` for `Option<$NUM>` types Fixes rust-lang#106911 Mirrors the `NonZero$NUM` implementations with an additional `assert_zero_valid`. `None::<i32>` doesn't stricly satisfy `IsZero` but for the purpose of allocating we can produce more efficient codegen.
2 parents 65d2f2a + 50e9f2e commit 705a96d

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
#![feature(const_size_of_val)]
107107
#![feature(const_align_of_val)]
108108
#![feature(const_ptr_read)]
109+
#![feature(const_maybe_uninit_zeroed)]
109110
#![feature(const_maybe_uninit_write)]
110111
#![feature(const_maybe_uninit_as_mut_ptr)]
111112
#![feature(const_refs_to_cell)]

library/alloc/src/vec/is_zero.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use crate::boxed::Box;
44

55
#[rustc_specialization_trait]
66
pub(super) unsafe trait IsZero {
7-
/// Whether this value's representation is all zeros
7+
/// Whether this value's representation is all zeros,
8+
/// or can be represented with all zeroes.
89
fn is_zero(&self) -> bool;
910
}
1011

@@ -147,6 +148,23 @@ impl_is_zero_option_of_nonzero!(
147148
NonZeroIsize,
148149
);
149150

151+
macro_rules! impl_is_zero_option_of_num {
152+
($($t:ty,)+) => {$(
153+
unsafe impl IsZero for Option<$t> {
154+
#[inline]
155+
fn is_zero(&self) -> bool {
156+
const {
157+
let none: Self = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
158+
assert!(none.is_none());
159+
}
160+
self.is_none()
161+
}
162+
}
163+
)+};
164+
}
165+
166+
impl_is_zero_option_of_num!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize,);
167+
150168
unsafe impl<T: IsZero> IsZero for Wrapping<T> {
151169
#[inline]
152170
fn is_zero(&self) -> bool {

tests/codegen/vec-calloc.rs

+17
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,23 @@ pub fn vec_option_bool(n: usize) -> Vec<Option<bool>> {
161161
vec![Some(false); n]
162162
}
163163

164+
// CHECK-LABEL: @vec_option_i32
165+
#[no_mangle]
166+
pub fn vec_option_i32(n: usize) -> Vec<Option<i32>> {
167+
// CHECK-NOT: call {{.*}}alloc::vec::from_elem
168+
// CHECK-NOT: call {{.*}}reserve
169+
// CHECK-NOT: call {{.*}}__rust_alloc(
170+
171+
// CHECK: call {{.*}}__rust_alloc_zeroed(
172+
173+
// CHECK-NOT: call {{.*}}alloc::vec::from_elem
174+
// CHECK-NOT: call {{.*}}reserve
175+
// CHECK-NOT: call {{.*}}__rust_alloc(
176+
177+
// CHECK: ret void
178+
vec![None; n]
179+
}
180+
164181
// Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away.
165182
// CHECK: declare noalias noundef ptr @__rust_alloc_zeroed(i64 noundef, i64 allocalign noundef) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]]
166183

0 commit comments

Comments
 (0)