This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch 57_maintenance
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/57_maintenance by this push:
     new 505eb8ec60 [57_maintenance] Revert "Seal Array trait (#9092)", mark 
`Array` as `unsafe` (#9234) (#9313)
505eb8ec60 is described below

commit 505eb8ec606907af2144ca664555ec60d1d55a26
Author: Andrew Lamb <[email protected]>
AuthorDate: Mon Feb 2 10:05:30 2026 -0500

    [57_maintenance] Revert "Seal Array trait (#9092)", mark `Array` as 
`unsafe` (#9234) (#9313)
    
    - Part of https://github.com/apache/arrow-rs/issues/9240
    - Related to https://github.com/apache/arrow-rs/issues/9184
    
    This is a backport of the following PR to the 57 line
    - https://github.com/apache/arrow-rs/pull/9234 from @gabotechs
    
    As discussed in https://github.com/apache/arrow-rs/issues/9184, rather
    than sealing the Array trait which broke several downstream crates, this
    PR markes the trait as `unsafe` so that projects have time to find
    alternatives for their use-cases that are now satisfied by a custom
    Array implementation.
    
    Co-authored-by: Gabriel <[email protected]>
---
 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 acea680ae3..a2a7a6c8f3 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 bd85bffcfe..599b140cf6 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 b31c76ab5a..91836054eb 100644
--- a/arrow-array/src/array/byte_view_array.rs
+++ b/arrow-array/src/array/byte_view_array.rs
@@ -854,9 +854,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 be7703b13c..a68ddb22a5 100644
--- a/arrow-array/src/array/dictionary_array.rs
+++ b/arrow-array/src/array/dictionary_array.rs
@@ -697,9 +697,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
     }
@@ -858,9 +857,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 b94e168cfe..18757fc6ac 100644
--- a/arrow-array/src/array/fixed_size_binary_array.rs
+++ b/arrow-array/src/array/fixed_size_binary_array.rs
@@ -602,9 +602,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 3d5e8a0787..070e6617f3 100644
--- a/arrow-array/src/array/fixed_size_list_array.rs
+++ b/arrow-array/src/array/fixed_size_list_array.rs
@@ -462,9 +462,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 225be14ae3..2b3e512234 100644
--- a/arrow-array/src/array/list_array.rs
+++ b/arrow-array/src/array/list_array.rs
@@ -525,9 +525,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 52c88d581d..713d8630f6 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 86608d586f..4ea1b11725 100644
--- a/arrow-array/src/array/map_array.rs
+++ b/arrow-array/src/array/map_array.rs
@@ -361,9 +361,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 75e32d57e8..bb75768af3 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 b682466b67..12fa6435c0 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 457c242814..0ef3520282 100644
--- a/arrow-array/src/array/primitive_array.rs
+++ b/arrow-array/src/array/primitive_array.rs
@@ -1190,9 +1190,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 5254a0ed3c..3e722b7226 100644
--- a/arrow-array/src/array/run_array.rs
+++ b/arrow-array/src/array/run_array.rs
@@ -260,9 +260,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
     }
@@ -521,9 +520,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 6ad1ead0d2..0d86e6305c 100644
--- a/arrow-array/src/array/struct_array.rs
+++ b/arrow-array/src/array/struct_array.rs
@@ -401,9 +401,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 e08542bc86..f7adaa9568 100644
--- a/arrow-array/src/array/union_array.rs
+++ b/arrow-array/src/array/union_array.rs
@@ -738,9 +738,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
     }

Reply via email to