From 8ba03e600ce7407e04a9166ac8d86a02a2161ac1 Mon Sep 17 00:00:00 2001 From: Gabriel <45515538+gabotechs@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:52:36 +0100 Subject: [PATCH] Revert "Seal Array trait (#9092)", mark `Array` as `unsafe` (#9234) This reverts commit 721f373fba7493c873a64421e32f1f67114ac130. # Which issue does this PR close? - Discussed in https://github.com/apache/arrow-rs/issues/9184 - Closes https://github.com/apache/arrow-rs/issues/9184 # Rationale for this change 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? Clean revert of https://github.com/apache/arrow-rs/pull/9092 # Are these changes tested? Not applicable here # Are there any user-facing changes? Yes, users can no implement the `Array` trait in their codebases again. --- 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 +++---- .../src/array/fixed_size_binary_array.rs | 5 ++-- .../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 acea680ae374..a2a7a6c8f38c 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 bd85bffcfe44..599b140cf6ae 100644 --- a/arrow-array/src/array/byte_array.rs +++ b/arrow-array/src/array/byte_array.rs @@ -462,9 +462,8 @@ impl std::fmt::Debug for GenericByteArray { } } -impl super::private::Sealed for GenericByteArray {} - -impl Array for GenericByteArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for GenericByteArray { 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 b31c76ab5a27..91836054ebea 100644 --- a/arrow-array/src/array/byte_view_array.rs +++ b/arrow-array/src/array/byte_view_array.rs @@ -854,9 +854,8 @@ impl Debug for GenericByteViewArray { } } -impl super::private::Sealed for GenericByteViewArray {} - -impl Array for GenericByteViewArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for GenericByteViewArray { 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 be7703b13c5c..a68ddb22a5bf 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 } } -impl super::private::Sealed for DictionaryArray {} - -impl Array for DictionaryArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for DictionaryArray { fn as_any(&self) -> &dyn Any { self } @@ -858,9 +857,7 @@ impl<'a, K: ArrowDictionaryKeyType, V> TypedDictionaryArray<'a, K, V> { } } -impl super::private::Sealed for TypedDictionaryArray<'_, K, V> {} - -impl Array for TypedDictionaryArray<'_, K, V> { +unsafe impl 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 b94e168cfe7c..18757fc6aceb 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 3d5e8a0787c2..070e6617f350 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 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 225be14ae365..2b3e5122348b 100644 --- a/arrow-array/src/array/list_array.rs +++ b/arrow-array/src/array/list_array.rs @@ -525,9 +525,8 @@ impl GenericListArray { } } -impl super::private::Sealed for GenericListArray {} - -impl Array for GenericListArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for GenericListArray { 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 52c88d581d20..713d8630f6ff 100644 --- a/arrow-array/src/array/list_view_array.rs +++ b/arrow-array/src/array/list_view_array.rs @@ -415,9 +415,8 @@ impl ArrayAccessor for &GenericListViewArray super::private::Sealed for GenericListViewArray {} - -impl Array for GenericListViewArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for GenericListViewArray { 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 86608d586f34..4ea1b11725aa 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 75e32d57e89c..bb75768af360 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 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; -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 Array for &T { +unsafe impl 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 b682466b6738..12fa6435c0fc 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 457c2428145e..0ef35202821f 100644 --- a/arrow-array/src/array/primitive_array.rs +++ b/arrow-array/src/array/primitive_array.rs @@ -1190,9 +1190,8 @@ impl From> for ArrayData { } } -impl super::private::Sealed for PrimitiveArray {} - -impl Array for PrimitiveArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for PrimitiveArray { 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 5254a0ed3cdc..3e722b72266c 100644 --- a/arrow-array/src/array/run_array.rs +++ b/arrow-array/src/array/run_array.rs @@ -260,9 +260,8 @@ impl From> for ArrayData { } } -impl super::private::Sealed for RunArray {} - -impl Array for RunArray { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl Array for RunArray { fn as_any(&self) -> &dyn Any { self } @@ -521,9 +520,8 @@ impl<'a, R: RunEndIndexType, V> TypedRunArray<'a, R, V> { } } -impl super::private::Sealed for TypedRunArray<'_, R, V> {} - -impl Array for TypedRunArray<'_, R, V> { +/// SAFETY: Correctly implements the contract of Arrow Arrays +unsafe impl 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 6ad1ead0d250..0d86e6305c06 100644 --- a/arrow-array/src/array/struct_array.rs +++ b/arrow-array/src/array/struct_array.rs @@ -401,9 +401,8 @@ impl TryFrom> 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 e08542bc8638..f7adaa9568b5 100644 --- a/arrow-array/src/array/union_array.rs +++ b/arrow-array/src/array/union_array.rs @@ -738,9 +738,8 @@ impl From 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 }