This is an automated email from the ASF dual-hosted git repository.
alamb 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 6505d2a354 Revert "Seal Array trait (#9092)", mark `Array` as `unsafe`
(#9234)
6505d2a354 is described below
commit 6505d2a354e87e193e00ca7c6ea945de92c7adca
Author: Gabriel <[email protected]>
AuthorDate: Mon Jan 26 22:52:36 2026 +0100
Revert "Seal Array trait (#9092)", mark `Array` as `unsafe` (#9234)
This reverts commit 721f373fba7493c873a64421e32f1f67114ac130.
# 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.
-->
- Discussed in https://github.com/apache/arrow-rs/issues/9184
- Closes https://github.com/apache/arrow-rs/issues/9184
# Rationale for this change
<!--
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.
-->
As discussed in Discussed in
https://github.com/apache/arrow-rs/issues/9184, rather than sealing the
`Array` trait, it's going to potentially be marked `unsafe` so that
projects have time to find alternatives for their use-cases that are now
satisfied by a custom `Array` implementation.
# What changes are included in this PR?
<!--
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.
-->
Clean revert of https://github.com/apache/arrow-rs/pull/9092
# Are these changes tested?
<!--
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)?
-->
Not applicable here
# Are there any user-facing changes?
Yes, users can no implement the `Array` trait in their codebases again.
<!--
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/array/boolean_array.rs | 5 ++---
arrow-array/src/array/byte_array.rs | 5 ++---
arrow-array/src/array/byte_view_array.rs | 5 ++---
arrow-array/src/array/dictionary_array.rs | 9 +++------
arrow-array/src/array/fixed_size_binary_array.rs | 5 ++---
arrow-array/src/array/fixed_size_list_array.rs | 5 ++---
arrow-array/src/array/list_array.rs | 5 ++---
arrow-array/src/array/list_view_array.rs | 5 ++---
arrow-array/src/array/map_array.rs | 5 ++---
arrow-array/src/array/mod.rs | 25 +++++++++++-------------
arrow-array/src/array/null_array.rs | 5 ++---
arrow-array/src/array/primitive_array.rs | 5 ++---
arrow-array/src/array/run_array.rs | 10 ++++------
arrow-array/src/array/struct_array.rs | 5 ++---
arrow-array/src/array/union_array.rs | 5 ++---
15 files changed, 42 insertions(+), 62 deletions(-)
diff --git a/arrow-array/src/array/boolean_array.rs
b/arrow-array/src/array/boolean_array.rs
index 6419837003..7e5c1feb39 100644
--- a/arrow-array/src/array/boolean_array.rs
+++ b/arrow-array/src/array/boolean_array.rs
@@ -286,9 +286,8 @@ impl BooleanArray {
}
}
-impl super::private::Sealed for BooleanArray {}
-
-impl Array for BooleanArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for BooleanArray {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/byte_array.rs
b/arrow-array/src/array/byte_array.rs
index 8e8ad91cea..a54e9a5fc7 100644
--- a/arrow-array/src/array/byte_array.rs
+++ b/arrow-array/src/array/byte_array.rs
@@ -462,9 +462,8 @@ impl<T: ByteArrayType> std::fmt::Debug for
GenericByteArray<T> {
}
}
-impl<T: ByteArrayType> super::private::Sealed for GenericByteArray<T> {}
-
-impl<T: ByteArrayType> Array for GenericByteArray<T> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<T: ByteArrayType> Array for GenericByteArray<T> {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/byte_view_array.rs
b/arrow-array/src/array/byte_view_array.rs
index 2d5d207b82..0275b628e2 100644
--- a/arrow-array/src/array/byte_view_array.rs
+++ b/arrow-array/src/array/byte_view_array.rs
@@ -820,9 +820,8 @@ impl<T: ByteViewType + ?Sized> Debug for
GenericByteViewArray<T> {
}
}
-impl<T: ByteViewType + ?Sized> super::private::Sealed for
GenericByteViewArray<T> {}
-
-impl<T: ByteViewType + ?Sized> Array for GenericByteViewArray<T> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<T: ByteViewType + ?Sized> Array for GenericByteViewArray<T> {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/dictionary_array.rs
b/arrow-array/src/array/dictionary_array.rs
index 190a5038a0..54f8c42dd8 100644
--- a/arrow-array/src/array/dictionary_array.rs
+++ b/arrow-array/src/array/dictionary_array.rs
@@ -692,9 +692,8 @@ impl<'a, T: ArrowDictionaryKeyType> FromIterator<&'a str>
for DictionaryArray<T>
}
}
-impl<T: ArrowDictionaryKeyType> super::private::Sealed for DictionaryArray<T>
{}
-
-impl<T: ArrowDictionaryKeyType> Array for DictionaryArray<T> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<T: ArrowDictionaryKeyType> Array for DictionaryArray<T> {
fn as_any(&self) -> &dyn Any {
self
}
@@ -853,9 +852,7 @@ impl<'a, K: ArrowDictionaryKeyType, V>
TypedDictionaryArray<'a, K, V> {
}
}
-impl<K: ArrowDictionaryKeyType, V: Sync> super::private::Sealed for
TypedDictionaryArray<'_, K, V> {}
-
-impl<K: ArrowDictionaryKeyType, V: Sync> Array for TypedDictionaryArray<'_, K,
V> {
+unsafe impl<K: ArrowDictionaryKeyType, V: Sync> Array for
TypedDictionaryArray<'_, K, V> {
fn as_any(&self) -> &dyn Any {
self.dictionary
}
diff --git a/arrow-array/src/array/fixed_size_binary_array.rs
b/arrow-array/src/array/fixed_size_binary_array.rs
index f736d1f1eb..f9a4919b2c 100644
--- a/arrow-array/src/array/fixed_size_binary_array.rs
+++ b/arrow-array/src/array/fixed_size_binary_array.rs
@@ -603,9 +603,8 @@ impl std::fmt::Debug for FixedSizeBinaryArray {
}
}
-impl super::private::Sealed for FixedSizeBinaryArray {}
-
-impl Array for FixedSizeBinaryArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for FixedSizeBinaryArray {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/fixed_size_list_array.rs
b/arrow-array/src/array/fixed_size_list_array.rs
index 5a37d7f3e9..ce75855c68 100644
--- a/arrow-array/src/array/fixed_size_list_array.rs
+++ b/arrow-array/src/array/fixed_size_list_array.rs
@@ -463,9 +463,8 @@ impl From<FixedSizeListArray> for ArrayData {
}
}
-impl super::private::Sealed for FixedSizeListArray {}
-
-impl Array for FixedSizeListArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for FixedSizeListArray {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/list_array.rs
b/arrow-array/src/array/list_array.rs
index ae1b77895d..53e1db1e15 100644
--- a/arrow-array/src/array/list_array.rs
+++ b/arrow-array/src/array/list_array.rs
@@ -527,9 +527,8 @@ impl<OffsetSize: OffsetSizeTrait>
GenericListArray<OffsetSize> {
}
}
-impl<OffsetSize: OffsetSizeTrait> super::private::Sealed for
GenericListArray<OffsetSize> {}
-
-impl<OffsetSize: OffsetSizeTrait> Array for GenericListArray<OffsetSize> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<OffsetSize: OffsetSizeTrait> Array for
GenericListArray<OffsetSize> {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/list_view_array.rs
b/arrow-array/src/array/list_view_array.rs
index 4c50a32de5..b8d427d829 100644
--- a/arrow-array/src/array/list_view_array.rs
+++ b/arrow-array/src/array/list_view_array.rs
@@ -415,9 +415,8 @@ impl<OffsetSize: OffsetSizeTrait> ArrayAccessor for
&GenericListViewArray<Offset
}
}
-impl<OffsetSize: OffsetSizeTrait> super::private::Sealed for
GenericListViewArray<OffsetSize> {}
-
-impl<OffsetSize: OffsetSizeTrait> Array for GenericListViewArray<OffsetSize> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<OffsetSize: OffsetSizeTrait> Array for
GenericListViewArray<OffsetSize> {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/map_array.rs
b/arrow-array/src/array/map_array.rs
index 02f9a35eb6..07758d59bb 100644
--- a/arrow-array/src/array/map_array.rs
+++ b/arrow-array/src/array/map_array.rs
@@ -362,9 +362,8 @@ impl MapArray {
}
}
-impl super::private::Sealed for MapArray {}
-
-impl Array for MapArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for MapArray {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/mod.rs b/arrow-array/src/array/mod.rs
index c51917ad58..abc4091fe3 100644
--- a/arrow-array/src/array/mod.rs
+++ b/arrow-array/src/array/mod.rs
@@ -78,18 +78,17 @@ pub use list_view_array::*;
use crate::iterator::ArrayIter;
-mod private {
- /// Private marker trait to ensure [`super::Array`] can not be implemented
outside this crate
- pub trait Sealed {}
-
- impl<T: Sealed> Sealed for &T {}
-}
-
/// An array in the [arrow columnar
format](https://arrow.apache.org/docs/format/Columnar.html)
///
-/// This trait is sealed as it is not intended for custom array types, rather
only
-/// those defined in this crate.
-pub trait Array: std::fmt::Debug + Send + Sync + private::Sealed {
+/// # Safety
+///
+/// Implementations of this trait must ensure that all methods implementations
comply with
+/// the Arrow specification. No safety guards are placed and failing to comply
with it can
+/// translate into panics or undefined behavior. For example, a value computed
based on `len`
+/// may be used as a direct index into memory regions without checks.
+///
+/// Use it at your own risk knowing that this trait might be sealed in the
future.
+pub unsafe trait Array: std::fmt::Debug + Send + Sync {
/// Returns the array as [`Any`] so that it can be
/// downcasted to a specific implementation.
///
@@ -351,10 +350,8 @@ pub trait Array: std::fmt::Debug + Send + Sync +
private::Sealed {
/// A reference-counted reference to a generic `Array`
pub type ArrayRef = Arc<dyn Array>;
-impl private::Sealed for ArrayRef {}
-
/// Ergonomics: Allow use of an ArrayRef as an `&dyn Array`
-impl Array for ArrayRef {
+unsafe impl Array for ArrayRef {
fn as_any(&self) -> &dyn Any {
self.as_ref().as_any()
}
@@ -433,7 +430,7 @@ impl Array for ArrayRef {
}
}
-impl<T: Array> Array for &T {
+unsafe impl<T: Array> Array for &T {
fn as_any(&self) -> &dyn Any {
T::as_any(self)
}
diff --git a/arrow-array/src/array/null_array.rs
b/arrow-array/src/array/null_array.rs
index 18c155b78b..00b30935d4 100644
--- a/arrow-array/src/array/null_array.rs
+++ b/arrow-array/src/array/null_array.rs
@@ -76,9 +76,8 @@ impl NullArray {
}
}
-impl super::private::Sealed for NullArray {}
-
-impl Array for NullArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for NullArray {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/primitive_array.rs
b/arrow-array/src/array/primitive_array.rs
index d49db8a7b2..573677dc60 100644
--- a/arrow-array/src/array/primitive_array.rs
+++ b/arrow-array/src/array/primitive_array.rs
@@ -1186,9 +1186,8 @@ impl<T: ArrowPrimitiveType> From<PrimitiveArray<T>> for
ArrayData {
}
}
-impl<T: ArrowPrimitiveType> super::private::Sealed for PrimitiveArray<T> {}
-
-impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/run_array.rs
b/arrow-array/src/array/run_array.rs
index 517e84f1d7..aa4d798c77 100644
--- a/arrow-array/src/array/run_array.rs
+++ b/arrow-array/src/array/run_array.rs
@@ -283,9 +283,8 @@ impl<R: RunEndIndexType> From<RunArray<R>> for ArrayData {
}
}
-impl<T: RunEndIndexType> super::private::Sealed for RunArray<T> {}
-
-impl<T: RunEndIndexType> Array for RunArray<T> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<T: RunEndIndexType> Array for RunArray<T> {
fn as_any(&self) -> &dyn Any {
self
}
@@ -544,9 +543,8 @@ impl<'a, R: RunEndIndexType, V> TypedRunArray<'a, R, V> {
}
}
-impl<R: RunEndIndexType, V: Sync> super::private::Sealed for TypedRunArray<'_,
R, V> {}
-
-impl<R: RunEndIndexType, V: Sync> Array for TypedRunArray<'_, R, V> {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl<R: RunEndIndexType, V: Sync> Array for TypedRunArray<'_, R, V> {
fn as_any(&self) -> &dyn Any {
self.run_array
}
diff --git a/arrow-array/src/array/struct_array.rs
b/arrow-array/src/array/struct_array.rs
index a738a73321..b5f25fff18 100644
--- a/arrow-array/src/array/struct_array.rs
+++ b/arrow-array/src/array/struct_array.rs
@@ -402,9 +402,8 @@ impl TryFrom<Vec<(&str, ArrayRef)>> for StructArray {
}
}
-impl super::private::Sealed for StructArray {}
-
-impl Array for StructArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for StructArray {
fn as_any(&self) -> &dyn Any {
self
}
diff --git a/arrow-array/src/array/union_array.rs
b/arrow-array/src/array/union_array.rs
index 7bb9162b57..03d69a5845 100644
--- a/arrow-array/src/array/union_array.rs
+++ b/arrow-array/src/array/union_array.rs
@@ -742,9 +742,8 @@ impl From<UnionArray> for ArrayData {
}
}
-impl super::private::Sealed for UnionArray {}
-
-impl Array for UnionArray {
+/// SAFETY: Correctly implements the contract of Arrow Arrays
+unsafe impl Array for UnionArray {
fn as_any(&self) -> &dyn Any {
self
}