diff --git a/src/array/dictionary/mod.rs b/src/array/dictionary/mod.rs index 53243208fb..8dc1bbd7c9 100644 --- a/src/array/dictionary/mod.rs +++ b/src/array/dictionary/mod.rs @@ -24,7 +24,11 @@ use super::{new_empty_array, primitive::PrimitiveArray, Array}; use super::{new_null_array, specification::check_indexes}; /// Trait denoting [`NativeType`]s that can be used as keys of a dictionary. -pub trait DictionaryKey: NativeType + TryInto + TryFrom { +/// # Safety +/// +/// Any implementation of this trait must ensure that `always_fits_usize` only +/// returns `true` if all values succeeds on `value::try_into::().unwrap()`. +pub unsafe trait DictionaryKey: NativeType + TryInto + TryFrom { /// The corresponding [`IntegerType`] of this key const KEY_TYPE: IntegerType; @@ -39,45 +43,46 @@ pub trait DictionaryKey: NativeType + TryInto + TryFrom { } } + /// If the key type always can be converted to `usize`. fn always_fits_usize() -> bool { false } } -impl DictionaryKey for i8 { +unsafe impl DictionaryKey for i8 { const KEY_TYPE: IntegerType = IntegerType::Int8; } -impl DictionaryKey for i16 { +unsafe impl DictionaryKey for i16 { const KEY_TYPE: IntegerType = IntegerType::Int16; } -impl DictionaryKey for i32 { +unsafe impl DictionaryKey for i32 { const KEY_TYPE: IntegerType = IntegerType::Int32; } -impl DictionaryKey for i64 { +unsafe impl DictionaryKey for i64 { const KEY_TYPE: IntegerType = IntegerType::Int64; } -impl DictionaryKey for u8 { +unsafe impl DictionaryKey for u8 { const KEY_TYPE: IntegerType = IntegerType::UInt8; fn always_fits_usize() -> bool { true } } -impl DictionaryKey for u16 { +unsafe impl DictionaryKey for u16 { const KEY_TYPE: IntegerType = IntegerType::UInt16; fn always_fits_usize() -> bool { true } } -impl DictionaryKey for u32 { +unsafe impl DictionaryKey for u32 { const KEY_TYPE: IntegerType = IntegerType::UInt32; fn always_fits_usize() -> bool { true } } -impl DictionaryKey for u64 { +unsafe impl DictionaryKey for u64 { const KEY_TYPE: IntegerType = IntegerType::UInt64; #[cfg(target_pointer_width = "64")] @@ -145,7 +150,7 @@ impl DictionaryArray { if K::always_fits_usize() { // safety: we just checked that conversion to `usize` always // succeeds - unsafe { check_indexes_unchecked(keys.values(), len) }?; + unsafe { check_indexes_unchecked(keys.values(), values.len()) }?; } else { check_indexes(keys.values(), values.len())?; }