From 2984b9968a6d9111b8fba6b04d63981b1e34fa1c Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Sun, 9 Jan 2022 10:41:23 -0500 Subject: [PATCH] Document safety justification of some uses of `from_trusted_len_iter` --- arrow/src/array/array_primitive.rs | 2 +- arrow/src/buffer/ops.rs | 3 ++- arrow/src/compute/kernels/arithmetic.rs | 6 +++++- arrow/src/compute/kernels/length.rs | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arrow/src/array/array_primitive.rs b/arrow/src/array/array_primitive.rs index a9e1ba87207e..e2272ed19791 100644 --- a/arrow/src/array/array_primitive.rs +++ b/arrow/src/array/array_primitive.rs @@ -140,7 +140,7 @@ impl PrimitiveArray { /// Creates a PrimitiveArray based on a constant value with `count` elements pub fn from_value(value: T::Native, count: usize) -> Self { - // # Safety: length is known + // # Safety: iterator (0..count) correctly reports its length let val_buf = unsafe { Buffer::from_trusted_len_iter((0..count).map(|_| value)) }; let data = unsafe { ArrayData::new_unchecked( diff --git a/arrow/src/buffer/ops.rs b/arrow/src/buffer/ops.rs index 14d381199bdd..279c85e44921 100644 --- a/arrow/src/buffer/ops.rs +++ b/arrow/src/buffer/ops.rs @@ -140,7 +140,8 @@ where .iter() .zip(right_chunks.iter()) .map(|(left, right)| op(left, right)); - // Soundness: `BitChunks` is a trusted len iterator + // Soundness: `BitChunks` is a `BitChunks` iterator which + // correctly reports its upper bound let mut buffer = unsafe { MutableBuffer::from_trusted_len_iter(chunks) }; let remainder_bytes = ceil(left_chunks.remainder_len(), 8); diff --git a/arrow/src/compute/kernels/arithmetic.rs b/arrow/src/compute/kernels/arithmetic.rs index 09d4b9fd6cd0..4cb55ce99f1b 100644 --- a/arrow/src/compute/kernels/arithmetic.rs +++ b/arrow/src/compute/kernels/arithmetic.rs @@ -185,7 +185,7 @@ where // Benefit // ~60% speedup // Soundness - // `values` is an iterator with a known size. + // `values` is an iterator with a known size from a PrimitiveArray let buffer = unsafe { Buffer::from_trusted_len_iter(values) }; let data = unsafe { @@ -241,6 +241,7 @@ where } }, ); + // Safety: Iterator comes from a PrimitiveArray which reports its size correctly unsafe { Buffer::try_from_trusted_len_iter(values) } } else { // no value is null @@ -255,6 +256,7 @@ where Ok(*left % *right) } }); + // Safety: Iterator comes from a PrimitiveArray which reports its size correctly unsafe { Buffer::try_from_trusted_len_iter(values) } }?; @@ -311,6 +313,7 @@ where } }, ); + // Safety: Iterator comes from a PrimitiveArray which reports its size correctly unsafe { Buffer::try_from_trusted_len_iter(values) } } else { // no value is null @@ -325,6 +328,7 @@ where Ok(*left / *right) } }); + // Safety: Iterator comes from a PrimitiveArray which reports its size correctly unsafe { Buffer::try_from_trusted_len_iter(values) } }?; diff --git a/arrow/src/compute/kernels/length.rs b/arrow/src/compute/kernels/length.rs index b0f3d9ad58ef..d6d554f8f26e 100644 --- a/arrow/src/compute/kernels/length.rs +++ b/arrow/src/compute/kernels/length.rs @@ -48,7 +48,7 @@ where // Benefit // ~60% speedup // Soundness - // `values` is an iterator with a known size. + // `values` come from a slice iterator with a known size. let buffer = unsafe { Buffer::from_trusted_len_iter(lengths) }; let null_bit_buffer = array