This is an automated email from the ASF dual-hosted git repository.
Jefffrey pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 7e65400964 docs : add safety comments (#10843)
7e65400964 is described below
commit 7e65400964976dc09d4d8415fbae60f296a15054
Author: RIchard Baah <[email protected]>
AuthorDate: Wed Aug 26 22:20:07 2026 -0400
docs : add safety comments (#10843)
# Which issue does this PR close?
<!--
We generally require a GitHub issue to be filed for all bug fixes and
enhancements and this helps us generate change logs for our releases.
You can link an issue to this PR using the GitHub syntax.
-->
- Closes #146
.
# Rationale for this change
see
https://github.com/apache/arrow-rs/issues/146#issuecomment-5415976683
<!--
Why are you proposing this change? If this is already explained clearly
in the issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand
your changes and offer better suggestions for fixes.
-->
# What changes are included in this PR?
updates the remaining call sites in
https://github.com/apache/arrow-rs/issues/146#issuecomment-5415976683
<!--
There is no need to duplicate the description in the issue here but it
is sometimes worth providing a summary of the individual changes in this
PR.
-->
# Are these changes tested?
n/a
<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code
If tests are not included in your PR, please explain why (for example,
are they covered by existing tests)?
If this PR claims a performance improvement, please include evidence
such as benchmark results.
-->
# Are there any user-facing changes?
no
<!--
If there are user-facing changes then we may require documentation to be
updated before approving the PR.
If there are any breaking changes to public APIs, please call them out.
-->
---------
---
arrow-array/src/builder/boolean_builder.rs | 2 ++
arrow-array/src/builder/fixed_size_binary_builder.rs | 2 ++
arrow-array/src/builder/fixed_size_binary_dictionary_builder.rs | 3 +++
arrow-array/src/builder/generic_bytes_builder.rs | 2 ++
arrow-array/src/builder/generic_bytes_dictionary_builder.rs | 3 +++
arrow-array/src/builder/map_builder.rs | 1 +
arrow-array/src/builder/null_builder.rs | 2 ++
arrow-array/src/builder/primitive_builder.rs | 2 ++
arrow-array/src/builder/primitive_dictionary_builder.rs | 3 +++
arrow-array/src/builder/union_builder.rs | 2 ++
10 files changed, 22 insertions(+)
diff --git a/arrow-array/src/builder/boolean_builder.rs
b/arrow-array/src/builder/boolean_builder.rs
index f483e3ed7e..9604a14c2e 100644
--- a/arrow-array/src/builder/boolean_builder.rs
+++ b/arrow-array/src/builder/boolean_builder.rs
@@ -167,6 +167,7 @@ impl BooleanBuilder {
.add_buffer(self.values_builder.finish().into_inner())
.nulls(null_bit_buffer);
+ // SAFETY: values buffer and nulls have matching lengths
let array_data = unsafe { builder.build_unchecked() };
BooleanArray::from(array_data)
}
@@ -181,6 +182,7 @@ impl BooleanBuilder {
.add_buffer(value_buffer)
.nulls(nulls);
+ // SAFETY: values buffer and nulls have matching lengths
let array_data = unsafe { builder.build_unchecked() };
BooleanArray::from(array_data)
}
diff --git a/arrow-array/src/builder/fixed_size_binary_builder.rs
b/arrow-array/src/builder/fixed_size_binary_builder.rs
index 94d03324ba..848e79c3d8 100644
--- a/arrow-array/src/builder/fixed_size_binary_builder.rs
+++ b/arrow-array/src/builder/fixed_size_binary_builder.rs
@@ -135,6 +135,7 @@ impl FixedSizeBinaryBuilder {
.add_buffer(std::mem::take(&mut self.values_builder).into())
.nulls(self.null_buffer_builder.finish())
.len(array_length);
+ // SAFETY: value_length >= 0, values.len() == len * value_length, and
nulls.len() == len — all guaranteed by the builder
let array_data = unsafe { array_data_builder.build_unchecked() };
FixedSizeBinaryArray::from(array_data)
}
@@ -147,6 +148,7 @@ impl FixedSizeBinaryBuilder {
.add_buffer(values_buffer)
.nulls(self.null_buffer_builder.finish_cloned())
.len(array_length);
+ // SAFETY: value_length >= 0, values.len() == len * value_length, and
nulls.len() == len — all guaranteed by the builder
let array_data = unsafe { array_data_builder.build_unchecked() };
FixedSizeBinaryArray::from(array_data)
}
diff --git a/arrow-array/src/builder/fixed_size_binary_dictionary_builder.rs
b/arrow-array/src/builder/fixed_size_binary_dictionary_builder.rs
index 23cb086cd7..a2a10ac4c4 100644
--- a/arrow-array/src/builder/fixed_size_binary_dictionary_builder.rs
+++ b/arrow-array/src/builder/fixed_size_binary_dictionary_builder.rs
@@ -316,6 +316,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
@@ -335,6 +336,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
@@ -370,6 +372,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
}
diff --git a/arrow-array/src/builder/generic_bytes_builder.rs
b/arrow-array/src/builder/generic_bytes_builder.rs
index c69094be61..af8950fb70 100644
--- a/arrow-array/src/builder/generic_bytes_builder.rs
+++ b/arrow-array/src/builder/generic_bytes_builder.rs
@@ -215,6 +215,7 @@ impl<T: ByteArrayType> GenericByteBuilder<T> {
.nulls(self.null_buffer_builder.finish());
self.offsets_builder.push(self.next_offset());
+ // SAFETY: builder is constructed from valid offset and value buffers
maintained by the builder
let array_data = unsafe { array_builder.build_unchecked() };
GenericByteArray::from(array_data)
}
@@ -230,6 +231,7 @@ impl<T: ByteArrayType> GenericByteBuilder<T> {
.add_buffer(value_buffer)
.nulls(self.null_buffer_builder.finish_cloned());
+ // SAFETY: builder is constructed from valid offset and value buffers
maintained by the builder
let array_data = unsafe { array_builder.build_unchecked() };
GenericByteArray::from(array_data)
}
diff --git a/arrow-array/src/builder/generic_bytes_dictionary_builder.rs
b/arrow-array/src/builder/generic_bytes_dictionary_builder.rs
index 67d02ee6b6..aed195a033 100644
--- a/arrow-array/src/builder/generic_bytes_dictionary_builder.rs
+++ b/arrow-array/src/builder/generic_bytes_dictionary_builder.rs
@@ -505,6 +505,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
@@ -521,6 +522,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
@@ -553,6 +555,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
diff --git a/arrow-array/src/builder/map_builder.rs
b/arrow-array/src/builder/map_builder.rs
index 9306c856f3..74093f8f98 100644
--- a/arrow-array/src/builder/map_builder.rs
+++ b/arrow-array/src/builder/map_builder.rs
@@ -286,6 +286,7 @@ impl<K: ArrayBuilder, V: ArrayBuilder> MapBuilder<K, V> {
.add_child_data(struct_array.into_data())
.nulls(nulls);
+ // SAFETY: builder is constructed from valid offset buffer and struct
child array maintained by the builder
let array_data = unsafe { array_data.build_unchecked() };
MapArray::from(array_data)
diff --git a/arrow-array/src/builder/null_builder.rs
b/arrow-array/src/builder/null_builder.rs
index 489822065b..9dab231b40 100644
--- a/arrow-array/src/builder/null_builder.rs
+++ b/arrow-array/src/builder/null_builder.rs
@@ -88,6 +88,7 @@ impl NullBuilder {
let len = self.len();
let builder = ArrayData::new_null(&DataType::Null, len).into_builder();
+ // SAFETY: ArrayData::new_null produces valid null array data, so all
builder invariants hold
let array_data = unsafe { builder.build_unchecked() };
NullArray::from(array_data)
}
@@ -97,6 +98,7 @@ impl NullBuilder {
let len = self.len();
let builder = ArrayData::new_null(&DataType::Null, len).into_builder();
+ // SAFETY: ArrayData::new_null produces valid null array data, so all
builder invariants hold
let array_data = unsafe { builder.build_unchecked() };
NullArray::from(array_data)
}
diff --git a/arrow-array/src/builder/primitive_builder.rs
b/arrow-array/src/builder/primitive_builder.rs
index 4f1939e4af..060eb4f8dc 100644
--- a/arrow-array/src/builder/primitive_builder.rs
+++ b/arrow-array/src/builder/primitive_builder.rs
@@ -328,6 +328,7 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
.add_buffer(std::mem::take(&mut self.values_builder).into())
.nulls(nulls);
+ // SAFETY: builder is constructed from valid primitive value buffer
and null buffer with matching lengths
let array_data = unsafe { builder.build_unchecked() };
PrimitiveArray::<T>::from(array_data)
}
@@ -342,6 +343,7 @@ impl<T: ArrowPrimitiveType> PrimitiveBuilder<T> {
.add_buffer(values_buffer)
.nulls(nulls);
+ // SAFETY: builder is constructed from valid primitive value buffer
and null buffer with matching lengths
let array_data = unsafe { builder.build_unchecked() };
PrimitiveArray::<T>::from(array_data)
}
diff --git a/arrow-array/src/builder/primitive_dictionary_builder.rs
b/arrow-array/src/builder/primitive_dictionary_builder.rs
index 5dfd78d271..4911bee9e3 100644
--- a/arrow-array/src/builder/primitive_dictionary_builder.rs
+++ b/arrow-array/src/builder/primitive_dictionary_builder.rs
@@ -445,6 +445,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
@@ -461,6 +462,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
@@ -493,6 +495,7 @@ where
.data_type(data_type)
.child_data(vec![values.into_data()]);
+ // SAFETY: builder is constructed from valid key/value arrays produced
by the builder
DictionaryArray::from(unsafe { builder.build_unchecked() })
}
diff --git a/arrow-array/src/builder/union_builder.rs
b/arrow-array/src/builder/union_builder.rs
index 9949384827..9e64d97d9f 100644
--- a/arrow-array/src/builder/union_builder.rs
+++ b/arrow-array/src/builder/union_builder.rs
@@ -297,6 +297,7 @@ impl UnionBuilder {
mut null_buffer_builder,
},
)| {
+ // SAFETY: builder is constructed from valid value buffer,
slot count, and null buffer maintained by the builder
let array_ref = make_array(unsafe {
ArrayDataBuilder::new(data_type.clone())
.add_buffer(values_buffer.finish())
@@ -334,6 +335,7 @@ impl UnionBuilder {
null_buffer_builder,
} = field_data;
+ // SAFETY: builder is constructed from valid value buffer,
slot count, and null buffer maintained by the builder
let array_ref = make_array(unsafe {
ArrayDataBuilder::new(data_type.clone())
.add_buffer(values_buffer.finish_cloned())