From 16d7b1bccadf62c58067e44fbfb66357dcd9b2ba Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 09:41:09 +0200 Subject: [PATCH 01/17] Enable ten clippy lints that have no violations None of these fire on the current code base, so this is purely a guard against future regressions: * `coerce_container_to_any` - catches `Box>` upcasts that can never match * `decimal_bitwise_operands` - catches bitwise operators on decimal literals * `doc_broken_link` - catches malformed links in docs * `duration_suboptimal_units` - prefer the clearest `Duration` constructor * `empty_enums` - suggests a never type instead * `ip_constant` - prefer the named IP address constants * `manual_ilog2` - prefer `ilog2` over a hand-rolled version * `needless_type_cast` - catches casts to the same type * `self_only_used_in_recursion` - catches parameters that do nothing but get passed along * `unchecked_time_subtraction` - catches `Instant` subtraction that can panic --- Cargo.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 535caae8d9ae..11e970801b92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,15 +159,20 @@ assigning_clones = "warn" bool_to_int_with_if = "warn" checked_conversions = "warn" clear_with_drain = "warn" +coerce_container_to_any = "warn" comparison_chain = "warn" dbg_macro = "warn" debug_assert_with_mut_call = "warn" +decimal_bitwise_operands = "warn" default_union_representation = "warn" disallowed_script_idents = "warn" +doc_broken_link = "warn" doc_comment_double_space_linebreaks = "warn" doc_include_without_cfg = "warn" doc_link_with_quotes = "warn" +duration_suboptimal_units = "warn" empty_enum_variants_with_brackets = "warn" +empty_enums = "warn" equatable_if_let = "warn" exit = "warn" expl_impl_clone_on_copy = "warn" @@ -187,6 +192,7 @@ inefficient_to_string = "warn" infinite_loop = "warn" into_iter_without_iter = "warn" invalid_upcast_comparisons = "warn" +ip_constant = "warn" iter_filter_is_ok = "warn" iter_filter_is_some = "warn" iter_not_returning_iterator = "warn" @@ -202,6 +208,7 @@ linkedlist = "warn" literal_string_with_formatting_args = "warn" lossy_float_literal = "warn" macro_use_imports = "warn" +manual_ilog2 = "warn" manual_instant_elapsed = "warn" manual_is_power_of_two = "warn" manual_is_variant_and = "warn" @@ -212,6 +219,7 @@ mismatching_type_param_order = "warn" mut_mut = "warn" mutex_integer = "warn" needless_raw_string_hashes = "warn" +needless_type_cast = "warn" negative_feature_names = "warn" non_zero_suggestions = "warn" nonstandard_macro_braces = "warn" @@ -229,6 +237,7 @@ ref_option_ref = "warn" rest_pat_in_fully_bound_structs = "warn" same_functions_in_if_condition = "warn" same_length_and_capacity = "warn" +self_only_used_in_recursion = "warn" set_contains_or_insert = "warn" should_panic_without_expect = "warn" single_char_pattern = "warn" @@ -243,6 +252,7 @@ trailing_empty_array = "warn" trait_duplication_in_bounds = "warn" transmute_ptr_to_ptr = "warn" tuple_array_conversions = "warn" +unchecked_time_subtraction = "warn" uninhabited_references = "warn" unnecessary_box_returns = "warn" unnecessary_literal_bound = "warn" From aad785f053c829c0b479a0b5c9ab81301d448017 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 09:46:26 +0200 Subject: [PATCH 02/17] Enable `clippy::branches_sharing_code` Hoists the code that every branch of an `if`/`else` shares out of the branches, which removes seven copy-pasted blocks. --- Cargo.toml | 1 + .../src/builder/fixed_size_list_builder.rs | 9 ++--- arrow-data/src/equal/fixed_binary.rs | 9 +++-- arrow-data/src/equal/list_view.rs | 36 ++++--------------- arrow-data/src/equal/primitive.rs | 9 +++-- .../src/arrow/array_reader/byte_view_array.rs | 3 +- .../arrow/arrow_reader/selection/ranges.rs | 6 ++-- parquet/src/encodings/decoding.rs | 4 +-- 8 files changed, 23 insertions(+), 54 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 11e970801b92..35c85ebf163f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -157,6 +157,7 @@ missing_crate_level_docs = "warn" as_ptr_cast_mut = "warn" assigning_clones = "warn" bool_to_int_with_if = "warn" +branches_sharing_code = "warn" checked_conversions = "warn" clear_with_drain = "warn" coerce_container_to_any = "warn" diff --git a/arrow-array/src/builder/fixed_size_list_builder.rs b/arrow-array/src/builder/fixed_size_list_builder.rs index 1ad2f7aeaa31..378d7ee3dc7d 100644 --- a/arrow-array/src/builder/fixed_size_list_builder.rs +++ b/arrow-array/src/builder/fixed_size_list_builder.rs @@ -281,17 +281,14 @@ mod tests { builder.append(true); } + builder.values().append_value(3); if include_null_in_values { - builder.values().append_value(3); builder.values().append_null(); - builder.values().append_value(5); - builder.append(true); } else { - builder.values().append_value(3); builder.values().append_value(4); - builder.values().append_value(5); - builder.append(true); } + builder.values().append_value(5); + builder.append(true); builder } diff --git a/arrow-data/src/equal/fixed_binary.rs b/arrow-data/src/equal/fixed_binary.rs index 8d29a2684db8..497e138d8a01 100644 --- a/arrow-data/src/equal/fixed_binary.rs +++ b/arrow-data/src/equal/fixed_binary.rs @@ -47,10 +47,11 @@ pub(super) fn fixed_binary_equal( } else { let selectivity_frac = lhs.null_count() as f64 / lhs.len() as f64; + // get a ref of the null buffer bytes, to use in testing for nullness + let lhs_nulls = lhs.nulls().unwrap(); + let rhs_nulls = rhs.nulls().unwrap(); + if selectivity_frac >= NULL_SLICES_SELECTIVITY_THRESHOLD { - // get a ref of the null buffer bytes, to use in testing for nullness - let lhs_nulls = lhs.nulls().unwrap(); - let rhs_nulls = rhs.nulls().unwrap(); // with nulls, we need to compare item by item whenever it is not null (0..len).all(|i| { let lhs_pos = lhs_start + i; @@ -70,10 +71,8 @@ pub(super) fn fixed_binary_equal( ) }) } else { - let lhs_nulls = lhs.nulls().unwrap(); let lhs_slices_iter = BitSliceIterator::new(lhs_nulls.validity(), lhs_start + lhs_nulls.offset(), len); - let rhs_nulls = rhs.nulls().unwrap(); let rhs_slices_iter = BitSliceIterator::new(rhs_nulls.validity(), rhs_start + rhs_nulls.offset(), len); diff --git a/arrow-data/src/equal/list_view.rs b/arrow-data/src/equal/list_view.rs index c7cb31db9099..f431e84589df 100644 --- a/arrow-data/src/equal/list_view.rs +++ b/arrow-data/src/equal/list_view.rs @@ -44,27 +44,19 @@ pub(super) fn list_view_equal( return false; } + // All four slices are `len` long + let lhs_range_sizes = &lhs_sizes[lhs_start..lhs_start + len]; + let rhs_range_sizes = &rhs_sizes[rhs_start..rhs_start + len]; + let lhs_range_offsets = &lhs_offsets[lhs_start..lhs_start + len]; + let rhs_range_offsets = &rhs_offsets[rhs_start..rhs_start + len]; + if lhs_null_count == 0 { // non-null pathway: all sizes must be equal, and all values must be equal - let lhs_range_sizes = &lhs_sizes[lhs_start..lhs_start + len]; - let rhs_range_sizes = &rhs_sizes[rhs_start..rhs_start + len]; - - if lhs_range_sizes.len() != rhs_range_sizes.len() { - return false; - } - if lhs_range_sizes != rhs_range_sizes { return false; } // Check values for equality - let lhs_range_offsets = &lhs_offsets[lhs_start..lhs_start + len]; - let rhs_range_offsets = &rhs_offsets[rhs_start..rhs_start + len]; - - if lhs_range_offsets.len() != rhs_range_offsets.len() { - return false; - } - for ((&lhs_offset, &rhs_offset), &size) in lhs_range_offsets .iter() .zip(rhs_range_offsets) @@ -81,26 +73,10 @@ pub(super) fn list_view_equal( } } else { // Need to integrate validity check in the inner loop. - // non-null pathway: all sizes must be equal, and all values must be equal - let lhs_range_sizes = &lhs_sizes[lhs_start..lhs_start + len]; - let rhs_range_sizes = &rhs_sizes[rhs_start..rhs_start + len]; - let lhs_nulls = lhs.nulls().unwrap().slice(lhs_start, len); let rhs_nulls = rhs.nulls().unwrap().slice(rhs_start, len); - // Sizes can differ if values are null - if lhs_range_sizes.len() != rhs_range_sizes.len() { - return false; - } - // Check values for equality, with null checking - let lhs_range_offsets = &lhs_offsets[lhs_start..lhs_start + len]; - let rhs_range_offsets = &rhs_offsets[rhs_start..rhs_start + len]; - - if lhs_range_offsets.len() != rhs_range_offsets.len() { - return false; - } - for (index, ((&lhs_offset, &rhs_offset), &size)) in lhs_range_offsets .iter() .zip(rhs_range_offsets) diff --git a/arrow-data/src/equal/primitive.rs b/arrow-data/src/equal/primitive.rs index e92fdd2ba23b..bd7e57eaa952 100644 --- a/arrow-data/src/equal/primitive.rs +++ b/arrow-data/src/equal/primitive.rs @@ -50,10 +50,11 @@ pub(super) fn primitive_equal( } else { let selectivity_frac = lhs.null_count() as f64 / lhs.len() as f64; + // get a ref of the null buffer bytes, to use in testing for nullness + let lhs_nulls = lhs.nulls().unwrap(); + let rhs_nulls = rhs.nulls().unwrap(); + if selectivity_frac >= NULL_SLICES_SELECTIVITY_THRESHOLD { - // get a ref of the null buffer bytes, to use in testing for nullness - let lhs_nulls = lhs.nulls().unwrap(); - let rhs_nulls = rhs.nulls().unwrap(); // with nulls, we need to compare item by item whenever it is not null (0..len).all(|i| { let lhs_pos = lhs_start + i; @@ -72,10 +73,8 @@ pub(super) fn primitive_equal( ) }) } else { - let lhs_nulls = lhs.nulls().unwrap(); let lhs_slices_iter = BitSliceIterator::new(lhs_nulls.validity(), lhs_start + lhs_nulls.offset(), len); - let rhs_nulls = rhs.nulls().unwrap(); let rhs_slices_iter = BitSliceIterator::new(rhs_nulls.validity(), rhs_start + rhs_nulls.offset(), len); diff --git a/parquet/src/arrow/array_reader/byte_view_array.rs b/parquet/src/arrow/array_reader/byte_view_array.rs index cc1abf7ff621..b8595f723318 100644 --- a/parquet/src/arrow/array_reader/byte_view_array.rs +++ b/parquet/src/arrow/array_reader/byte_view_array.rs @@ -529,7 +529,6 @@ impl ByteViewArrayDecoderDictionary { 0 } })); - Ok(()) } else { output .views @@ -551,8 +550,8 @@ impl ByteViewArrayDecoderDictionary { 0 } })); - Ok(()) } + Ok(()) })?; if let Some(e) = error { return Err(e); diff --git a/parquet/src/arrow/arrow_reader/selection/ranges.rs b/parquet/src/arrow/arrow_reader/selection/ranges.rs index 4c7860d095fa..acf805c9faad 100644 --- a/parquet/src/arrow/arrow_reader/selection/ranges.rs +++ b/parquet/src/arrow/arrow_reader/selection/ranges.rs @@ -100,9 +100,7 @@ where let mut row_offset = 0; for selector in selectors { - if selector.skip { - row_offset += selector.row_count; - } else { + if !selector.skip { let start = row_offset; let end = row_offset + selector.row_count; @@ -113,8 +111,8 @@ where let expanded_end = expanded_end.min(total_rows); expanded_ranges.push(expanded_start..expanded_end); - row_offset += selector.row_count; } + row_offset += selector.row_count; } // Sort ranges by start position diff --git a/parquet/src/encodings/decoding.rs b/parquet/src/encodings/decoding.rs index 1e117799adcf..4d902a96e678 100644 --- a/parquet/src/encodings/decoding.rs +++ b/parquet/src/encodings/decoding.rs @@ -2266,14 +2266,14 @@ mod tests { let mut decoder = get_decoder::(col_descr, encoding).expect("get decoder"); decoder.set_data(bytes, data.len()).expect("ok to set data"); + let skipped = decoder.skip(skip).expect("ok to skip"); + if skip >= data.len() { - let skipped = decoder.skip(skip).expect("ok to skip"); assert_eq!(skipped, data.len()); let skipped_again = decoder.skip(skip).expect("ok to skip again"); assert_eq!(skipped_again, 0); } else { - let skipped = decoder.skip(skip).expect("ok to skip"); assert_eq!(skipped, skip); let remaining = data.len() - skip; From c1af44b9ab2235349ec0dfa93bcae6d827d80aef Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 09:48:19 +0200 Subject: [PATCH 03/17] Enable `clippy::iter_without_into_iter` Types with an `iter` method should also implement `IntoIterator` for their reference type, so that `for x in &collection` works. Adds the missing impls for `FixedSizeListArray`, `GenericListArray`, `GenericListViewArray`, `MapArray`, `BitChunks`, `UnalignedBitChunk` and `VariantArray`. --- Cargo.toml | 1 + arrow-array/src/array/fixed_size_list_array.rs | 9 +++++++++ arrow-array/src/array/list_array.rs | 9 +++++++++ arrow-array/src/array/list_view_array.rs | 9 +++++++++ arrow-array/src/array/map_array.rs | 9 +++++++++ arrow-buffer/src/util/bit_chunk_iterator.rs | 18 ++++++++++++++++++ parquet-variant-compute/src/variant_array.rs | 9 +++++++++ 7 files changed, 64 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 35c85ebf163f..18dcc82c29f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -199,6 +199,7 @@ iter_filter_is_some = "warn" iter_not_returning_iterator = "warn" iter_on_empty_collections = "warn" iter_with_drain = "warn" +iter_without_into_iter = "warn" large_digit_groups = "warn" large_futures = "warn" large_include_file = "warn" diff --git a/arrow-array/src/array/fixed_size_list_array.rs b/arrow-array/src/array/fixed_size_list_array.rs index 9cecc309971d..ab28255d4ce0 100644 --- a/arrow-array/src/array/fixed_size_list_array.rs +++ b/arrow-array/src/array/fixed_size_list_array.rs @@ -452,6 +452,15 @@ impl FixedSizeListArray { } } +impl<'a> IntoIterator for &'a FixedSizeListArray { + type Item = Option; + type IntoIter = FixedSizeListIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + FixedSizeListIter::new(self) + } +} + impl From for FixedSizeListArray { fn from(data: ArrayData) -> Self { let (data_type, len, nulls, offset, _buffers, child_data) = data.into_parts(); diff --git a/arrow-array/src/array/list_array.rs b/arrow-array/src/array/list_array.rs index 69c642b97782..4dec674671bc 100644 --- a/arrow-array/src/array/list_array.rs +++ b/arrow-array/src/array/list_array.rs @@ -667,6 +667,15 @@ impl super::ListLikeArray for GenericListArray IntoIterator for &'a GenericListArray { + type Item = Option; + type IntoIter = GenericListArrayIter<'a, OffsetSize>; + + fn into_iter(self) -> Self::IntoIter { + GenericListArrayIter::<'a, OffsetSize>::new(self) + } +} + impl ArrayAccessor for &GenericListArray { type Item = ArrayRef; diff --git a/arrow-array/src/array/list_view_array.rs b/arrow-array/src/array/list_view_array.rs index 8e7765be703b..13b25fdb4832 100644 --- a/arrow-array/src/array/list_view_array.rs +++ b/arrow-array/src/array/list_view_array.rs @@ -432,6 +432,15 @@ impl GenericListViewArray { } } +impl<'a, OffsetSize: OffsetSizeTrait> IntoIterator for &'a GenericListViewArray { + type Item = Option; + type IntoIter = GenericListViewArrayIter<'a, OffsetSize>; + + fn into_iter(self) -> Self::IntoIter { + GenericListViewArrayIter::<'a, OffsetSize>::new(self) + } +} + impl ArrayAccessor for &GenericListViewArray { type Item = ArrayRef; diff --git a/arrow-array/src/array/map_array.rs b/arrow-array/src/array/map_array.rs index 7f90f0ffd200..b115a9640704 100644 --- a/arrow-array/src/array/map_array.rs +++ b/arrow-array/src/array/map_array.rs @@ -288,6 +288,15 @@ impl MapArray { } } +impl<'a> IntoIterator for &'a MapArray { + type Item = Option; + type IntoIter = MapArrayIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + MapArrayIter::new(self) + } +} + impl From for MapArray { fn from(data: ArrayData) -> Self { Self::try_new_from_array_data(data) diff --git a/arrow-buffer/src/util/bit_chunk_iterator.rs b/arrow-buffer/src/util/bit_chunk_iterator.rs index 95ef82bd60e5..55a7583f36b5 100644 --- a/arrow-buffer/src/util/bit_chunk_iterator.rs +++ b/arrow-buffer/src/util/bit_chunk_iterator.rs @@ -170,6 +170,15 @@ impl<'a> UnalignedBitChunk<'a> { } } +impl<'a> IntoIterator for &UnalignedBitChunk<'a> { + type Item = u64; + type IntoIter = UnalignedBitChunkIterator<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + /// Iterator over an [`UnalignedBitChunk`] pub type UnalignedBitChunkIterator<'a> = std::iter::Chain< std::iter::Chain, std::iter::Cloned>>, @@ -338,6 +347,15 @@ impl<'a> IntoIterator for BitChunks<'a> { } } +impl<'a> IntoIterator for &BitChunks<'a> { + type Item = u64; + type IntoIter = BitChunkIterator<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + impl Iterator for BitChunkIterator<'_> { type Item = u64; diff --git a/parquet-variant-compute/src/variant_array.rs b/parquet-variant-compute/src/variant_array.rs index 7af504572e5b..4d33b714c88f 100644 --- a/parquet-variant-compute/src/variant_array.rs +++ b/parquet-variant-compute/src/variant_array.rs @@ -539,6 +539,15 @@ impl VariantArray { } } +impl<'a> IntoIterator for &'a VariantArray { + type Item = Option>; + type IntoIter = VariantArrayIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + VariantArrayIter::new(self) + } +} + impl PartialEq for VariantArray { fn eq(&self, other: &Self) -> bool { self.inner == other.inner From 8ffc9730180000bea1b2da344e9a228bba0b861b Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 09:52:20 +0200 Subject: [PATCH 04/17] Enable `clippy::ref_option` `&Option` in an argument position forces the caller to have an owned `Option`; `Option<&T>` does not, and it is one less indirection to read through. All ten sites were private or `pub(crate)`, so no public API changed. --- Cargo.toml | 1 + arrow-avro/src/reader/record.rs | 8 +-- arrow-cast/src/cast/mod.rs | 81 ++++++++++++++++---------- arrow-cast/src/cast/string.rs | 8 +-- arrow-select/src/coalesce/primitive.rs | 9 ++- parquet/benches/arrow_statistics.rs | 6 +- parquet/src/arrow/arrow_writer/mod.rs | 2 +- parquet/src/basic.rs | 12 ++-- parquet/src/column/page_encryption.rs | 2 +- parquet/src/column/writer/mod.rs | 6 +- parquet/src/file/statistics.rs | 19 +++--- parquet/src/file/writer.rs | 2 +- parquet/src/schema/types.rs | 4 +- 13 files changed, 91 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 18dcc82c29f3..99e515611140 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -235,6 +235,7 @@ ptr_offset_by_literal = "warn" pub_without_shorthand = "warn" rc_mutex = "warn" ref_binding_to_reference = "warn" +ref_option = "warn" ref_option_ref = "warn" rest_pat_in_fully_bound_structs = "warn" same_functions_in_if_condition = "warn" diff --git a/arrow-avro/src/reader/record.rs b/arrow-avro/src/reader/record.rs index 9f97a800a015..1d5019e95fed 100644 --- a/arrow-avro/src/reader/record.rs +++ b/arrow-avro/src/reader/record.rs @@ -50,7 +50,7 @@ const DEFAULT_CAPACITY: usize = 1024; /// Macro to decode a decimal payload for a given width and integer type. macro_rules! decode_decimal { ($size:expr, $buf:expr, $builder:expr, $N:expr, $Int:ty) => {{ - let bytes = read_decimal_bytes_be::<{ $N }>($buf, $size)?; + let bytes = read_decimal_bytes_be::<{ $N }>($buf, *$size)?; $builder.append_value(<$Int>::from_be_bytes(bytes)); }}; } @@ -2364,17 +2364,17 @@ fn flush_primitive( #[inline] fn read_decimal_bytes_be( buf: &mut AvroCursor<'_>, - size: &Option, + size: Option, ) -> Result<[u8; N], AvroError> { match size { - Some(n) if *n == N => { + Some(n) if n == N => { let raw = buf.get_fixed(N)?; let mut arr = [0u8; N]; arr.copy_from_slice(raw); Ok(arr) } Some(n) => { - let raw = buf.get_fixed(*n)?; + let raw = buf.get_fixed(n)?; sign_cast_to::(raw) } None => { diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index 942e393ebd2c..3cab0def6b12 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -1277,20 +1277,28 @@ pub fn cast_with_options( Time64(TimeUnit::Nanosecond) => { parse_string::(array, cast_options) } - Timestamp(TimeUnit::Second, to_tz) => { - cast_string_to_timestamp::(array, to_tz, cast_options) - } + Timestamp(TimeUnit::Second, to_tz) => cast_string_to_timestamp::< + i32, + TimestampSecondType, + >(array, to_tz.as_ref(), cast_options), Timestamp(TimeUnit::Millisecond, to_tz) => cast_string_to_timestamp::< i32, TimestampMillisecondType, - >(array, to_tz, cast_options), + >( + array, to_tz.as_ref(), cast_options + ), Timestamp(TimeUnit::Microsecond, to_tz) => cast_string_to_timestamp::< i32, TimestampMicrosecondType, - >(array, to_tz, cast_options), - Timestamp(TimeUnit::Nanosecond, to_tz) => { - cast_string_to_timestamp::(array, to_tz, cast_options) - } + >( + array, to_tz.as_ref(), cast_options + ), + Timestamp(TimeUnit::Nanosecond, to_tz) => cast_string_to_timestamp::< + i32, + TimestampNanosecondType, + >( + array, to_tz.as_ref(), cast_options + ), Interval(IntervalUnit::YearMonth) => { cast_string_to_year_month_interval::(array, cast_options) } @@ -1334,17 +1342,23 @@ pub fn cast_with_options( parse_string_view::(array, cast_options) } Timestamp(TimeUnit::Second, to_tz) => { - cast_view_to_timestamp::(array, to_tz, cast_options) - } - Timestamp(TimeUnit::Millisecond, to_tz) => { - cast_view_to_timestamp::(array, to_tz, cast_options) - } - Timestamp(TimeUnit::Microsecond, to_tz) => { - cast_view_to_timestamp::(array, to_tz, cast_options) - } - Timestamp(TimeUnit::Nanosecond, to_tz) => { - cast_view_to_timestamp::(array, to_tz, cast_options) + cast_view_to_timestamp::(array, to_tz.as_ref(), cast_options) } + Timestamp(TimeUnit::Millisecond, to_tz) => cast_view_to_timestamp::< + TimestampMillisecondType, + >( + array, to_tz.as_ref(), cast_options + ), + Timestamp(TimeUnit::Microsecond, to_tz) => cast_view_to_timestamp::< + TimestampMicrosecondType, + >( + array, to_tz.as_ref(), cast_options + ), + Timestamp(TimeUnit::Nanosecond, to_tz) => cast_view_to_timestamp::< + TimestampNanosecondType, + >( + array, to_tz.as_ref(), cast_options + ), Interval(IntervalUnit::YearMonth) => { cast_view_to_year_month_interval(array, cast_options) } @@ -1396,20 +1410,28 @@ pub fn cast_with_options( Time64(TimeUnit::Nanosecond) => { parse_string::(array, cast_options) } - Timestamp(TimeUnit::Second, to_tz) => { - cast_string_to_timestamp::(array, to_tz, cast_options) - } + Timestamp(TimeUnit::Second, to_tz) => cast_string_to_timestamp::< + i64, + TimestampSecondType, + >(array, to_tz.as_ref(), cast_options), Timestamp(TimeUnit::Millisecond, to_tz) => cast_string_to_timestamp::< i64, TimestampMillisecondType, - >(array, to_tz, cast_options), + >( + array, to_tz.as_ref(), cast_options + ), Timestamp(TimeUnit::Microsecond, to_tz) => cast_string_to_timestamp::< i64, TimestampMicrosecondType, - >(array, to_tz, cast_options), - Timestamp(TimeUnit::Nanosecond, to_tz) => { - cast_string_to_timestamp::(array, to_tz, cast_options) - } + >( + array, to_tz.as_ref(), cast_options + ), + Timestamp(TimeUnit::Nanosecond, to_tz) => cast_string_to_timestamp::< + i64, + TimestampNanosecondType, + >( + array, to_tz.as_ref(), cast_options + ), Interval(IntervalUnit::YearMonth) => { cast_string_to_year_month_interval::(array, cast_options) } @@ -11502,11 +11524,8 @@ mod tests { format_options: FormatOptions::default(), }; - let result = cast_string_to_timestamp::( - &array, - &None::>, - &cast_options, - ); + let result = + cast_string_to_timestamp::(&array, None, &cast_options); let err = result.unwrap_err(); assert_eq!( diff --git a/arrow-cast/src/cast/string.rs b/arrow-cast/src/cast/string.rs index 3c1933519631..b8039e652912 100644 --- a/arrow-cast/src/cast/string.rs +++ b/arrow-cast/src/cast/string.rs @@ -123,7 +123,7 @@ fn parse_string_iter< /// Casts generic string arrays to an ArrowTimestampType (TimeStampNanosecondArray, etc.) pub(crate) fn cast_string_to_timestamp( array: &dyn Array, - to_tz: &Option>, + to_tz: Option<&Arc>, cast_options: &CastOptions, ) -> Result { let array = array.as_string::(); @@ -134,13 +134,13 @@ pub(crate) fn cast_string_to_timestamp cast_string_to_timestamp_impl(array.iter(), &Utc, cast_options)?, }; - Ok(Arc::new(out.with_timezone_opt(to_tz.clone()))) + Ok(Arc::new(out.with_timezone_opt(to_tz.cloned()))) } /// Casts string view arrays to an ArrowTimestampType (TimeStampNanosecondArray, etc.) pub(crate) fn cast_view_to_timestamp( array: &dyn Array, - to_tz: &Option>, + to_tz: Option<&Arc>, cast_options: &CastOptions, ) -> Result { let array = array.as_string_view(); @@ -151,7 +151,7 @@ pub(crate) fn cast_view_to_timestamp( } None => cast_string_to_timestamp_impl(array.iter(), &Utc, cast_options)?, }; - Ok(Arc::new(out.with_timezone_opt(to_tz.clone()))) + Ok(Arc::new(out.with_timezone_opt(to_tz.cloned()))) } fn cast_string_to_timestamp_impl< diff --git a/arrow-select/src/coalesce/primitive.rs b/arrow-select/src/coalesce/primitive.rs index 3fa070d6271d..98df8202369e 100644 --- a/arrow-select/src/coalesce/primitive.rs +++ b/arrow-select/src/coalesce/primitive.rs @@ -121,10 +121,9 @@ impl InProgressPrimitiveArray { #[inline] fn primitive_source( - source: &Option, + source: Option<&ArrayRef>, ) -> Result<&PrimitiveArray, ArrowError> { Ok(source - .as_ref() .ok_or_else(|| { ArrowError::InvalidArgumentError( "Internal Error: InProgressPrimitiveArray: source not set".to_string(), @@ -153,7 +152,7 @@ impl InProgressArray for InProgressPrimitiveArray fn copy_rows(&mut self, offset: usize, len: usize) -> Result<(), ArrowError> { self.ensure_capacity(); - let s = primitive_source::(&self.source)?; + let s = primitive_source::(self.source.as_ref())?; // add nulls if necessary if let Some(nulls) = s.nulls().as_ref() { @@ -176,7 +175,7 @@ impl InProgressArray for InProgressPrimitiveArray match filter.selection() { FilterSelection::Indices(indices) => { self.ensure_capacity(); - let s = primitive_source::(&self.source)?; + let s = primitive_source::(self.source.as_ref())?; append_filtered_nulls(&mut self.nulls, s.nulls(), filter); self.current.reserve(filter.count()); @@ -190,7 +189,7 @@ impl InProgressArray for InProgressPrimitiveArray } FilterSelection::Slices(slices) => { self.ensure_capacity(); - let s = primitive_source::(&self.source)?; + let s = primitive_source::(self.source.as_ref())?; append_filtered_nulls(&mut self.nulls, s.nulls(), filter); self.current.reserve(filter.count()); diff --git a/parquet/benches/arrow_statistics.rs b/parquet/benches/arrow_statistics.rs index 6da816bde9aa..8dd064e86acf 100644 --- a/parquet/benches/arrow_statistics.rs +++ b/parquet/benches/arrow_statistics.rs @@ -61,7 +61,7 @@ impl fmt::Display for TestTypes { fn create_parquet_file( dtype: TestTypes, row_groups: usize, - data_page_row_count_limit: &Option, + data_page_row_count_limit: Option, ) -> NamedTempFile { let schema = match dtype { TestTypes::UInt64 => Arc::new(Schema::new(vec![Field::new("col", DataType::UInt64, true)])), @@ -82,7 +82,7 @@ fn create_parquet_file( let mut props = WriterProperties::builder().set_max_row_group_row_count(Some(row_groups)); if let Some(limit) = data_page_row_count_limit { props = props - .set_data_page_row_count_limit(*limit) + .set_data_page_row_count_limit(limit) .set_statistics_enabled(EnabledStatistics::Page); }; let props = props.build(); @@ -196,7 +196,7 @@ fn criterion_benchmark(c: &mut Criterion) { for dtype in types { for data_page_row_count_limit in &data_page_row_count_limits { - let file = create_parquet_file(dtype.clone(), row_groups, data_page_row_count_limit); + let file = create_parquet_file(dtype.clone(), row_groups, *data_page_row_count_limit); let file = file.reopen().unwrap(); let options = ArrowReaderOptions::new().with_page_index_policy(PageIndexPolicy::from(true)); diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 4ffdb17c964d..2835cf7c6340 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -1368,7 +1368,7 @@ impl ArrowColumnWriterFactory { ) -> Result> { let column_path = column_descriptor.path().string(); let page_encryptor = PageEncryptor::create_if_column_encrypted( - &self.file_encryptor, + self.file_encryptor.as_ref(), self.row_group_index, column_index, &column_path, diff --git a/parquet/src/basic.rs b/parquet/src/basic.rs index ab99f7b6827d..5ad88ef0e908 100644 --- a/parquet/src/basic.rs +++ b/parquet/src/basic.rs @@ -724,7 +724,7 @@ fn split_compression_string(str_setting: &str) -> Result<(&str, Option), Pa } } -fn check_level_is_none(level: &Option) -> Result<(), ParquetError> { +fn check_level_is_none(level: Option) -> Result<(), ParquetError> { if level.is_some() { return Err(ParquetError::General( "compression level is not supported".to_string(), @@ -748,11 +748,11 @@ impl FromStr for Compression { let c = match codec { "UNCOMPRESSED" | "uncompressed" => { - check_level_is_none(&level)?; + check_level_is_none(level)?; Compression::UNCOMPRESSED } "SNAPPY" | "snappy" => { - check_level_is_none(&level)?; + check_level_is_none(level)?; Compression::SNAPPY } "GZIP" | "gzip" => { @@ -760,7 +760,7 @@ impl FromStr for Compression { Compression::GZIP(GzipLevel::try_new(level.try_into()?)?) } "LZO" | "lzo" => { - check_level_is_none(&level)?; + check_level_is_none(level)?; Compression::LZO } "BROTLI" | "brotli" => { @@ -768,7 +768,7 @@ impl FromStr for Compression { Compression::BROTLI(BrotliLevel::try_new(level.try_into()?)?) } "LZ4" | "lz4" => { - check_level_is_none(&level)?; + check_level_is_none(level)?; Compression::LZ4 } "ZSTD" | "zstd" => { @@ -776,7 +776,7 @@ impl FromStr for Compression { Compression::ZSTD(ZstdLevel::try_new(level)?) } "LZ4_RAW" | "lz4_raw" => { - check_level_is_none(&level)?; + check_level_is_none(level)?; Compression::LZ4_RAW } _ => { diff --git a/parquet/src/column/page_encryption.rs b/parquet/src/column/page_encryption.rs index 26df75900ce7..de9506342931 100644 --- a/parquet/src/column/page_encryption.rs +++ b/parquet/src/column/page_encryption.rs @@ -40,7 +40,7 @@ pub(crate) struct PageEncryptor { impl PageEncryptor { /// Create a [`PageEncryptor`] for a column if it should be encrypted pub fn create_if_column_encrypted( - file_encryptor: &Option>, + file_encryptor: Option<&Arc>, row_group_index: usize, column_index: usize, column_path: &str, diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index 52daecf75f14..34d6709e9c01 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -325,7 +325,7 @@ impl ColumnMetrics { /// Sum `page_histogram` into `chunk_histogram` fn update_histogram( chunk_histogram: &mut Option, - page_histogram: &Option, + page_histogram: Option<&LevelHistogram>, ) { if let (Some(page_hist), Some(chunk_hist)) = (page_histogram, chunk_histogram) { chunk_hist.add(page_hist); @@ -337,11 +337,11 @@ impl ColumnMetrics { fn update_from_page_metrics(&mut self, page_metrics: &PageMetrics) { ColumnMetrics::::update_histogram( &mut self.definition_level_histogram, - &page_metrics.definition_level_histogram, + page_metrics.definition_level_histogram.as_ref(), ); ColumnMetrics::::update_histogram( &mut self.repetition_level_histogram, - &page_metrics.repetition_level_histogram, + page_metrics.repetition_level_histogram.as_ref(), ); } diff --git a/parquet/src/file/statistics.rs b/parquet/src/file/statistics.rs index 21932fc3035a..1da2abe5cd61 100644 --- a/parquet/src/file/statistics.rs +++ b/parquet/src/file/statistics.rs @@ -166,7 +166,7 @@ pub(crate) fn from_thrift_page_stats( stats.max_value }; - fn check_len(min: &Option>, max: &Option>, len: usize) -> Result<()> { + fn check_len(min: Option<&[u8]>, max: Option<&[u8]>, len: usize) -> Result<()> { if let Some(min) = min && min.len() < len { @@ -184,13 +184,16 @@ pub(crate) fn from_thrift_page_stats( Ok(()) } - match physical_type { - Type::BOOLEAN => check_len(&min, &max, 1), - Type::INT32 | Type::FLOAT => check_len(&min, &max, 4), - Type::INT64 | Type::DOUBLE => check_len(&min, &max, 8), - Type::INT96 => check_len(&min, &max, 12), - _ => Ok(()), - }?; + { + let (min, max) = (min.as_deref(), max.as_deref()); + match physical_type { + Type::BOOLEAN => check_len(min, max, 1), + Type::INT32 | Type::FLOAT => check_len(min, max, 4), + Type::INT64 | Type::DOUBLE => check_len(min, max, 8), + Type::INT96 => check_len(min, max, 12), + _ => Ok(()), + }?; + } // Values are encoded using PLAIN encoding definition, except that // variable-length byte arrays do not include a length prefix. diff --git a/parquet/src/file/writer.rs b/parquet/src/file/writer.rs index cc2e36b50fd2..730aa0fe8e92 100644 --- a/parquet/src/file/writer.rs +++ b/parquet/src/file/writer.rs @@ -926,7 +926,7 @@ impl<'a, W: Write + Send> SerializedRowGroupWriter<'a, W> { page_writer: SerializedPageWriter<'b, W>, ) -> Result> { let page_encryptor = PageEncryptor::create_if_column_encrypted( - &context.file_encryptor, + context.file_encryptor.as_ref(), context.row_group_index, context.column_index, &column.path().string(), diff --git a/parquet/src/schema/types.rs b/parquet/src/schema/types.rs index c7e66231fa5c..a545affbfddb 100644 --- a/parquet/src/schema/types.rs +++ b/parquet/src/schema/types.rs @@ -1268,7 +1268,7 @@ fn build_tree<'a>( } /// Checks if the logical type is valid. -fn check_logical_type(logical_type: &Option) -> Result<()> { +fn check_logical_type(logical_type: Option<&LogicalType>) -> Result<()> { if let Some(LogicalType::Integer(IntType { bit_width, .. })) = logical_type && *bit_width != 8 && *bit_width != 16 @@ -1341,7 +1341,7 @@ fn schema_from_array_helper<'a>( // LogicalType is prefered to ConvertedType, but both may be present. let logical_type = element.logical_type; - check_logical_type(&logical_type)?; + check_logical_type(logical_type.as_ref())?; let field_id = element.field_id; match element.num_children { From ca5f09f9261f546fe76695bc9dfa0da7dba844ec Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 09:53:50 +0200 Subject: [PATCH 05/17] Enable `clippy::or_fun_call` Makes the fallback of `unwrap_or`/`or`/`ok_or`/`map_or` lazy, so that the eleven sites that built an error, a `String` or a cursor only do that work when the fallback is actually taken. --- Cargo.toml | 1 + arrow-cast/src/parse.rs | 2 +- arrow-cast/src/pretty.rs | 2 +- arrow-flight/src/client.rs | 12 ++++++------ arrow-string/src/binary_like.rs | 2 +- arrow-string/src/like.rs | 2 +- parquet/examples/write_parquet.rs | 2 +- parquet/src/arrow/arrow_reader/read_plan.rs | 2 +- parquet/src/basic.rs | 2 +- parquet/src/column/writer/mod.rs | 2 +- parquet/src/compression.rs | 2 +- 11 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 99e515611140..7659c371f245 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -227,6 +227,7 @@ non_zero_suggestions = "warn" nonstandard_macro_braces = "warn" option_as_ref_cloned = "warn" option_option = "warn" +or_fun_call = "warn" path_buf_push_overwrite = "warn" pathbuf_init_then_push = "warn" precedence_bits = "warn" diff --git a/arrow-cast/src/parse.rs b/arrow-cast/src/parse.rs index 2db047359ab6..959922873bf5 100644 --- a/arrow-cast/src/parse.rs +++ b/arrow-cast/src/parse.rs @@ -1840,7 +1840,7 @@ mod tests { for case in cases { let v = date32_to_datetime(Date32Type::parse(case).unwrap()).unwrap(); let expected = NaiveDate::parse_from_str(case, "%Y-%m-%d") - .or(NaiveDate::parse_from_str(case, "%Y-%m-%d %H:%M:%S")) + .or_else(|_| NaiveDate::parse_from_str(case, "%Y-%m-%d %H:%M:%S")) .unwrap(); assert_eq!(v.date(), expected); } diff --git a/arrow-cast/src/pretty.rs b/arrow-cast/src/pretty.rs index fc0a7259c055..98dd605d7ee9 100644 --- a/arrow-cast/src/pretty.rs +++ b/arrow-cast/src/pretty.rs @@ -206,7 +206,7 @@ fn create_table( } for batch in results { - let schema = schema_opt.as_ref().unwrap_or(batch.schema_ref()); + let schema = schema_opt.as_ref().unwrap_or_else(|| batch.schema_ref()); // Could be a custom schema that was provided. if batch.columns().len() != schema.fields().len() { diff --git a/arrow-flight/src/client.rs b/arrow-flight/src/client.rs index b2059a81d0df..cd5a34730a65 100644 --- a/arrow-flight/src/client.rs +++ b/arrow-flight/src/client.rs @@ -625,9 +625,9 @@ where ) -> Result { let action = Action::new("CancelFlightInfo", request.encode_to_vec()); let response = self.do_action(action).await?.try_next().await?; - let response = response.ok_or(FlightError::protocol( - "Received no response for cancel_flight_info call", - ))?; + let response = response.ok_or_else(|| { + FlightError::protocol("Received no response for cancel_flight_info call") + })?; CancelFlightInfoResult::decode(response) .map_err(|e| FlightError::DecodeError(e.to_string())) } @@ -664,9 +664,9 @@ where ) -> Result { let action = Action::new("RenewFlightEndpoint", request.encode_to_vec()); let response = self.do_action(action).await?.try_next().await?; - let response = response.ok_or(FlightError::protocol( - "Received no response for renew_flight_endpoint call", - ))?; + let response = response.ok_or_else(|| { + FlightError::protocol("Received no response for renew_flight_endpoint call") + })?; FlightEndpoint::decode(response).map_err(|e| FlightError::DecodeError(e.to_string())) } diff --git a/arrow-string/src/binary_like.rs b/arrow-string/src/binary_like.rs index 3759ff85737a..1e67a03a85d1 100644 --- a/arrow-string/src/binary_like.rs +++ b/arrow-string/src/binary_like.rs @@ -65,7 +65,7 @@ pub(crate) fn binary_apply<'a, T: BinaryArrayType<'a> + 'a>( r_s: bool, r_v: Option<&'a dyn AnyDictionaryArray>, ) -> Result { - let l_len = l_v.map(|l| l.len()).unwrap_or(l.len()); + let l_len = l_v.map_or_else(|| l.len(), |l| l.len()); if r_s { let idx = match r_v { Some(dict) if dict.null_count() != 0 => return Ok(BooleanArray::new_null(l_len)), diff --git a/arrow-string/src/like.rs b/arrow-string/src/like.rs index 5fc75d81c9b6..4c2ef88d4068 100644 --- a/arrow-string/src/like.rs +++ b/arrow-string/src/like.rs @@ -304,7 +304,7 @@ fn string_apply<'a, T: StringArrayType<'a> + 'a>( r_s: bool, r_v: Option<&'a dyn AnyDictionaryArray>, ) -> Result { - let l_len = l_v.map(|l| l.len()).unwrap_or(l.len()); + let l_len = l_v.map_or_else(|| l.len(), |l| l.len()); if r_s { let idx = match r_v { Some(dict) if dict.null_count() != 0 => return Ok(BooleanArray::new_null(l_len)), diff --git a/parquet/examples/write_parquet.rs b/parquet/examples/write_parquet.rs index 803f29da38c9..8b704c2e0222 100644 --- a/parquet/examples/write_parquet.rs +++ b/parquet/examples/write_parquet.rs @@ -76,7 +76,7 @@ fn mem(system: &mut System) -> String { system .process(pid) .map(|proc| format!("{}MB", proc.memory() / 1_000_000)) - .unwrap_or("N/A".to_string()) + .unwrap_or_else(|| "N/A".to_string()) } fn main() -> Result<()> { diff --git a/parquet/src/arrow/arrow_reader/read_plan.rs b/parquet/src/arrow/arrow_reader/read_plan.rs index a05024dac0d6..63e1b1ce351c 100644 --- a/parquet/src/arrow/arrow_reader/read_plan.rs +++ b/parquet/src/arrow/arrow_reader/read_plan.rs @@ -308,7 +308,7 @@ impl ReadPlanBuilder { let row_selection_cursor = selection .map(|s| build_cursor(s.trim(), selection_strategy, loaded_row_ranges)) - .unwrap_or(RowSelectionCursor::new_all()); + .unwrap_or_else(RowSelectionCursor::new_all); ReadPlan { batch_size, diff --git a/parquet/src/basic.rs b/parquet/src/basic.rs index 5ad88ef0e908..af2d4c492ede 100644 --- a/parquet/src/basic.rs +++ b/parquet/src/basic.rs @@ -249,7 +249,7 @@ impl GeographyType { /// /// [specification]: https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#geography pub fn algorithm(&self) -> Option { - self.algorithm.or(Some(Default::default())) + Some(self.algorithm.unwrap_or_default()) } } diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index 34d6709e9c01..66daaade9e0d 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -570,7 +570,7 @@ impl<'a, E: ColumnValueEncoder> GenericColumnWriter<'a, E> { let num_levels = if num_levels > 0 { num_levels } else { - value_indices.map_or(values.len(), |i| i.len()) + value_indices.map_or_else(|| values.len(), |i| i.len()) }; if let Some(min) = min { diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 55783de1c3e4..1a77bfda51e7 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -546,7 +546,7 @@ mod zstd_codec { .flatten() .map(|size| size as usize) }) - .unwrap_or(input_buf.len().saturating_mul(4)); + .unwrap_or_else(|| input_buf.len().saturating_mul(4)); output_buf.reserve(len); let mut cursor = Cursor::new(output_buf); From 735748cc929bf7dbfe0089af82cced6c6f8c815d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 09:56:56 +0200 Subject: [PATCH 06/17] Enable `clippy::ref_as_ptr` `std::ptr::from_ref`/`from_mut` says what the code means and cannot silently change the pointee type, unlike a chain of `as` casts. The generated flatbuffers modules in `arrow-ipc/src/gen` are now exempt from `clippy::pedantic` as well as `clippy::all`: they say "do not modify" at the top, so no pedantic lint can ever be fixed there. --- Cargo.toml | 1 + arrow-array/src/array/byte_view_array.rs | 5 ++++- arrow-array/src/ffi.rs | 4 ++-- arrow-buffer/src/bigint/div.rs | 4 ++-- arrow-buffer/src/native.rs | 2 +- arrow-buffer/src/util/bit_mask.rs | 2 +- arrow-cast/src/display.rs | 2 +- arrow-ipc/src/gen/mod.rs | 12 +++++++----- parquet/src/arrow/buffer/dictionary_buffer.rs | 4 ++-- parquet/src/data_type.rs | 8 +++++--- 10 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7659c371f245..e53f22cf250b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -235,6 +235,7 @@ ptr_cast_constness = "warn" ptr_offset_by_literal = "warn" pub_without_shorthand = "warn" rc_mutex = "warn" +ref_as_ptr = "warn" ref_binding_to_reference = "warn" ref_option = "warn" ref_option_ref = "warn" diff --git a/arrow-array/src/array/byte_view_array.rs b/arrow-array/src/array/byte_view_array.rs index d1b1721034d9..b6eb1805ac48 100644 --- a/arrow-array/src/array/byte_view_array.rs +++ b/arrow-array/src/array/byte_view_array.rs @@ -357,7 +357,10 @@ impl GenericByteViewArray { pub unsafe fn inline_value(view: &u128, len: usize) -> &[u8] { debug_assert!(len <= MAX_INLINE_VIEW_LEN as usize); unsafe { - std::slice::from_raw_parts((view as *const u128 as *const u8).wrapping_add(4), len) + std::slice::from_raw_parts( + (std::ptr::from_ref::(view) as *const u8).wrapping_add(4), + len, + ) } } diff --git a/arrow-array/src/ffi.rs b/arrow-array/src/ffi.rs index 21e309a50d47..07ac0782ceab 100644 --- a/arrow-array/src/ffi.rs +++ b/arrow-array/src/ffi.rs @@ -589,8 +589,8 @@ mod tests_to_then_from_ffi { let schema = Box::new(ManuallyDrop::new(schema)); let array = Box::new(ManuallyDrop::new(array)); - let schema_ptr = &**schema as *const _; - let array_ptr = &**array as *const _; + let schema_ptr = std::ptr::from_ref(&**schema); + let array_ptr = std::ptr::from_ref(&**array); // We can read them back to memory // SAFETY: diff --git a/arrow-buffer/src/bigint/div.rs b/arrow-buffer/src/bigint/div.rs index f094f662ccf8..fb5bf76c0f7d 100644 --- a/arrow-buffer/src/bigint/div.rs +++ b/arrow-buffer/src/bigint/div.rs @@ -289,14 +289,14 @@ impl std::ops::Deref for ArrayPlusOne { #[inline] fn deref(&self) -> &Self::Target { - let x = self as *const Self; + let x = std::ptr::from_ref::(self); unsafe { std::slice::from_raw_parts(x as *const T, N + 1) } } } impl std::ops::DerefMut for ArrayPlusOne { fn deref_mut(&mut self) -> &mut Self::Target { - let x = self as *mut Self; + let x = std::ptr::from_mut::(self); unsafe { std::slice::from_raw_parts_mut(x as *mut T, N + 1) } } } diff --git a/arrow-buffer/src/native.rs b/arrow-buffer/src/native.rs index 68058a4eeccd..72dc32601212 100644 --- a/arrow-buffer/src/native.rs +++ b/arrow-buffer/src/native.rs @@ -281,7 +281,7 @@ impl ToByteSlice for [T] { impl ToByteSlice for T { #[inline] fn to_byte_slice(&self) -> &[u8] { - let raw_ptr = self as *const T as *const u8; + let raw_ptr = std::ptr::from_ref::(self) as *const u8; unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of::()) } } } diff --git a/arrow-buffer/src/util/bit_mask.rs b/arrow-buffer/src/util/bit_mask.rs index d248bd3c56b3..ad55728aae91 100644 --- a/arrow-buffer/src/util/bit_mask.rs +++ b/arrow-buffer/src/util/bit_mask.rs @@ -143,7 +143,7 @@ unsafe fn read_bytes_to_u64(data: &[u8], offset: usize, count: usize) -> u64 { debug_assert!(count <= 8); let mut tmp: u64 = 0; let src = unsafe { data.as_ptr().add(offset) }; - unsafe { std::ptr::copy_nonoverlapping(src, &mut tmp as *mut _ as *mut u8, count) }; + unsafe { std::ptr::copy_nonoverlapping(src, std::ptr::from_mut(&mut tmp) as *mut u8, count) }; tmp } diff --git a/arrow-cast/src/display.rs b/arrow-cast/src/display.rs index 64ba6b7d81f3..96832b6bd7b2 100644 --- a/arrow-cast/src/display.rs +++ b/arrow-cast/src/display.rs @@ -147,7 +147,7 @@ impl Hash for FormatOptions<'_> { self.types_info.hash(state); self.quoted_strings.hash(state); self.formatter_factory - .map(|f| f as *const dyn ArrayFormatterFactory) + .map(std::ptr::from_ref::) .hash(state); } } diff --git a/arrow-ipc/src/gen/mod.rs b/arrow-ipc/src/gen/mod.rs index 37192354edc7..ef7274eb0819 100644 --- a/arrow-ipc/src/gen/mod.rs +++ b/arrow-ipc/src/gen/mod.rs @@ -21,6 +21,8 @@ // The flatbuffers compiler emits redundant `T: 'a` bounds, and lifetime parameters // that some of the generated types never use. This file is not regenerated by // `regen.sh`, so these attributes survive regeneration of the modules below. +// The generated modules are exempt from `clippy::pedantic` for the same reason: +// we cannot fix what we do not write. #![expect( explicit_outlives_requirements, reason = "the flatbuffers compiler emits redundant `T: 'a` bounds" @@ -30,13 +32,13 @@ reason = "the flatbuffers compiler emits lifetime parameters that some generated types never use" )] -#[allow(clippy::all)] +#[allow(clippy::all, clippy::pedantic)] pub mod File; -#[allow(clippy::all)] +#[allow(clippy::all, clippy::pedantic)] pub mod Message; -#[allow(clippy::all)] +#[allow(clippy::all, clippy::pedantic)] pub mod Schema; -#[allow(clippy::all)] +#[allow(clippy::all, clippy::pedantic)] pub mod SparseTensor; -#[allow(clippy::all)] +#[allow(clippy::all, clippy::pedantic)] pub mod Tensor; diff --git a/parquet/src/arrow/buffer/dictionary_buffer.rs b/parquet/src/arrow/buffer/dictionary_buffer.rs index 33537b40f80b..fd0d2102f2e0 100644 --- a/parquet/src/arrow/buffer/dictionary_buffer.rs +++ b/parquet/src/arrow/buffer/dictionary_buffer.rs @@ -62,8 +62,8 @@ impl DictionaryBuffer { // Need to discard fat pointer for equality check // - https://stackoverflow.com/a/67114787 // - https://github.com/rust-lang/rust/issues/46139 - let values_ptr = values.as_ref() as *const _ as *const (); - let dict_ptr = dictionary.as_ref() as *const _ as *const (); + let values_ptr = std::ptr::from_ref(values.as_ref()) as *const (); + let dict_ptr = std::ptr::from_ref(dictionary.as_ref()) as *const (); if values_ptr == dict_ptr { Some(keys) } else if keys.is_empty() { diff --git a/parquet/src/data_type.rs b/parquet/src/data_type.rs index 1558d9cb8059..3af311cfbd62 100644 --- a/parquet/src/data_type.rs +++ b/parquet/src/data_type.rs @@ -554,7 +554,7 @@ macro_rules! gen_as_bytes { // resulting slice always refers to initialized memory. unsafe { std::slice::from_raw_parts( - self as *const $source_ty as *const u8, + std::ptr::from_ref::<$source_ty>(self) as *const u8, std::mem::size_of::<$source_ty>(), ) } @@ -627,14 +627,16 @@ impl AsBytes for bool { fn as_bytes(&self) -> &[u8] { // SAFETY: a bool is guaranteed to be either 0x00 or 0x01 in memory, so the memory is // valid. - unsafe { std::slice::from_raw_parts(self as *const bool as *const u8, 1) } + unsafe { std::slice::from_raw_parts(std::ptr::from_ref::(self) as *const u8, 1) } } } impl AsBytes for Int96 { fn as_bytes(&self) -> &[u8] { // SAFETY: Int96::data is a &[u32; 3]. - unsafe { std::slice::from_raw_parts(self.data() as *const [u32] as *const u8, 12) } + unsafe { + std::slice::from_raw_parts(std::ptr::from_ref::<[u32]>(self.data()) as *const u8, 12) + } } } From 7aa7f377d03bb06fe61259cd904aad622a3fe4eb Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:00:54 +0200 Subject: [PATCH 07/17] Enable `clippy::needless_continue` Removes 25 `continue` statements that were the last thing in their loop body, so they only restated what the loop already does. Two of them, in `arrow-ord::comparison`, become `break`: once a matching list element is found there is nothing left to look for. --- Cargo.toml | 1 + arrow-avro/src/reader/async_reader/mod.rs | 2 -- arrow-cmp/src/lib.rs | 10 +++++----- arrow-ipc/src/reader.rs | 4 +--- arrow-ord/src/comparison.rs | 4 ++-- arrow-ord/src/sort.rs | 4 ++-- arrow-schema/src/datatype_parse.rs | 3 +-- parquet-variant-compute/src/variant_get.rs | 1 - parquet/src/arrow/arrow_reader/selection/ranges.rs | 2 -- parquet/src/arrow/async_reader/mod.rs | 8 ++++---- parquet/src/column/reader.rs | 1 - parquet/src/column/writer/encoder.rs | 2 -- parquet/src/file/metadata/push_decoder.rs | 2 -- 13 files changed, 16 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e53f22cf250b..bd2a28e74c1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -220,6 +220,7 @@ match_wild_err_arm = "warn" mismatching_type_param_order = "warn" mut_mut = "warn" mutex_integer = "warn" +needless_continue = "warn" needless_raw_string_hashes = "warn" needless_type_cast = "warn" negative_feature_names = "warn" diff --git a/arrow-avro/src/reader/async_reader/mod.rs b/arrow-avro/src/reader/async_reader/mod.rs index b98792e1a97a..9a48d7e243e8 100644 --- a/arrow-avro/src/reader/async_reader/mod.rs +++ b/arrow-avro/src/reader/async_reader/mod.rs @@ -363,7 +363,6 @@ impl AsyncAvroFileReader { future, next_behaviour: FetchNextBehaviour::ContinueDecoding, }; - continue; } FetchNextBehaviour::ContinueDecoding => { self.reader_state = ReaderState::DecodingBlock { @@ -482,7 +481,6 @@ impl AsyncAvroFileReader { future, next_behaviour: FetchNextBehaviour::ContinueDecoding, }; - continue; } ReaderState::ReadingBatches { reader, diff --git a/arrow-cmp/src/lib.rs b/arrow-cmp/src/lib.rs index 5620ba710e0a..368ef9921cd2 100644 --- a/arrow-cmp/src/lib.rs +++ b/arrow-cmp/src/lib.rs @@ -250,7 +250,7 @@ fn compare_list( for (i, j) in (l_start..l_end).zip(r_start..r_end) { match cmp(i, j) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } @@ -281,7 +281,7 @@ fn compare_fixed_list( let r_end = r_start + r_size; for (i, j) in (l_start..l_end).zip(r_start..r_end) { match cmp(i, j) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } @@ -317,7 +317,7 @@ fn compare_list_view( for (i, j) in (l_start..l_end).zip(r_start..r_end) { match cmp(i, j) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } @@ -348,7 +348,7 @@ fn compare_map( for (i, j) in (l_start..l_end).zip(r_start..r_end) { match cmp(i, j) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } @@ -380,7 +380,7 @@ fn compare_struct( let f = compare(left, right, opts, move |i, j| { for cmp in &comparators { match cmp(i, j) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs index f3856b1d3274..77f4cb300cd8 100644 --- a/arrow-ipc/src/reader.rs +++ b/arrow-ipc/src/reader.rs @@ -1660,9 +1660,7 @@ impl StreamReader { IpcMessage::RecordBatch(record_batch) => { return Ok(Some(record_batch)); } - IpcMessage::DictionaryBatch { .. } => { - continue; - } + IpcMessage::DictionaryBatch { .. } => {} }; } } diff --git a/arrow-ord/src/comparison.rs b/arrow-ord/src/comparison.rs index 07f40be55e2b..a45a4671b66f 100644 --- a/arrow-ord/src/comparison.rs +++ b/arrow-ord/src/comparison.rs @@ -60,7 +60,7 @@ where for j in 0..list.len() { if list.is_valid(j) && (left.value(i) == list.value(j)) { bit_util::set_bit(bool_slice, i); - continue; + break; } } } @@ -100,7 +100,7 @@ where for j in 0..list.len() { if list.is_valid(j) && (left.value(i) == list.value(j)) { bit_util::set_bit(bool_slice, i); - continue; + break; } } } diff --git a/arrow-ord/src/sort.rs b/arrow-ord/src/sort.rs index f6139ad90296..720da4d56637 100644 --- a/arrow-ord/src/sort.rs +++ b/arrow-ord/src/sort.rs @@ -1132,7 +1132,7 @@ impl LexicographicalComparator { pub fn compare(&self, a_idx: usize, b_idx: usize) -> Ordering { for comparator in &self.compare_items { match comparator(a_idx, b_idx) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } @@ -1168,7 +1168,7 @@ impl FixedLexicographicalComparator { pub fn compare(&self, a_idx: usize, b_idx: usize) -> Ordering { for comparator in &self.compare_items { match comparator(a_idx, b_idx) { - Ordering::Equal => continue, + Ordering::Equal => {} r => return r, } } diff --git a/arrow-schema/src/datatype_parse.rs b/arrow-schema/src/datatype_parse.rs index 9439d8ea2188..c2c607c22fc7 100644 --- a/arrow-schema/src/datatype_parse.rs +++ b/arrow-schema/src/datatype_parse.rs @@ -512,7 +512,7 @@ impl<'a> Parser<'a> { let field = self.parse_field()?; fields.push(Arc::new(field)); match self.next_token()? { - Token::Comma => continue, + Token::Comma => {} Token::RParen => break, tok => { return Err(make_error( @@ -863,7 +863,6 @@ impl Iterator for Tokenizer<'_> { ' ' => { // skip whitespace self.next_char(); - continue; } '"' => { return Some(self.parse_quoted_string(QuoteType::Double)); diff --git a/parquet-variant-compute/src/variant_get.rs b/parquet-variant-compute/src/variant_get.rs index d062d0ff0816..1c3a77627cf3 100644 --- a/parquet-variant-compute/src/variant_get.rs +++ b/parquet-variant-compute/src/variant_get.rs @@ -283,7 +283,6 @@ fn shredded_get_path( } shredding_state = state; path_index += 1; - continue; } ShreddedPathStep::Missing => { let num_rows = input.len(); diff --git a/parquet/src/arrow/arrow_reader/selection/ranges.rs b/parquet/src/arrow/arrow_reader/selection/ranges.rs index acf805c9faad..ac9ee17d9ce8 100644 --- a/parquet/src/arrow/arrow_reader/selection/ranges.rs +++ b/parquet/src/arrow/arrow_reader/selection/ranges.rs @@ -62,8 +62,6 @@ where row_offset += remaining_in_page; current_page = pages.next(); current_page_included = false; - - continue; } else { if row_offset + selector.row_count == next_page.first_row_index as usize { current_page = pages.next(); diff --git a/parquet/src/arrow/async_reader/mod.rs b/parquet/src/arrow/async_reader/mod.rs index 903a3952d079..d386bec48d0b 100644 --- a/parquet/src/arrow/async_reader/mod.rs +++ b/parquet/src/arrow/async_reader/mod.rs @@ -835,7 +835,7 @@ where match self.decoder.try_next_reader()? { DecodeResult::NeedsData(ranges) => { self.request_state = RequestState::begin_request(input, ranges); - continue; // poll again (as the input might be ready immediately) + // Will loop again: the input might be ready immediately. } DecodeResult::Data(reader) => { self.request_state = RequestState::None { input }; @@ -849,7 +849,7 @@ where // Push the requested data to the decoder and try again self.decoder.push_ranges(ranges, data)?; self.request_state = RequestState::None { input }; - continue; // try and decode on next iteration + // Will try and decode on the next iteration. } RequestState::Done => { self.request_state = RequestState::Done; @@ -897,7 +897,7 @@ where match self.decoder.try_decode()? { DecodeResult::NeedsData(ranges) => { self.request_state = RequestState::begin_request(input, ranges); - continue; // poll again (as the input might be ready immediately) + // Will loop again: the input might be ready immediately. } DecodeResult::Data(batch) => { self.request_state = RequestState::None { input }; @@ -916,7 +916,7 @@ where // Push the requested data to the decoder self.decoder.push_ranges(ranges, data)?; self.request_state = RequestState::None { input }; - continue; // next iteration will try to decode the next batch + // The next iteration will try to decode the next batch. } Poll::Pending => { self.request_state = RequestState::Outstanding { ranges, future }; diff --git a/parquet/src/column/reader.rs b/parquet/src/column/reader.rs index 0bf5dd822dbf..39b93b43105a 100644 --- a/parquet/src/column/reader.rs +++ b/parquet/src/column/reader.rs @@ -442,7 +442,6 @@ where } => { self.values_decoder .set_dict(buf, num_values, encoding, is_sorted)?; - continue; } // 2. Data page v1 Page::DataPage { diff --git a/parquet/src/column/writer/encoder.rs b/parquet/src/column/writer/encoder.rs index 9420aa40f7d5..e7b548f0dc78 100644 --- a/parquet/src/column/writer/encoder.rs +++ b/parquet/src/column/writer/encoder.rs @@ -423,14 +423,12 @@ where // skip NaNs if we've encounter non-NaN (false, true) => { nan_count += 1; - continue; } // if min/max are NaN, check for non-NaN and reset (true, false) => { min = val; max = val; min_max_nan = false; - continue; } // both are NaN or non-NaN, so do the comparison (_, val_is_nan) => { diff --git a/parquet/src/file/metadata/push_decoder.rs b/parquet/src/file/metadata/push_decoder.rs index 42545f156555..e70cea23e819 100644 --- a/parquet/src/file/metadata/push_decoder.rs +++ b/parquet/src/file/metadata/push_decoder.rs @@ -383,7 +383,6 @@ impl ParquetMetaDataPushDecoder { let footer_tail = FooterTail::try_from(footer_bytes.as_ref())?; self.state = DecodeState::ReadingMetadata(footer_tail); - continue; } DecodeState::ReadingMetadata(footer_tail) => { @@ -404,7 +403,6 @@ impl ParquetMetaDataPushDecoder { // Note: ReadingPageIndex first checks if page indexes are needed // and is a no-op if not self.state = DecodeState::ReadingPageIndex(Box::new(metadata)); - continue; } DecodeState::ReadingPageIndex(mut metadata) => { From aeac23a2fea9aa5e57c52b0904f5666e0e2c122b Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:03:30 +0200 Subject: [PATCH 08/17] Enable `clippy::redundant_type_annotations` Drops 25 type annotations that only repeated the type of the expression on the right hand side. --- Cargo.toml | 1 + arrow-array/src/array/byte_view_array.rs | 2 +- arrow-array/src/array/struct_array.rs | 2 +- .../src/builder/fixed_size_binary_builder.rs | 6 +++--- arrow-avro/src/reader/mod.rs | 4 ++-- arrow-buffer/src/util/bit_util.rs | 2 +- arrow-cast/src/parse.rs | 2 +- arrow-data/src/data.rs | 2 +- arrow/tests/array_cast.rs | 2 +- parquet-variant/src/builder/metadata.rs | 2 +- parquet/benches/row_selection_cursor.rs | 2 +- .../src/arrow/arrow_reader/selection/boolean.rs | 2 +- parquet/src/column/reader.rs | 4 ++-- parquet/src/encodings/rle.rs | 16 ++++++++-------- parquet/src/file/metadata/mod.rs | 2 +- 15 files changed, 26 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bd2a28e74c1b..f478da803271 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,6 +236,7 @@ ptr_cast_constness = "warn" ptr_offset_by_literal = "warn" pub_without_shorthand = "warn" rc_mutex = "warn" +redundant_type_annotations = "warn" ref_as_ptr = "warn" ref_binding_to_reference = "warn" ref_option = "warn" diff --git a/arrow-array/src/array/byte_view_array.rs b/arrow-array/src/array/byte_view_array.rs index b6eb1805ac48..8f23f8fd443a 100644 --- a/arrow-array/src/array/byte_view_array.rs +++ b/arrow-array/src/array/byte_view_array.rs @@ -1513,7 +1513,7 @@ mod tests { } else { // random length between 0 and twice the inline limit let len = rng.random_range(0..(MAX_INLINE_VIEW_LEN * 2)); - let s: String = "A".repeat(len as usize); + let s = "A".repeat(len as usize); builder.append_option(Some(&s)); original.push(Some(s)); } diff --git a/arrow-array/src/array/struct_array.rs b/arrow-array/src/array/struct_array.rs index 126a3ff4b208..7b734a32b792 100644 --- a/arrow-array/src/array/struct_array.rs +++ b/arrow-array/src/array/struct_array.rs @@ -1023,7 +1023,7 @@ mod tests { #[test] fn test_struct_array_fmt_debug() { - let arr: StructArray = StructArray::new( + let arr = StructArray::new( vec![Arc::new(Field::new("c", DataType::Int32, true))].into(), vec![Arc::new(Int32Array::from((0..30).collect::>())) as ArrayRef], Some(NullBuffer::new(BooleanBuffer::from( diff --git a/arrow-array/src/builder/fixed_size_binary_builder.rs b/arrow-array/src/builder/fixed_size_binary_builder.rs index b033ed0ff389..8544e70c6aa6 100644 --- a/arrow-array/src/builder/fixed_size_binary_builder.rs +++ b/arrow-array/src/builder/fixed_size_binary_builder.rs @@ -201,7 +201,7 @@ mod tests { builder.append_value(b"arrow").unwrap(); builder.append_nulls(2); builder.append_value(b"world").unwrap(); - let array: FixedSizeBinaryArray = builder.finish(); + let array = builder.finish(); assert_eq!(&DataType::FixedSizeBinary(5), array.data_type()); assert_eq!(6, array.len()); @@ -221,7 +221,7 @@ mod tests { builder.append_value(b"hello").unwrap(); builder.append_null(); builder.append_value(b"arrow").unwrap(); - let mut array: FixedSizeBinaryArray = builder.finish_cloned(); + let mut array = builder.finish_cloned(); assert_eq!(&DataType::FixedSizeBinary(5), array.data_type()); assert_eq!(3, array.len()); @@ -252,7 +252,7 @@ mod tests { builder.append_value(b"").unwrap(); assert!(!builder.is_empty()); - let array: FixedSizeBinaryArray = builder.finish(); + let array = builder.finish(); assert_eq!(&DataType::FixedSizeBinary(0), array.data_type()); assert_eq!(3, array.len()); assert_eq!(1, array.null_count()); diff --git a/arrow-avro/src/reader/mod.rs b/arrow-avro/src/reader/mod.rs index d024904844f0..2c83a9cfe29a 100644 --- a/arrow-avro/src/reader/mod.rs +++ b/arrow-avro/src/reader/mod.rs @@ -5397,7 +5397,7 @@ mod test { .to_string_lossy() .into_owned() }; - let pow10: i128 = 10i128.pow(scale_u32); + let pow10 = 10i128.pow(scale_u32); let values_i128: Vec = (1..=24).map(|n| (n as i128) * pow10).collect(); let build_expected = |dt: &DataType, values: &[i128]| -> ArrayRef { match *dt { @@ -7945,7 +7945,7 @@ mod test { let mut tid_array: Option = None; let mut tid_map: Option = None; let mut map_entry_field: Option = None; - let mut map_sorted: bool = false; + let mut map_sorted = false; for (tid, f) in uf.iter() { match f.data_type() { DataType::Dictionary(_, _) => tid_enum = Some(tid), diff --git a/arrow-buffer/src/util/bit_util.rs b/arrow-buffer/src/util/bit_util.rs index 6fe4acb83968..ecfa00d1a297 100644 --- a/arrow-buffer/src/util/bit_util.rs +++ b/arrow-buffer/src/util/bit_util.rs @@ -239,7 +239,7 @@ pub fn apply_bitwise_binary_op( let right_byte_offset = right_offset_in_bits / 8; // Read the same amount of bits from the right buffer - let right_first_byte: u8 = crate::util::bit_util::read_up_to_byte_from_offset( + let right_first_byte = crate::util::bit_util::read_up_to_byte_from_offset( &right.as_ref()[right_byte_offset..], bits_to_next_byte, // Right bit offset diff --git a/arrow-cast/src/parse.rs b/arrow-cast/src/parse.rs index 959922873bf5..a5599d9ef82f 100644 --- a/arrow-cast/src/parse.rs +++ b/arrow-cast/src/parse.rs @@ -809,7 +809,7 @@ fn parse_e_notation( let base = T::Native::usize_as(10); // e has a plus sign - let mut pos_shift_direction: bool = true; + let mut pos_shift_direction = true; // skip to the exponent index directly or just after any processed fractionals let mut bs = s.as_bytes().iter().skip(index + fractionals as usize); diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs index 7407873c2386..5f0586005f11 100644 --- a/arrow-data/src/data.rs +++ b/arrow-data/src/data.rs @@ -1695,7 +1695,7 @@ impl ArrayData { T: ArrowNativeType + TryInto + num_traits::Num + std::fmt::Display, { let values = self.typed_buffer::(0, self.len)?; - let mut prev_value: i64 = 0_i64; + let mut prev_value = 0_i64; values.iter().enumerate().try_for_each(|(ix, &inp_value)| { let value: i64 = inp_value.try_into().map_err(|_| { ArrowError::InvalidArgumentError(format!( diff --git a/arrow/tests/array_cast.rs b/arrow/tests/array_cast.rs index b5a8c43cc4d9..a6e2bbd51204 100644 --- a/arrow/tests/array_cast.rs +++ b/arrow/tests/array_cast.rs @@ -366,7 +366,7 @@ fn make_fixed_size_list_array() -> FixedSizeListArray { } fn make_fixed_size_binary_array() -> FixedSizeBinaryArray { - let values: &[u8; 15] = b"hellotherearrow"; + let values = b"hellotherearrow"; let array_data = ArrayData::builder(DataType::FixedSizeBinary(5)) .len(3) diff --git a/parquet-variant/src/builder/metadata.rs b/parquet-variant/src/builder/metadata.rs index 003407847aad..a8c4e5ba1e5a 100644 --- a/parquet-variant/src/builder/metadata.rs +++ b/parquet-variant/src/builder/metadata.rs @@ -198,7 +198,7 @@ impl WritableMetadataBuilder { let nkeys = self.num_field_names(); // Calculate metadata size - let total_dict_size: usize = self.metadata_size(); + let total_dict_size = self.metadata_size(); let metadata_buffer = &mut self.metadata_buffer; let is_sorted = std::mem::take(&mut self.is_sorted); diff --git a/parquet/benches/row_selection_cursor.rs b/parquet/benches/row_selection_cursor.rs index 8b96f0363d78..87b0e101f320 100644 --- a/parquet/benches/row_selection_cursor.rs +++ b/parquet/benches/row_selection_cursor.rs @@ -316,7 +316,7 @@ fn build_utf8view_batch(total_rows: usize) -> RecordBatch { fn build_utf8view_batch_with_len(total_rows: usize, len: usize) -> RecordBatch { let mut builder = StringViewBuilder::new(); - let value: String = "a".repeat(len); + let value = "a".repeat(len); for _ in 0..total_rows { builder.append_value(&value); } diff --git a/parquet/src/arrow/arrow_reader/selection/boolean.rs b/parquet/src/arrow/arrow_reader/selection/boolean.rs index 990fc1b2ab71..5985d9c12ed2 100644 --- a/parquet/src/arrow/arrow_reader/selection/boolean.rs +++ b/parquet/src/arrow/arrow_reader/selection/boolean.rs @@ -475,7 +475,7 @@ mod tests { #[test] fn test_set_algebra_agrees_whether_or_not_the_cache_is_populated() { let bits: Vec = (0..256).map(|i| i % 3 == 0).collect(); - let other: RowSelection = RowSelection::from_filters(&[BooleanArray::from( + let other = RowSelection::from_filters(&[BooleanArray::from( (0..256).map(|i| i % 5 != 0).collect::>(), )]); diff --git a/parquet/src/column/reader.rs b/parquet/src/column/reader.rs index 39b93b43105a..6c64dd7a7ec8 100644 --- a/parquet/src/column/reader.rs +++ b/parquet/src/column/reader.rs @@ -1336,7 +1336,7 @@ mod tests { let max_def_level = desc.max_def_level(); let max_rep_level = desc.max_rep_level(); let page_reader = InMemoryPageReader::new(pages); - let column_reader: ColumnReader = get_column_reader(desc, Box::new(page_reader)); + let column_reader = get_column_reader(desc, Box::new(page_reader)); let mut typed_column_reader = get_typed_column_reader::(column_reader); let mut values = Vec::new(); @@ -1469,7 +1469,7 @@ mod tests { // 5 records total: [10,20], [30,40], [50,60], [70,80], [90,100] let pages = VecDeque::from(vec![page1, page2, page3]); let page_reader = InMemoryPageReader::new(pages); - let column_reader: ColumnReader = get_column_reader(desc, Box::new(page_reader)); + let column_reader = get_column_reader(desc, Box::new(page_reader)); let mut typed_reader = get_typed_column_reader::(column_reader); // Step 1 — skip 1 record: diff --git a/parquet/src/encodings/rle.rs b/parquet/src/encodings/rle.rs index f4dfebe81d88..e9f013a69c77 100644 --- a/parquet/src/encodings/rle.rs +++ b/parquet/src/encodings/rle.rs @@ -652,7 +652,7 @@ mod tests { // Test data: 0-7 with bit width 3 // 00000011 10001000 11000110 11111010 let data = vec![0x03, 0x88, 0xC6, 0xFA]; - let mut decoder: RleDecoder = RleDecoder::new(3); + let mut decoder = RleDecoder::new(3); decoder.set_data(data.into()).unwrap(); let mut buffer = vec![0; BIT_PACK_GROUP_SIZE]; let expected = vec![0, 1, 2, 3, 4, 5, 6, 7]; @@ -666,7 +666,7 @@ mod tests { // Test data: 0-7 with bit width 3 // 00000011 10001000 11000110 11111010 let data = vec![0x03, 0x88, 0xC6, 0xFA]; - let mut decoder: RleDecoder = RleDecoder::new(3); + let mut decoder = RleDecoder::new(3); decoder.set_data(data.into()).unwrap(); let expected = vec![2, 3, 4, 5, 6, 7]; let skipped = decoder.skip(2).expect("skipping values"); @@ -707,7 +707,7 @@ mod tests { 0x1B, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x0A, ]; - let mut decoder: RleDecoder = RleDecoder::new(1); + let mut decoder = RleDecoder::new(1); decoder.set_data(data1.into()).unwrap(); let mut buffer = vec![false; 100]; let mut expected = vec![]; @@ -750,7 +750,7 @@ mod tests { 0x1B, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x0A, ]; - let mut decoder: RleDecoder = RleDecoder::new(1); + let mut decoder = RleDecoder::new(1); decoder.set_data(data1.into()).unwrap(); let mut buffer = vec![true; 50]; let expected = vec![false; 50]; @@ -788,7 +788,7 @@ mod tests { // 00000110 00000000 00001000 00000001 00001010 00000010 let dict = vec![10, 20, 30]; let data = vec![0x06, 0x00, 0x08, 0x01, 0x0A, 0x02]; - let mut decoder: RleDecoder = RleDecoder::new(3); + let mut decoder = RleDecoder::new(3); decoder.set_data(data.into()).unwrap(); let mut buffer = vec![0; 12]; let expected = vec![10, 10, 10, 20, 20, 20, 20, 30, 30, 30, 30, 30]; @@ -801,7 +801,7 @@ mod tests { // 00000011 01100011 11000111 10001110 00000011 01100101 00001011 let dict = vec!["aaa", "bbb", "ccc", "ddd", "eee", "fff"]; let data = vec![0x03, 0x63, 0xC7, 0x8E, 0x03, 0x65, 0x0B]; - let mut decoder: RleDecoder = RleDecoder::new(3); + let mut decoder = RleDecoder::new(3); decoder.set_data(data.into()).unwrap(); let mut buffer = vec![""; 12]; let expected = vec![ @@ -819,7 +819,7 @@ mod tests { // 00000110 00000000 00001000 00000001 00001010 00000010 let dict = vec![10, 20, 30]; let data = vec![0x06, 0x00, 0x08, 0x01, 0x0A, 0x02]; - let mut decoder: RleDecoder = RleDecoder::new(3); + let mut decoder = RleDecoder::new(3); decoder.set_data(data.into()).unwrap(); let mut buffer = vec![0; 10]; let expected = vec![10, 20, 20, 20, 20, 30, 30, 30, 30, 30]; @@ -836,7 +836,7 @@ mod tests { // 00000011 01100011 11000111 10001110 00000011 01100101 00001011 let dict = vec!["aaa", "bbb", "ccc", "ddd", "eee", "fff"]; let data = vec![0x03, 0x63, 0xC7, 0x8E, 0x03, 0x65, 0x0B]; - let mut decoder: RleDecoder = RleDecoder::new(3); + let mut decoder = RleDecoder::new(3); decoder.set_data(data.into()).unwrap(); let mut buffer = vec![""; BIT_PACK_GROUP_SIZE]; let expected = vec!["eee", "fff", "ddd", "eee", "fff", "eee", "fff", "fff"]; diff --git a/parquet/src/file/metadata/mod.rs b/parquet/src/file/metadata/mod.rs index 874449d992c0..6fb136dbfe30 100644 --- a/parquet/src/file/metadata/mod.rs +++ b/parquet/src/file/metadata/mod.rs @@ -2018,7 +2018,7 @@ mod tests { .build() .unwrap(); - let compressed_size_res: i64 = row_group_meta.compressed_size(); + let compressed_size_res = row_group_meta.compressed_size(); let compressed_size_exp: i64 = 1000; assert_eq!(compressed_size_res, compressed_size_exp); From f6a03529f0f214aae9e4835025f4bde76f2b4232 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:08:27 +0200 Subject: [PATCH 09/17] Enable `clippy::iter_on_single_items` Building a one-element array only to iterate it allocates a temporary and hides how many items there are. Twelve `HashMap` cases become `HashMap::from([..])`; the rest become `std::iter::once`. --- Cargo.toml | 1 + arrow-array/src/array/dictionary_array.rs | 2 +- arrow-avro/src/reader/mod.rs | 2 +- arrow-flight/src/encode.rs | 12 ++++---- arrow-integration-test/src/schema.rs | 5 +--- arrow-ipc/src/convert.rs | 10 ++----- arrow-ipc/src/writer.rs | 2 +- arrow-json/src/reader/schema.rs | 6 +--- arrow-schema/src/schema.rs | 35 +++++------------------ arrow-select/src/interleave.rs | 2 +- arrow/tests/schema.rs | 4 +-- parquet/src/arrow/schema/mod.rs | 5 +--- parquet/src/column/writer/mod.rs | 6 ++-- parquet/src/compression.rs | 5 ++-- 14 files changed, 28 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f478da803271..496476ddf4b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -198,6 +198,7 @@ iter_filter_is_ok = "warn" iter_filter_is_some = "warn" iter_not_returning_iterator = "warn" iter_on_empty_collections = "warn" +iter_on_single_items = "warn" iter_with_drain = "warn" iter_without_into_iter = "warn" large_digit_groups = "warn" diff --git a/arrow-array/src/array/dictionary_array.rs b/arrow-array/src/array/dictionary_array.rs index 7766f952a60c..af5de49ca6b6 100644 --- a/arrow-array/src/array/dictionary_array.rs +++ b/arrow-array/src/array/dictionary_array.rs @@ -1386,7 +1386,7 @@ mod tests { #[should_panic(expected = "Invalid dictionary key -100 at index 0, expected 0 <= key < 2")] fn test_try_new_index_too_small() { let values: StringArray = [Some("foo"), Some("bar")].into_iter().collect(); - let keys: Int32Array = [Some(-100)].into_iter().collect(); + let keys: Int32Array = std::iter::once(Some(-100)).collect(); DictionaryArray::new(keys, Arc::new(values)); } diff --git a/arrow-avro/src/reader/mod.rs b/arrow-avro/src/reader/mod.rs index 2c83a9cfe29a..0f2fa4682ffa 100644 --- a/arrow-avro/src/reader/mod.rs +++ b/arrow-avro/src/reader/mod.rs @@ -4454,7 +4454,7 @@ mod test { let offs = vec![0, 0, 0, 1]; let arr = mk_dense_union(&uf, tids, offs, |f| match f.data_type() { DataType::FixedSizeBinary(8) => { - let it = [Some(fx8_a)].into_iter(); + let it = std::iter::once(Some(fx8_a)); Some(Arc::new( FixedSizeBinaryArray::try_from_sparse_iter_with_size(it, 8).unwrap(), ) as ArrayRef) diff --git a/arrow-flight/src/encode.rs b/arrow-flight/src/encode.rs index 437d910debd4..a263ad73898c 100644 --- a/arrow-flight/src/encode.rs +++ b/arrow-flight/src/encode.rs @@ -1235,7 +1235,7 @@ mod tests { let arr1 = builder.finish(); - let type_id_buffer = [0].into_iter().collect::>(); + let type_id_buffer = std::iter::once(0).collect::>(); let arr1 = UnionArray::try_new( union_fields.clone(), type_id_buffer, @@ -1253,7 +1253,7 @@ mod tests { let arr2 = Arc::new(builder.finish()); let arr2 = StructArray::new(struct_fields.clone().into(), vec![arr2], None); - let type_id_buffer = [1].into_iter().collect::>(); + let type_id_buffer = std::iter::once(1).collect::>(); let arr2 = UnionArray::try_new( union_fields.clone(), type_id_buffer, @@ -1266,7 +1266,7 @@ mod tests { ) .unwrap(); - let type_id_buffer = [2].into_iter().collect::>(); + let type_id_buffer = std::iter::once(2).collect::>(); let arr3 = UnionArray::try_new( union_fields.clone(), type_id_buffer, @@ -1409,7 +1409,7 @@ mod tests { let arr1 = builder.finish(); - let type_id_buffer = [0].into_iter().collect::>(); + let type_id_buffer = std::iter::once(0).collect::>(); let arr1 = UnionArray::try_new( union_fields.clone(), type_id_buffer, @@ -1427,7 +1427,7 @@ mod tests { let arr2 = Arc::new(builder.finish()); let arr2 = StructArray::new(struct_fields.clone().into(), vec![arr2], None); - let type_id_buffer = [1].into_iter().collect::>(); + let type_id_buffer = std::iter::once(1).collect::>(); let arr2 = UnionArray::try_new( union_fields.clone(), type_id_buffer, @@ -1440,7 +1440,7 @@ mod tests { ) .unwrap(); - let type_id_buffer = [2].into_iter().collect::>(); + let type_id_buffer = std::iter::once(2).collect::>(); let arr3 = UnionArray::try_new( union_fields.clone(), type_id_buffer, diff --git a/arrow-integration-test/src/schema.rs b/arrow-integration-test/src/schema.rs index 092a07a95548..6e6f3910c9a4 100644 --- a/arrow-integration-test/src/schema.rs +++ b/arrow-integration-test/src/schema.rs @@ -113,10 +113,7 @@ mod tests { #[test] fn schema_json() { // Add some custom metadata - let metadata: HashMap = [("Key".to_string(), "Value".to_string())] - .iter() - .cloned() - .collect(); + let metadata = HashMap::from([("Key".to_string(), "Value".to_string())]); let schema = Schema::new_with_metadata( vec![ diff --git a/arrow-ipc/src/convert.rs b/arrow-ipc/src/convert.rs index 6429f76f8ae0..acce273fe6ba 100644 --- a/arrow-ipc/src/convert.rs +++ b/arrow-ipc/src/convert.rs @@ -1004,14 +1004,8 @@ mod tests { #[test] fn convert_schema_round_trip() { - let md: HashMap = [("Key".to_string(), "value".to_string())] - .iter() - .cloned() - .collect(); - let field_md: HashMap = [("k".to_string(), "v".to_string())] - .iter() - .cloned() - .collect(); + let md = HashMap::from([("Key".to_string(), "value".to_string())]); + let field_md = HashMap::from([("k".to_string(), "v".to_string())]); let schema = Schema::new_with_metadata( vec![ Field::new("uint8", DataType::UInt8, false).with_metadata(field_md), diff --git a/arrow-ipc/src/writer.rs b/arrow-ipc/src/writer.rs index 20d3441a3f6c..59ae2cdcb68d 100644 --- a/arrow-ipc/src/writer.rs +++ b/arrow-ipc/src/writer.rs @@ -3211,7 +3211,7 @@ mod tests { // Dict field with id 2 #[allow(deprecated)] let dctfield = Field::new_dict("dict", array.data_type().clone(), false, 0, false); - let union_fields = [(0, Arc::new(dctfield))].into_iter().collect(); + let union_fields = std::iter::once((0, Arc::new(dctfield))).collect(); let types = [0, 0, 0].into_iter().collect::>(); let offsets = [0, 1, 2].into_iter().collect::>(); diff --git a/arrow-json/src/reader/schema.rs b/arrow-json/src/reader/schema.rs index f9f70da1f03c..22769522a160 100644 --- a/arrow-json/src/reader/schema.rs +++ b/arrow-json/src/reader/schema.rs @@ -664,11 +664,7 @@ mod tests { infer_json_schema_from_seekable(Cursor::new(data), None).expect("infer"); let schema = Schema::new(vec![Field::new( "obj", - DataType::Struct( - [Field::new("foo", DataType::Int64, true)] - .into_iter() - .collect(), - ), + DataType::Struct(std::iter::once(Field::new("foo", DataType::Int64, true)).collect()), true, )]); assert_eq!(inferred_schema, schema); diff --git a/arrow-schema/src/schema.rs b/arrow-schema/src/schema.rs index ca7d3dadb403..47d031deabaa 100644 --- a/arrow-schema/src/schema.rs +++ b/arrow-schema/src/schema.rs @@ -1221,26 +1221,17 @@ mod tests { #[test] fn test_try_merge_field_with_metadata() { // 1. Different values for the same key should cause error. - let metadata1: HashMap = [("foo".to_string(), "bar".to_string())] - .iter() - .cloned() - .collect(); + let metadata1 = HashMap::from([("foo".to_string(), "bar".to_string())]); let f1 = Field::new("first_name", DataType::Utf8, false).with_metadata(metadata1); - let metadata2: HashMap = [("foo".to_string(), "baz".to_string())] - .iter() - .cloned() - .collect(); + let metadata2 = HashMap::from([("foo".to_string(), "baz".to_string())]); let f2 = Field::new("first_name", DataType::Utf8, false).with_metadata(metadata2); assert!(Schema::try_merge(vec![Schema::new(vec![f1]), Schema::new(vec![f2])]).is_err()); // 2. None + Some let mut f1 = Field::new("first_name", DataType::Utf8, false); - let metadata2: HashMap = [("missing".to_string(), "value".to_string())] - .iter() - .cloned() - .collect(); + let metadata2 = HashMap::from([("missing".to_string(), "value".to_string())]); let f2 = Field::new("first_name", DataType::Utf8, false).with_metadata(metadata2); assert!(f1.try_merge(&f2).is_ok()); @@ -1303,10 +1294,7 @@ mod tests { // new field Field::new("number", DataType::Utf8, true), ], - [("foo".to_string(), "bar".to_string())] - .iter() - .cloned() - .collect::>(), + HashMap::from([("foo".to_string(), "bar".to_string())]), ), ]) .unwrap(); @@ -1327,10 +1315,7 @@ mod tests { ), Field::new("number", DataType::Utf8, true), ], - [("foo".to_string(), "bar".to_string())] - .iter() - .cloned() - .collect::>() + HashMap::from([("foo".to_string(), "bar".to_string())]) ) ); @@ -1385,17 +1370,11 @@ mod tests { let res = Schema::try_merge(vec![ Schema::new_with_metadata( vec![Field::new("first_name", DataType::Utf8, false)], - [("foo".to_string(), "bar".to_string())] - .iter() - .cloned() - .collect::>(), + HashMap::from([("foo".to_string(), "bar".to_string())]), ), Schema::new_with_metadata( vec![Field::new("last_name", DataType::Utf8, false)], - [("foo".to_string(), "baz".to_string())] - .iter() - .cloned() - .collect::>(), + HashMap::from([("foo".to_string(), "baz".to_string())]), ), ]) .unwrap_err(); diff --git a/arrow-select/src/interleave.rs b/arrow-select/src/interleave.rs index d84370947957..471b744e966c 100644 --- a/arrow-select/src/interleave.rs +++ b/arrow-select/src/interleave.rs @@ -1956,7 +1956,7 @@ mod tests { #[test] fn test_interleave_run_end_encoded_empty_runs() { let mut builder = PrimitiveRunBuilder::::new(); - builder.extend([1].into_iter().map(Some)); + builder.extend(std::iter::once(Some(1))); let a = builder.finish(); let mut builder = PrimitiveRunBuilder::::new(); diff --git a/arrow/tests/schema.rs b/arrow/tests/schema.rs index f252d77ca65d..4894508fd79b 100644 --- a/arrow/tests/schema.rs +++ b/arrow/tests/schema.rs @@ -22,9 +22,7 @@ use std::collections::HashMap; #[test] fn schema_destructure() { - let meta = [("foo".to_string(), "baz".to_string())] - .into_iter() - .collect::>(); + let meta = HashMap::from([("foo".to_string(), "baz".to_string())]); let field = Field::new("c1", DataType::Utf8, false); let schema = Schema::new(vec![field]).with_metadata(meta); diff --git a/parquet/src/arrow/schema/mod.rs b/parquet/src/arrow/schema/mod.rs index 110c799b4276..7b5287577b41 100644 --- a/parquet/src/arrow/schema/mod.rs +++ b/parquet/src/arrow/schema/mod.rs @@ -2270,10 +2270,7 @@ mod tests { #[test] fn test_arrow_schema_roundtrip_lists() -> Result<()> { - let metadata: HashMap = [("Key".to_string(), "Value".to_string())] - .iter() - .cloned() - .collect(); + let metadata = HashMap::from([("Key".to_string(), "Value".to_string())]); let schema = Schema::new_with_metadata( vec![ diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index 66daaade9e0d..f351ec6606f7 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -3560,8 +3560,7 @@ mod tests { #[test] fn test_float16_statistics_zero_only() { - let input = [f16::ZERO] - .into_iter() + let input = std::iter::once(f16::ZERO) .map(|s| ByteArray::from(s).into()) .collect::>(); @@ -3573,8 +3572,7 @@ mod tests { #[test] fn test_float16_statistics_neg_zero_only() { - let input = [f16::NEG_ZERO] - .into_iter() + let input = std::iter::once(f16::NEG_ZERO) .map(|s| ByteArray::from(s).into()) .collect::>(); diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 1a77bfda51e7..f3dd0e9e86e6 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -936,9 +936,8 @@ mod tests { #[test] fn test_codec_zstd() { // since ZstdLevel::MINIMUM_LEVEL is a large negative number, we test a smaller range - for level in [ZstdLevel::MINIMUM_LEVEL] - .into_iter() - .chain(-100..=ZstdLevel::MAXIMUM_LEVEL) + for level in + std::iter::once(ZstdLevel::MINIMUM_LEVEL).chain(-100..=ZstdLevel::MAXIMUM_LEVEL) { let level = ZstdLevel::try_new(level).unwrap(); test_codec_with_size(CodecType::ZSTD(level)); From 4fbd5593c5c1102834d14972cd2ae4bc518627ab Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:10:54 +0200 Subject: [PATCH 10/17] Enable `clippy::unnecessary_trailing_comma` Removes trailing commas after the last macro argument, mostly in `panic!` and `assert_eq!` messages, where they look like a forgotten argument. --- Cargo.toml | 1 + arrow-array/src/types.rs | 12 ++++++------ arrow-avro/src/reader/mod.rs | 2 +- arrow-buffer/src/bytes.rs | 2 +- arrow-cast/src/display.rs | 2 +- arrow-data/src/transform/run.rs | 2 +- arrow-json/src/reader/primitive_array.rs | 18 ++++++++---------- .../benches/variant_kernels.rs | 16 ++++++++-------- parquet/benches/arrow_reader_row_filter.rs | 2 +- parquet/benches/encoding.rs | 2 +- parquet/src/arrow/async_reader/store.rs | 2 +- 11 files changed, 30 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 496476ddf4b3..399462c0e09d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -267,6 +267,7 @@ unnecessary_literal_bound = "warn" unnecessary_safety_doc = "warn" unnecessary_self_imports = "warn" unnecessary_struct_initialization = "warn" +unnecessary_trailing_comma = "warn" unnested_or_patterns = "warn" unused_async = "warn" unused_peekable = "warn" diff --git a/arrow-array/src/types.rs b/arrow-array/src/types.rs index 40cb3fd7fa78..2625b41880d5 100644 --- a/arrow-array/src/types.rs +++ b/arrow-array/src/types.rs @@ -948,7 +948,7 @@ impl Date32Type { #[deprecated(since = "58.0.0", note = "Use to_naive_date_opt instead.")] pub fn to_naive_date(i: ::Native) -> NaiveDate { Self::to_naive_date_opt(i) - .unwrap_or_else(|| panic!("Date32Type::to_naive_date overflowed for date: {i}",)) + .unwrap_or_else(|| panic!("Date32Type::to_naive_date overflowed for date: {i}")) } /// Converts an arrow Date32Type into a chrono::NaiveDate @@ -988,7 +988,7 @@ impl Date32Type { delta: ::Native, ) -> ::Native { Self::add_year_months_opt(date, delta).unwrap_or_else(|| { - panic!("Date32Type::add_year_months overflowed for date: {date}, delta: {delta}",) + panic!("Date32Type::add_year_months overflowed for date: {date}, delta: {delta}") }) } @@ -1025,7 +1025,7 @@ impl Date32Type { delta: ::Native, ) -> ::Native { Self::add_day_time_opt(date, delta).unwrap_or_else(|| { - panic!("Date32Type::add_day_time overflowed for date: {date}, delta: {delta:?}",) + panic!("Date32Type::add_day_time overflowed for date: {date}, delta: {delta:?}") }) } @@ -1063,7 +1063,7 @@ impl Date32Type { delta: ::Native, ) -> ::Native { Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| { - panic!("Date32Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",) + panic!("Date32Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}") }) } @@ -1102,7 +1102,7 @@ impl Date32Type { delta: ::Native, ) -> ::Native { Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| { - panic!("Date32Type::subtract_year_months overflowed for date: {date}, delta: {delta}",) + panic!("Date32Type::subtract_year_months overflowed for date: {date}, delta: {delta}") }) } @@ -1139,7 +1139,7 @@ impl Date32Type { delta: ::Native, ) -> ::Native { Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| { - panic!("Date32Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",) + panic!("Date32Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}") }) } diff --git a/arrow-avro/src/reader/mod.rs b/arrow-avro/src/reader/mod.rs index 0f2fa4682ffa..a8d7d7d2148d 100644 --- a/arrow-avro/src/reader/mod.rs +++ b/arrow-avro/src/reader/mod.rs @@ -6587,7 +6587,7 @@ mod test { .expect("id column should be an Int64Array"); let expected_ids = [1, 2, 3, 4, 5, 6, 7]; for (i, &expected_id) in expected_ids.iter().enumerate() { - assert_eq!(id_array.value(i), expected_id, "Mismatch in id at row {i}",); + assert_eq!(id_array.value(i), expected_id, "Mismatch in id at row {i}"); } let int_array = batch .column(1) diff --git a/arrow-buffer/src/bytes.rs b/arrow-buffer/src/bytes.rs index d473f13dacad..07b08da43d07 100644 --- a/arrow-buffer/src/bytes.rs +++ b/arrow-buffer/src/bytes.rs @@ -218,7 +218,7 @@ impl PartialEq for Bytes { impl Debug for Bytes { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!(f, "Bytes {{ ptr: {:?}, len: {}, data: ", self.ptr, self.len,)?; + write!(f, "Bytes {{ ptr: {:?}, len: {}, data: ", self.ptr, self.len)?; f.debug_list().entries(self.iter()).finish()?; diff --git a/arrow-cast/src/display.rs b/arrow-cast/src/display.rs index 96832b6bd7b2..68775ace75ed 100644 --- a/arrow-cast/src/display.rs +++ b/arrow-cast/src/display.rs @@ -971,7 +971,7 @@ impl DisplayIndex for &PrimitiveArray { let years = (interval / 12_f64).floor(); let month = interval - (years * 12_f64); - write!(f, "{years} years {month} mons",)?; + write!(f, "{years} years {month} mons")?; Ok(()) } } diff --git a/arrow-data/src/transform/run.rs b/arrow-data/src/transform/run.rs index 3678db16e058..e366bd5367be 100644 --- a/arrow-data/src/transform/run.rs +++ b/arrow-data/src/transform/run.rs @@ -251,7 +251,7 @@ pub fn build_extend(array: &ArrayData) -> Extend<'_> { DataType::Int16 => build_and_process_impl!(i16), DataType::Int32 => build_and_process_impl!(i32), DataType::Int64 => build_and_process_impl!(i64), - _ => panic!("Invalid run end type for RunEndEncoded array: {dest_run_end_type}",), + _ => panic!("Invalid run end type for RunEndEncoded array: {dest_run_end_type}"), } Ok(()) }, diff --git a/arrow-json/src/reader/primitive_array.rs b/arrow-json/src/reader/primitive_array.rs index b086954297a9..dc9c0a8b1a6a 100644 --- a/arrow-json/src/reader/primitive_array.rs +++ b/arrow-json/src/reader/primitive_array.rs @@ -109,28 +109,26 @@ where TapeElement::String(idx) => { let s = tape.get_string(idx); P::parse(s).ok_or_else(|| { - ArrowError::JsonError(format!("failed to parse \"{s}\" as {d}",)) + ArrowError::JsonError(format!("failed to parse \"{s}\" as {d}")) }) } TapeElement::Number(idx) => { let s = tape.get_string(idx); - ParseJsonNumber::parse(s.as_bytes()).ok_or_else(|| { - ArrowError::JsonError(format!("failed to parse {s} as {d}",)) - }) + ParseJsonNumber::parse(s.as_bytes()) + .ok_or_else(|| ArrowError::JsonError(format!("failed to parse {s} as {d}"))) } TapeElement::F32(v) => { let v = f32::from_bits(v); - NumCast::from(v).ok_or_else(|| { - ArrowError::JsonError(format!("failed to parse {v} as {d}",)) - }) + NumCast::from(v) + .ok_or_else(|| ArrowError::JsonError(format!("failed to parse {v} as {d}"))) } TapeElement::I32(v) => NumCast::from(v) - .ok_or_else(|| ArrowError::JsonError(format!("failed to parse {v} as {d}",))), + .ok_or_else(|| ArrowError::JsonError(format!("failed to parse {v} as {d}"))), TapeElement::F64(high) => match tape.get(p + 1) { TapeElement::F32(low) => { let v = f64::from_bits(((high as u64) << 32) | low as u64); NumCast::from(v).ok_or_else(|| { - ArrowError::JsonError(format!("failed to parse {v} as {d}",)) + ArrowError::JsonError(format!("failed to parse {v} as {d}")) }) } _ => unreachable!(), @@ -139,7 +137,7 @@ where TapeElement::I32(low) => { let v = ((high as i64) << 32) | (low as u32) as i64; NumCast::from(v).ok_or_else(|| { - ArrowError::JsonError(format!("failed to parse {v} as {d}",)) + ArrowError::JsonError(format!("failed to parse {v} as {d}")) }) } _ => unreachable!(), diff --git a/parquet-variant-compute/benches/variant_kernels.rs b/parquet-variant-compute/benches/variant_kernels.rs index 8ecf5bf44e20..800633b57133 100644 --- a/parquet-variant-compute/benches/variant_kernels.rs +++ b/parquet-variant-compute/benches/variant_kernels.rs @@ -462,7 +462,7 @@ impl RandomJsonGenerator { let random_string: String = (0..length) .map(|_| rng.sample(Alphanumeric) as char) .collect(); - write!(output_buffer, "\"{random_string}\"",).unwrap(); + write!(output_buffer, "\"{random_string}\"").unwrap(); } else { random_value -= *string_weight; @@ -471,11 +471,11 @@ impl RandomJsonGenerator { if rng.random_bool(0.5) { // Generate a random integer let random_integer: i64 = rng.random_range(-1000..1000); - write!(output_buffer, "{random_integer}",).unwrap(); + write!(output_buffer, "{random_integer}").unwrap(); } else { // Generate a random float let random_float: f64 = rng.random_range(-1000.0..1000.0); - write!(output_buffer, "{random_float}",).unwrap(); + write!(output_buffer, "{random_float}").unwrap(); } } else { random_value -= *number_weight; @@ -483,7 +483,7 @@ impl RandomJsonGenerator { if random_value <= *boolean_weight { // Generate a random boolean let random_boolean: bool = rng.random(); - write!(output_buffer, "{random_boolean}",).unwrap(); + write!(output_buffer, "{random_boolean}").unwrap(); } } } @@ -539,7 +539,7 @@ impl RandomJsonGenerator { let random_string: String = (0..length) .map(|_| rng.sample(Alphanumeric) as char) .collect(); - write!(output_buffer, "\"{random_string}\"",).unwrap(); + write!(output_buffer, "\"{random_string}\"").unwrap(); return; } random_value -= *string_weight; @@ -549,11 +549,11 @@ impl RandomJsonGenerator { if rng.random_bool(0.5) { // Generate a random integer let random_integer: i64 = rng.random_range(-1000..1000); - write!(output_buffer, "{random_integer}",).unwrap(); + write!(output_buffer, "{random_integer}").unwrap(); } else { // Generate a random float let random_float: f64 = rng.random_range(-1000.0..1000.0); - write!(output_buffer, "{random_float}",).unwrap(); + write!(output_buffer, "{random_float}").unwrap(); } return; } @@ -562,7 +562,7 @@ impl RandomJsonGenerator { if random_value <= *boolean_weight { // Generate a random boolean let random_boolean: bool = rng.random(); - write!(output_buffer, "{random_boolean}",).unwrap(); + write!(output_buffer, "{random_boolean}").unwrap(); return; } random_value -= *boolean_weight; diff --git a/parquet/benches/arrow_reader_row_filter.rs b/parquet/benches/arrow_reader_row_filter.rs index 85e75e5a7c9b..d34d2eb3d920 100644 --- a/parquet/benches/arrow_reader_row_filter.rs +++ b/parquet/benches/arrow_reader_row_filter.rs @@ -468,7 +468,7 @@ fn benchmark_filters_and_projections(c: &mut Criterion) { let projection_mask = ProjectionMask::roots(schema_descr, output_projection.clone()); let pred_mask = ProjectionMask::roots(schema_descr, filter_col.clone()); - let benchmark_name = format!("{filter_type}/{proj_case}",); + let benchmark_name = format!("{filter_type}/{proj_case}"); // run the benchmark for the async reader let bench_id = BenchmarkId::new(benchmark_name.clone(), "async"); diff --git a/parquet/benches/encoding.rs b/parquet/benches/encoding.rs index 65c2ec3d37ee..880e169cffef 100644 --- a/parquet/benches/encoding.rs +++ b/parquet/benches/encoding.rs @@ -63,7 +63,7 @@ fn bench_typed( let mut encoder = get_encoder::(encoding, &column_desc_ptr).unwrap(); encoder.put(values).unwrap(); let encoded = encoder.flush_buffer().unwrap(); - println!("{} encoded as {} bytes", name, encoded.len(),); + println!("{} encoded as {} bytes", name, encoded.len()); let mut buffer = vec![T::T::default(); values.len()]; c.bench_function(&format!("decoding: {name}"), |b| { diff --git a/parquet/src/arrow/async_reader/store.rs b/parquet/src/arrow/async_reader/store.rs index 0b1efc492b38..4943ca021bf3 100644 --- a/parquet/src/arrow/async_reader/store.rs +++ b/parquet/src/arrow/async_reader/store.rs @@ -342,7 +342,7 @@ mod tests { Ok(_) => panic!("expected failure"), Err(e) => { let err = e.to_string(); - assert!(err.contains("I don't exist.parquet not found:"), "{err}",); + assert!(err.contains("I don't exist.parquet not found:"), "{err}"); } } } From e731fc4a72e0d849992706bc216473f591dd6d0f Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:15:38 +0200 Subject: [PATCH 11/17] Enable `clippy::implicit_clone` `to_string`/`to_vec`/`to_owned` on a type that is already owned goes through `Deref` and clones anyway, just less obviously. Four of the sites turned out to be clones nothing needed, so they are now gone entirely. --- Cargo.toml | 1 + arrow-avro/src/codec.rs | 4 ++-- arrow-buffer/src/util/bit_mask.rs | 2 +- arrow-csv/src/reader/mod.rs | 5 ++--- arrow-csv/src/writer.rs | 2 +- arrow-integration-test/src/field.rs | 2 +- arrow-integration-test/src/lib.rs | 2 +- arrow-integration-test/src/schema.rs | 2 +- arrow-json/src/reader/mod.rs | 2 +- arrow-json/src/reader/schema.rs | 10 +++++----- arrow-json/src/reader/struct_array.rs | 2 +- parquet/src/arrow/async_reader/store.rs | 2 +- parquet/src/file/metadata/thrift/encryption.rs | 3 +-- parquet/src/file/serialized_reader.rs | 15 +++------------ parquet/src/file/writer.rs | 2 -- parquet/src/record/reader.rs | 2 +- parquet/tests/encryption/encryption.rs | 2 +- parquet/tests/encryption/encryption_async.rs | 2 +- 18 files changed, 25 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 399462c0e09d..527f07578cc8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -186,6 +186,7 @@ fn_params_excessive_bools = "warn" fn_to_numeric_cast_any = "warn" format_push_string = "warn" ignored_unit_patterns = "warn" +implicit_clone = "warn" imprecise_flops = "warn" inconsistent_struct_constructor = "warn" index_refutable_slice = "warn" diff --git a/arrow-avro/src/codec.rs b/arrow-avro/src/codec.rs index ec6224ed1ecc..ff3486db6235 100644 --- a/arrow-avro/src/codec.rs +++ b/arrow-avro/src/codec.rs @@ -1200,12 +1200,12 @@ fn union_branch_name(dt: &AvroDataType) -> String { if let Some(name) = dt.metadata.get(AVRO_NAME_METADATA_KEY) { if name.contains('.') { // Full name - return name.to_string(); + return name.clone(); } if let Some(ns) = dt.metadata.get(AVRO_NAMESPACE_METADATA_KEY) { return format!("{ns}.{name}"); } - return name.to_string(); + return name.clone(); } dt.codec.union_field_name() } diff --git a/arrow-buffer/src/util/bit_mask.rs b/arrow-buffer/src/util/bit_mask.rs index ad55728aae91..42b42cb2d6e5 100644 --- a/arrow-buffer/src/util/bit_mask.rs +++ b/arrow-buffer/src/util/bit_mask.rs @@ -388,7 +388,7 @@ mod tests { /// call set_bits with the given parameters and compare with the expected output fn verify(&self) { // call set_bits and compare - let mut actual = self.write_data.to_vec(); + let mut actual = self.write_data.clone(); let null_count = set_bits( &mut actual, &self.data, diff --git a/arrow-csv/src/reader/mod.rs b/arrow-csv/src/reader/mod.rs index fc06aaffa599..64b1ef494206 100644 --- a/arrow-csv/src/reader/mod.rs +++ b/arrow-csv/src/reader/mod.rs @@ -2678,7 +2678,7 @@ mod tests { let batches = reader.collect::, _>>(); assert!(match batches { - Err(ArrowError::CsvError(e)) => e.to_string().contains("incorrect number of fields"), + Err(ArrowError::CsvError(e)) => e.contains("incorrect number of fields"), _ => false, }); } @@ -2907,8 +2907,7 @@ mod tests { let batches = reader.collect::, _>>(); assert!(match batches { - Err(ArrowError::InvalidArgumentError(e)) => - e.to_string().contains("contains null values"), + Err(ArrowError::InvalidArgumentError(e)) => e.contains("contains null values"), _ => false, }); } diff --git a/arrow-csv/src/writer.rs b/arrow-csv/src/writer.rs index af413c889d86..dd63a683e2d3 100644 --- a/arrow-csv/src/writer.rs +++ b/arrow-csv/src/writer.rs @@ -247,7 +247,7 @@ impl Writer { .schema() .fields() .iter() - .for_each(|field| headers.push(field.name().to_string())); + .for_each(|field| headers.push(field.name().clone())); self.writer .write_record(&headers[..]) .map_err(map_csv_error)?; diff --git a/arrow-integration-test/src/field.rs b/arrow-integration-test/src/field.rs index b7d14acd60c1..997c50989065 100644 --- a/arrow-integration-test/src/field.rs +++ b/arrow-integration-test/src/field.rs @@ -27,7 +27,7 @@ pub fn field_from_json(json: &serde_json::Value) -> Result { match *json { Value::Object(ref map) => { let name = match map.get("name") { - Some(Value::String(name)) => name.to_string(), + Some(Value::String(name)) => name.clone(), _ => { return Err(ArrowError::ParseError( "Field missing 'name' attribute".to_string(), diff --git a/arrow-integration-test/src/lib.rs b/arrow-integration-test/src/lib.rs index 2b51318f1b38..e294aced0310 100644 --- a/arrow-integration-test/src/lib.rs +++ b/arrow-integration-test/src/lib.rs @@ -132,7 +132,7 @@ impl From<&Field> for ArrowJsonField { }; Self { - name: field.name().to_string(), + name: field.name().clone(), field_type: data_type_to_json(field.data_type()), nullable: field.is_nullable(), children: vec![], diff --git a/arrow-integration-test/src/schema.rs b/arrow-integration-test/src/schema.rs index 6e6f3910c9a4..c43c8bb12693 100644 --- a/arrow-integration-test/src/schema.rs +++ b/arrow-integration-test/src/schema.rs @@ -83,7 +83,7 @@ fn from_metadata(json: &serde_json::Value) -> Result> { .iter() .map(|(k, v)| { if let Value::String(v) = v { - Ok((k.to_string(), v.to_string())) + Ok((k.clone(), v.clone())) } else { Err(ArrowError::ParseError( "metadata `value` field must be a string".to_string(), diff --git a/arrow-json/src/reader/mod.rs b/arrow-json/src/reader/mod.rs index 83864b1a4f3d..1a2ca7631db8 100644 --- a/arrow-json/src/reader/mod.rs +++ b/arrow-json/src/reader/mod.rs @@ -3295,7 +3295,7 @@ mod tests { .iter() .chain(json_values[..i].iter()) .zip(&schema.fields) - .map(|(v, f)| (f.name().to_string(), v.clone())) + .map(|(v, f)| (f.name().clone(), v.clone())) .collect(); serde_json::Value::Object(pairs) }) diff --git a/arrow-json/src/reader/schema.rs b/arrow-json/src/reader/schema.rs index 22769522a160..674375f629b7 100644 --- a/arrow-json/src/reader/schema.rs +++ b/arrow-json/src/reader/schema.rs @@ -328,13 +328,13 @@ fn collect_field_types_from_object( match ele_type { InferredType::Scalar(_) => { field_types.insert( - k.to_string(), + k.clone(), InferredType::Array(Box::new(InferredType::Scalar(HashSet::new()))), ); } InferredType::Object(_) => { field_types.insert( - k.to_string(), + k.clone(), InferredType::Array(Box::new(InferredType::Object(HashMap::new()))), ); } @@ -342,7 +342,7 @@ fn collect_field_types_from_object( // set inner type to any for nested array as well // so it can be updated properly from subsequent type merges field_types.insert( - k.to_string(), + k.clone(), InferredType::Array(Box::new(InferredType::Any)), ); } @@ -373,7 +373,7 @@ fn collect_field_types_from_object( // we treat json as nullable by default when inferring, so just // mark existence of a field if it wasn't known before if !field_types.contains_key(k) { - field_types.insert(k.to_string(), InferredType::Any); + field_types.insert(k.clone(), InferredType::Any); } } Value::Number(n) => { @@ -391,7 +391,7 @@ fn collect_field_types_from_object( field_types.get(k).unwrap_or(&InferredType::Any), InferredType::Any ) { - field_types.insert(k.to_string(), InferredType::Object(HashMap::new())); + field_types.insert(k.clone(), InferredType::Object(HashMap::new())); } match field_types.get_mut(k).unwrap() { InferredType::Object(inner_field_types) => { diff --git a/arrow-json/src/reader/struct_array.rs b/arrow-json/src/reader/struct_array.rs index 75bb02781be9..6de81a6c8d1d 100644 --- a/arrow-json/src/reader/struct_array.rs +++ b/arrow-json/src/reader/struct_array.rs @@ -284,7 +284,7 @@ fn build_field_index(fields: &Fields) -> Option> { for (idx, field) in fields.iter().enumerate() { let name = field.name(); if !map.contains_key(name) { - map.insert(name.to_string(), idx); + map.insert(name.clone(), idx); } } Some(map) diff --git a/parquet/src/arrow/async_reader/store.rs b/parquet/src/arrow/async_reader/store.rs index 4943ca021bf3..8d572fe99bd9 100644 --- a/parquet/src/arrow/async_reader/store.rs +++ b/parquet/src/arrow/async_reader/store.rs @@ -427,7 +427,7 @@ mod tests { let err = reader.get_bytes(0..1).await.unwrap_err().to_string(); - assert!(err.to_string().contains("was cancelled")); + assert!(err.contains("was cancelled")); } #[tokio::test] diff --git a/parquet/src/file/metadata/thrift/encryption.rs b/parquet/src/file/metadata/thrift/encryption.rs index 00258d2981f7..f71150dff329 100644 --- a/parquet/src/file/metadata/thrift/encryption.rs +++ b/parquet/src/file/metadata/thrift/encryption.rs @@ -350,9 +350,8 @@ fn get_file_decryptor( let aad_prefix = if let Some(aad_prefix) = file_decryption_properties.aad_prefix() { aad_prefix.clone() } else { - algo.aad_prefix.map(|v| v.to_vec()).unwrap_or_default() + algo.aad_prefix.unwrap_or_default() }; - let aad_file_unique = aad_file_unique.to_vec(); FileDecryptor::new( file_decryption_properties, diff --git a/parquet/src/file/serialized_reader.rs b/parquet/src/file/serialized_reader.rs index fe9a5c04863c..80ec15b6ca68 100644 --- a/parquet/src/file/serialized_reader.rs +++ b/parquet/src/file/serialized_reader.rs @@ -1468,10 +1468,7 @@ mod tests { "parquet-mr version 1.8.1 (build 4aba4dae7bb0d4edbcf7923ae1339f28fd3f7fcf)" ); assert!(file_metadata.key_value_metadata().is_some()); - assert_eq!( - file_metadata.key_value_metadata().to_owned().unwrap().len(), - 1 - ); + assert_eq!(file_metadata.key_value_metadata().unwrap().len(), 1); assert_eq!(file_metadata.num_rows(), 5); assert_eq!(file_metadata.version(), 1); @@ -1567,10 +1564,7 @@ mod tests { "parquet-cpp-arrow version 14.0.2" ); assert!(file_metadata.key_value_metadata().is_some()); - assert_eq!( - file_metadata.key_value_metadata().to_owned().unwrap().len(), - 1 - ); + assert_eq!(file_metadata.key_value_metadata().unwrap().len(), 1); assert_eq!(file_metadata.num_rows(), 10); assert_eq!(file_metadata.version(), 2); @@ -1669,10 +1663,7 @@ mod tests { "parquet-mr version 1.13.1 (build db4183109d5b734ec5930d870cdae161e408ddba)" ); assert!(file_metadata.key_value_metadata().is_some()); - assert_eq!( - file_metadata.key_value_metadata().to_owned().unwrap().len(), - 2 - ); + assert_eq!(file_metadata.key_value_metadata().unwrap().len(), 2); assert_eq!(file_metadata.num_rows(), 1); assert_eq!(file_metadata.version(), 1); diff --git a/parquet/src/file/writer.rs b/parquet/src/file/writer.rs index 730aa0fe8e92..aa17a5274a97 100644 --- a/parquet/src/file/writer.rs +++ b/parquet/src/file/writer.rs @@ -1388,7 +1388,6 @@ mod tests { .metadata() .file_metadata() .key_value_metadata() - .to_owned() .unwrap() .len(), 1 @@ -1431,7 +1430,6 @@ mod tests { .metadata() .file_metadata() .key_value_metadata() - .to_owned() .unwrap() .len(), 1 diff --git a/parquet/src/record/reader.rs b/parquet/src/record/reader.rs index f1a262250ca9..7a8384c93613 100644 --- a/parquet/src/record/reader.rs +++ b/parquet/src/record/reader.rs @@ -128,7 +128,7 @@ impl TreeBuilder { path.push(String::from(field.name())); let reader = if field.is_primitive() { - let col_path = ColumnPath::new(path.to_vec()); + let col_path = ColumnPath::new(path.clone()); let orig_index = *paths .get(&col_path) .ok_or(general_err!("Path {:?} not found", col_path))?; diff --git a/parquet/tests/encryption/encryption.rs b/parquet/tests/encryption/encryption.rs index 2b4a438b614b..37c08f82bd81 100644 --- a/parquet/tests/encryption/encryption.rs +++ b/parquet/tests/encryption/encryption.rs @@ -783,7 +783,7 @@ fn test_write_non_uniform_encryption() { let file = File::open(path).unwrap(); let decryption_properties = FileDecryptionProperties::builder(footer_key.to_vec()) - .with_column_keys(column_names.to_vec(), column_keys.clone()) + .with_column_keys(column_names.clone(), column_keys.clone()) .unwrap() .build() .unwrap(); diff --git a/parquet/tests/encryption/encryption_async.rs b/parquet/tests/encryption/encryption_async.rs index 35fb98a9eb23..7d73601643a3 100644 --- a/parquet/tests/encryption/encryption_async.rs +++ b/parquet/tests/encryption/encryption_async.rs @@ -380,7 +380,7 @@ async fn test_write_non_uniform_encryption() { ); let decryption_properties = FileDecryptionProperties::builder(footer_key.to_vec()) - .with_column_keys(column_names.to_vec(), column_keys.clone()) + .with_column_keys(column_names.clone(), column_keys.clone()) .unwrap() .build() .unwrap(); From 4ec247bfaef5261f6fd4b9f9384e60528f3a4404 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:45:26 +0200 Subject: [PATCH 12/17] Enable `clippy::cloned_instead_of_copied` `copied` says the element is `Copy`, so the reader does not have to wonder whether the iterator is cloning something expensive. `UnalignedBitChunkIterator` changes from `Cloned<..>` to `Copied<..>` accordingly. --- Cargo.toml | 1 + arrow-buffer/src/buffer/boolean.rs | 6 +++--- arrow-buffer/src/buffer/scalar.rs | 4 ++-- arrow-buffer/src/util/bit_chunk_iterator.rs | 6 +++--- arrow-flight/src/sql/metadata/sql_info.rs | 2 +- arrow-select/src/coalesce.rs | 2 +- arrow-select/src/filter.rs | 16 ++++++++-------- parquet/src/arrow/array_reader/byte_array.rs | 4 ++-- .../arrow/array_reader/byte_array_dictionary.rs | 6 +++--- .../src/arrow/array_reader/byte_view_array.rs | 2 +- parquet/src/arrow/arrow_reader/mod.rs | 8 ++++---- parquet/src/arrow/arrow_writer/mod.rs | 6 +++--- parquet/src/arrow/buffer/bit_util.rs | 2 +- parquet/src/arrow/buffer/dictionary_buffer.rs | 4 ++-- parquet/src/arrow/record_reader/mod.rs | 6 +++--- parquet/tests/arrow_reader/bad_data.rs | 2 +- parquet/tests/arrow_reader/mod.rs | 4 ++-- parquet/tests/encryption/encryption.rs | 8 ++++---- 18 files changed, 45 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 527f07578cc8..c272435cedcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -160,6 +160,7 @@ bool_to_int_with_if = "warn" branches_sharing_code = "warn" checked_conversions = "warn" clear_with_drain = "warn" +cloned_instead_of_copied = "warn" coerce_container_to_any = "warn" comparison_chain = "warn" dbg_macro = "warn" diff --git a/arrow-buffer/src/buffer/boolean.rs b/arrow-buffer/src/buffer/boolean.rs index 591227a5c061..319cbbcf049e 100644 --- a/arrow-buffer/src/buffer/boolean.rs +++ b/arrow-buffer/src/buffer/boolean.rs @@ -255,7 +255,7 @@ impl BooleanBuffer { let suffix = read_u64(suffix); let result_u64s: Vec = aligned_u64s .iter() - .cloned() + .copied() .chain(std::iter::once(suffix)) .map(&mut op) .collect(); @@ -375,11 +375,11 @@ impl BooleanBuffer { ([], left_suf, [], right_suf) => { let left_iter = left_u64s .iter() - .cloned() + .copied() .chain((!left_suf.is_empty()).then(|| read_u64(left_suf))); let right_iter = right_u64s .iter() - .cloned() + .copied() .chain((!right_suf.is_empty()).then(|| read_u64(right_suf))); let result_u64s: Vec = left_iter.zip(right_iter).map(|(l, r)| op(l, r)).collect(); diff --git a/arrow-buffer/src/buffer/scalar.rs b/arrow-buffer/src/buffer/scalar.rs index f74b93ab8914..753f15c6f540 100644 --- a/arrow-buffer/src/buffer/scalar.rs +++ b/arrow-buffer/src/buffer/scalar.rs @@ -287,7 +287,7 @@ mod tests { #[test] fn test_basic() { let expected = [0_i32, 1, 2]; - let buffer = Buffer::from_iter(expected.iter().cloned()); + let buffer = Buffer::from_iter(expected.iter().copied()); let typed = ScalarBuffer::::new(buffer.clone(), 0, 3); assert_eq!(*typed, expected); @@ -311,7 +311,7 @@ mod tests { #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")] fn test_unaligned() { let expected = [0_i32, 1, 2]; - let buffer = Buffer::from_iter(expected.iter().cloned()); + let buffer = Buffer::from_iter(expected.iter().copied()); let buffer = buffer.slice(1); ScalarBuffer::::new(buffer, 0, 2); } diff --git a/arrow-buffer/src/util/bit_chunk_iterator.rs b/arrow-buffer/src/util/bit_chunk_iterator.rs index 55a7583f36b5..5fda66501a41 100644 --- a/arrow-buffer/src/util/bit_chunk_iterator.rs +++ b/arrow-buffer/src/util/bit_chunk_iterator.rs @@ -160,7 +160,7 @@ impl<'a> UnalignedBitChunk<'a> { pub fn iter(&self) -> UnalignedBitChunkIterator<'a> { self.prefix .into_iter() - .chain(self.chunks.iter().cloned()) + .chain(self.chunks.iter().copied()) .chain(self.suffix) } @@ -181,7 +181,7 @@ impl<'a> IntoIterator for &UnalignedBitChunk<'a> { /// Iterator over an [`UnalignedBitChunk`] pub type UnalignedBitChunkIterator<'a> = std::iter::Chain< - std::iter::Chain, std::iter::Cloned>>, + std::iter::Chain, std::iter::Copied>>, std::option::IntoIter, >; @@ -732,7 +732,7 @@ mod tests { .take(mask_len) .collect(); - let buffer = Buffer::from_iter(bools.iter().cloned()); + let buffer = Buffer::from_iter(bools.iter().copied()); let max_offset = 64.min(mask_len); let offset = uusize.sample(&mut rng).checked_rem(max_offset).unwrap_or(0); diff --git a/arrow-flight/src/sql/metadata/sql_info.rs b/arrow-flight/src/sql/metadata/sql_info.rs index 885d15dd6f87..ec4f901b84de 100644 --- a/arrow-flight/src/sql/metadata/sql_info.rs +++ b/arrow-flight/src/sql/metadata/sql_info.rs @@ -356,7 +356,7 @@ impl SqlInfoDataBuilder { let mut name_builder = UInt32Builder::new(); let mut value_builder = SqlInfoUnionBuilder::new(); - let mut names: Vec<_> = self.infos.keys().cloned().collect(); + let mut names: Vec<_> = self.infos.keys().copied().collect(); names.sort_unstable(); for key in names { diff --git a/arrow-select/src/coalesce.rs b/arrow-select/src/coalesce.rs index 1889a0360e46..5a567a92348a 100644 --- a/arrow-select/src/coalesce.rs +++ b/arrow-select/src/coalesce.rs @@ -2069,7 +2069,7 @@ mod tests { let values: Vec<_> = values.into_iter().collect(); let values_iter = std::iter::repeat(values.iter()) .flatten() - .cloned() + .copied() .take(num_rows); let mut builder = StringViewBuilder::with_capacity(100).with_fixed_block_size(8192); diff --git a/arrow-select/src/filter.rs b/arrow-select/src/filter.rs index 1c49826fe3d3..be2fb1891879 100644 --- a/arrow-select/src/filter.rs +++ b/arrow-select/src/filter.rs @@ -902,16 +902,16 @@ where filter.extend_slices(SlicesIterator::new(&predicate.filter)) } IterationStrategy::Slices(slices) => { - filter.extend_offsets_slices(slices.iter().cloned(), predicate.count); - filter.extend_slices(slices.iter().cloned()) + filter.extend_offsets_slices(slices.iter().copied(), predicate.count); + filter.extend_slices(slices.iter().copied()) } IterationStrategy::IndexIterator => { filter.extend_offsets_idx(IndexIterator::new(&predicate.filter, predicate.count)); filter.extend_idx(IndexIterator::new(&predicate.filter, predicate.count)) } IterationStrategy::Indices(indices) => { - filter.extend_offsets_idx(indices.iter().cloned()); - filter.extend_idx(indices.iter().cloned()) + filter.extend_offsets_idx(indices.iter().copied()); + filter.extend_idx(indices.iter().copied()) } IterationStrategy::All | IterationStrategy::None => unreachable!(), } @@ -1788,7 +1788,7 @@ mod tests { .take(mask_len) .collect(); - let buffer = Buffer::from_iter(bools.iter().cloned()); + let buffer = Buffer::from_iter(bools.iter().copied()); let truncated_length = mask_len - offset - truncate; @@ -1909,7 +1909,7 @@ mod tests { .take(array_len + filter_offset - filter_truncate) .collect(); - let predicate = BooleanArray::from_iter(bools.iter().cloned().map(Some)); + let predicate = BooleanArray::from_iter(bools.iter().copied().map(Some)); // Offset predicate let predicate = predicate.slice(filter_offset, array_len - filter_truncate); @@ -1918,7 +1918,7 @@ mod tests { // Test i32 let values = gen_primitive(array_len + array_offset, valid_percent); - let src = Int32Array::from_iter(values.iter().cloned()); + let src = Int32Array::from_iter(values.iter().copied()); let src = src.slice(array_offset, array_len); let src = src.as_any().downcast_ref::().unwrap(); @@ -1928,7 +1928,7 @@ mod tests { let array = filtered.as_any().downcast_ref::().unwrap(); let actual: Vec<_> = array.iter().collect(); - assert_eq!(actual, filter_rust(values.iter().cloned(), bools)); + assert_eq!(actual, filter_rust(values.iter().copied(), bools)); // Test string let strings = gen_strings(array_len + array_offset, valid_percent, 0..20); diff --git a/parquet/src/arrow/array_reader/byte_array.rs b/parquet/src/arrow/array_reader/byte_array.rs index 4fc32dd803b7..a7a76f1309bc 100644 --- a/parquet/src/arrow/array_reader/byte_array.rs +++ b/parquet/src/arrow/array_reader/byte_array.rs @@ -658,7 +658,7 @@ mod tests { assert_eq!(decoder.read(&mut output, 4).unwrap(), 0); let valid = [false, false, true, true, false, true, true, false, false]; - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); output .pad_nulls(0, 4, valid.len(), valid_buffer.as_slice()) @@ -714,7 +714,7 @@ mod tests { assert_eq!(decoder.read(&mut output, 4).unwrap(), 0); let valid = [false, false, true, true, false, false]; - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); output .pad_nulls(0, 2, valid.len(), valid_buffer.as_slice()) diff --git a/parquet/src/arrow/array_reader/byte_array_dictionary.rs b/parquet/src/arrow/array_reader/byte_array_dictionary.rs index 65f2d9cb0a7a..14a2bd1241d2 100644 --- a/parquet/src/arrow/array_reader/byte_array_dictionary.rs +++ b/parquet/src/arrow/array_reader/byte_array_dictionary.rs @@ -437,7 +437,7 @@ mod tests { assert_eq!(decoder.read(&mut output, 3).unwrap(), 3); let mut valid = vec![false, false, true, true, false, true]; - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); output .pad_nulls(0, 3, valid.len(), valid_buffer.as_slice()) .unwrap(); @@ -447,7 +447,7 @@ mod tests { assert_eq!(decoder.read(&mut output, 4).unwrap(), 4); valid.extend_from_slice(&[false, false, true, true, false, true, true, false]); - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); output.pad_nulls(6, 4, 8, valid_buffer.as_slice()).unwrap(); assert!(matches!(output, DictionaryBuffer::Dict { .. })); @@ -518,7 +518,7 @@ mod tests { assert_eq!(decoder.skip_values(4).unwrap(), 0); let valid = [true, true, true, true, true]; - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); output.pad_nulls(0, 5, 5, valid_buffer.as_slice()).unwrap(); assert!(matches!(output, DictionaryBuffer::Dict { .. })); diff --git a/parquet/src/arrow/array_reader/byte_view_array.rs b/parquet/src/arrow/array_reader/byte_view_array.rs index b8595f723318..51a75151ce78 100644 --- a/parquet/src/arrow/array_reader/byte_view_array.rs +++ b/parquet/src/arrow/array_reader/byte_view_array.rs @@ -801,7 +801,7 @@ mod tests { assert_eq!(output.views.len(), 4); let valid = [false, false, true, true, false, true, true, false, false]; - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); output .pad_nulls(0, 4, valid.len(), valid_buffer.as_slice()) diff --git a/parquet/src/arrow/arrow_reader/mod.rs b/parquet/src/arrow/arrow_reader/mod.rs index 7ab219086fec..adf148d57714 100644 --- a/parquet/src/arrow/arrow_reader/mod.rs +++ b/parquet/src/arrow/arrow_reader/mod.rs @@ -1939,14 +1939,14 @@ pub(crate) mod tests { 2, ConvertedType::NONE, None, - |vals| Arc::new(BooleanArray::from_iter(vals.iter().cloned())), + |vals| Arc::new(BooleanArray::from_iter(vals.iter().copied())), &[Encoding::PLAIN, Encoding::RLE, Encoding::RLE_DICTIONARY], ); run_single_column_reader_tests::( 2, ConvertedType::NONE, None, - |vals| Arc::new(Int32Array::from_iter(vals.iter().cloned())), + |vals| Arc::new(Int32Array::from_iter(vals.iter().copied())), &[ Encoding::PLAIN, Encoding::RLE_DICTIONARY, @@ -1958,7 +1958,7 @@ pub(crate) mod tests { 2, ConvertedType::NONE, None, - |vals| Arc::new(Int64Array::from_iter(vals.iter().cloned())), + |vals| Arc::new(Int64Array::from_iter(vals.iter().copied())), &[ Encoding::PLAIN, Encoding::RLE_DICTIONARY, @@ -1970,7 +1970,7 @@ pub(crate) mod tests { 2, ConvertedType::NONE, None, - |vals| Arc::new(Float32Array::from_iter(vals.iter().cloned())), + |vals| Arc::new(Float32Array::from_iter(vals.iter().copied())), &[Encoding::PLAIN, Encoding::BYTE_STREAM_SPLIT], ); } diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 2835cf7c6340..3c6b8cd1c2e6 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -4445,7 +4445,7 @@ mod tests { u32::MAX - 1, u32::MAX, ]; - let values = Arc::new(UInt32Array::from_iter_values(src.iter().cloned())); + let values = Arc::new(UInt32Array::from_iter_values(src.iter().copied())); let files = RoundTripTest::new(values).with_nullable(false).run(); for file in files { @@ -4491,7 +4491,7 @@ mod tests { u64::MAX - 1, u64::MAX, ]; - let values = Arc::new(UInt64Array::from_iter_values(src.iter().cloned())); + let values = Arc::new(UInt64Array::from_iter_values(src.iter().copied())); let files = RoundTripTest::new(values).with_nullable(false).run(); for file in files { @@ -4694,7 +4694,7 @@ mod tests { .unwrap() .values() .iter() - .cloned() + .copied() }) .collect(); diff --git a/parquet/src/arrow/buffer/bit_util.rs b/parquet/src/arrow/buffer/bit_util.rs index 985943b851ac..3a288bf7d13a 100644 --- a/parquet/src/arrow/buffer/bit_util.rs +++ b/parquet/src/arrow/buffer/bit_util.rs @@ -33,7 +33,7 @@ pub fn iter_set_bits_rev(bytes: &[u8]) -> impl Iterator + '_ { let iter = unaligned .prefix() .into_iter() - .chain(unaligned.chunks().iter().cloned()) + .chain(unaligned.chunks().iter().copied()) .chain(unaligned.suffix()); iter.rev().flat_map(move |chunk| { diff --git a/parquet/src/arrow/buffer/dictionary_buffer.rs b/parquet/src/arrow/buffer/dictionary_buffer.rs index fd0d2102f2e0..96099b3886f5 100644 --- a/parquet/src/arrow/buffer/dictionary_buffer.rs +++ b/parquet/src/arrow/buffer/dictionary_buffer.rs @@ -300,7 +300,7 @@ mod tests { buffer.as_keys(&d1).unwrap().extend_from_slice(values); let mut valid = vec![false, false, true, true, false, true, true, true]; - let valid_buffer = Buffer::from_iter(valid.iter().cloned()); + let valid_buffer = Buffer::from_iter(valid.iter().copied()); buffer .pad_nulls(0, values.len(), valid.len(), valid_buffer.as_slice()) .unwrap(); @@ -313,7 +313,7 @@ mod tests { values.try_push("bongo".as_bytes(), false).unwrap(); valid.extend_from_slice(&[false, false, true, false, true]); - let null_buffer = Buffer::from_iter(valid.iter().cloned()); + let null_buffer = Buffer::from_iter(valid.iter().copied()); buffer .pad_nulls(read_offset, 2, 5, null_buffer.as_slice()) .unwrap(); diff --git a/parquet/src/arrow/record_reader/mod.rs b/parquet/src/arrow/record_reader/mod.rs index ba3c525b4ab1..d4b2f5cefdba 100644 --- a/parquet/src/arrow/record_reader/mod.rs +++ b/parquet/src/arrow/record_reader/mod.rs @@ -605,7 +605,7 @@ mod tests { // Verify bitmap let expected_valid = &[false, true, false, true, true, false, true]; - let expected_buffer = Buffer::from_iter(expected_valid.iter().cloned()); + let expected_buffer = Buffer::from_iter(expected_valid.iter().copied()); assert_eq!(Some(expected_buffer), record_reader.consume_bitmap()); // Verify result record data @@ -711,7 +711,7 @@ mod tests { // Verify bitmap let expected_valid = &[true, false, false, true, true, true, true, true, true]; - let expected_buffer = Buffer::from_iter(expected_valid.iter().cloned()); + let expected_buffer = Buffer::from_iter(expected_valid.iter().copied()); assert_eq!(Some(expected_buffer), record_reader.consume_bitmap()); // Verify result record data @@ -1063,7 +1063,7 @@ mod tests { // Verify bitmap let expected_valid = &[false, true, true]; - let expected_buffer = Buffer::from_iter(expected_valid.iter().cloned()); + let expected_buffer = Buffer::from_iter(expected_valid.iter().copied()); assert_eq!(Some(expected_buffer), record_reader.consume_bitmap()); // Verify result record data diff --git a/parquet/tests/arrow_reader/bad_data.rs b/parquet/tests/arrow_reader/bad_data.rs index b3173138fbf5..b43e55317974 100644 --- a/parquet/tests/arrow_reader/bad_data.rs +++ b/parquet/tests/arrow_reader/bad_data.rs @@ -50,7 +50,7 @@ fn bad_data_dir() -> PathBuf { #[test] // Ensure that if we add a new test the files are added to the tests. fn test_invalid_files() { - let known_files: HashSet<_> = KNOWN_FILES.iter().cloned().collect(); + let known_files: HashSet<_> = KNOWN_FILES.iter().copied().collect(); let mut seen_files = HashSet::new(); let files = std::fs::read_dir(bad_data_dir()).unwrap(); diff --git a/parquet/tests/arrow_reader/mod.rs b/parquet/tests/arrow_reader/mod.rs index c4c15d77a2a6..c7c77e0a444c 100644 --- a/parquet/tests/arrow_reader/mod.rs +++ b/parquet/tests/arrow_reader/mod.rs @@ -675,8 +675,8 @@ fn make_dict_batch() -> RecordBatch { Some("fffff"), Some("aaa"), ]; - let dict_i8_array = DictionaryArray::::from_iter(values.iter().cloned()); - let dict_i32_array = DictionaryArray::::from_iter(values.iter().cloned()); + let dict_i8_array = DictionaryArray::::from_iter(values.iter().copied()); + let dict_i32_array = DictionaryArray::::from_iter(values.iter().copied()); // Dictionary array of integers let int64_values = Int64Array::from(vec![0, -100, 100]); diff --git a/parquet/tests/encryption/encryption.rs b/parquet/tests/encryption/encryption.rs index 37c08f82bd81..8dc4b6168bea 100644 --- a/parquet/tests/encryption/encryption.rs +++ b/parquet/tests/encryption/encryption.rs @@ -631,7 +631,7 @@ fn uniform_encryption_roundtrip( .unwrap() .values() .iter() - .cloned() + .copied() }) .collect(); @@ -644,7 +644,7 @@ fn uniform_encryption_roundtrip( .unwrap() .values() .iter() - .cloned() + .copied() }) .collect(); @@ -743,7 +743,7 @@ fn uniform_encryption_page_skipping(page_index: bool) -> parquet::errors::Result .unwrap() .values() .iter() - .cloned() + .copied() }) .collect(); @@ -756,7 +756,7 @@ fn uniform_encryption_page_skipping(page_index: bool) -> parquet::errors::Result .unwrap() .values() .iter() - .cloned() + .copied() }) .collect(); From 661fbc3176108e648e82208abb597268c839573e Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:51:26 +0200 Subject: [PATCH 13/17] Enable `clippy::needless_pass_by_ref_mut` An `&mut` that is never used mutably asks callers for more than the function needs, which can stop them from sharing the value at all. Most of the sites are the stateless Avro encoders, which only read their array. The `#[cfg(not(feature = "encryption"))]` stubs keep their `&mut self` and get an `#[expect]` with a reason: their signatures mirror the encryption-enabled versions so callers need no `cfg` of their own. --- Cargo.toml | 1 + arrow-avro/src/writer/encoder.rs | 70 +++++++++---------- arrow-ipc/src/reader.rs | 4 +- .../src/arrow_to_variant.rs | 2 +- .../src/unshred_variant.rs | 10 +-- .../arrow/array_reader/cached_array_reader.rs | 2 +- .../array_reader/fixed_len_byte_array.rs | 2 +- parquet/src/arrow/arrow_reader/mod.rs | 2 +- parquet/src/arrow/arrow_writer/mod.rs | 6 ++ .../src/column/page_encryption_disabled.rs | 7 ++ parquet/src/column/reader/decoder.rs | 2 +- parquet/src/file/metadata/mod.rs | 10 +-- parquet/src/file/metadata/thrift/mod.rs | 6 +- parquet/src/file/writer.rs | 6 ++ 14 files changed, 75 insertions(+), 55 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c272435cedcd..e4c9b451b7c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -224,6 +224,7 @@ mismatching_type_param_order = "warn" mut_mut = "warn" mutex_integer = "warn" needless_continue = "warn" +needless_pass_by_ref_mut = "warn" needless_raw_string_hashes = "warn" needless_type_cast = "warn" negative_feature_names = "warn" diff --git a/arrow-avro/src/writer/encoder.rs b/arrow-avro/src/writer/encoder.rs index 4d1140677c46..29dfa8e5aea0 100644 --- a/arrow-avro/src/writer/encoder.rs +++ b/arrow-avro/src/writer/encoder.rs @@ -1464,7 +1464,7 @@ impl<'a> Encoder<'a> { struct BooleanEncoder<'a>(&'a arrow_array::BooleanArray); impl BooleanEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_bool(out, self.0.value(idx)) } } @@ -1472,7 +1472,7 @@ impl BooleanEncoder<'_> { /// Generic Avro `int` encoder for primitive arrays with `i32` native values. struct IntEncoder<'a, P: ArrowPrimitiveType>(&'a PrimitiveArray

); impl<'a, P: ArrowPrimitiveType> IntEncoder<'a, P> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx)) } } @@ -1480,7 +1480,7 @@ impl<'a, P: ArrowPrimitiveType> IntEncoder<'a, P> { /// Generic Avro `long` encoder for primitive arrays with `i64` native values. struct LongEncoder<'a, P: ArrowPrimitiveType>(&'a PrimitiveArray

); impl<'a, P: ArrowPrimitiveType> LongEncoder<'a, P> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_long(out, self.0.value(idx)) } } @@ -1489,7 +1489,7 @@ impl<'a, P: ArrowPrimitiveType> LongEncoder<'a, P> { struct Time32SecondsToMillisEncoder<'a>(&'a PrimitiveArray); impl<'a> Time32SecondsToMillisEncoder<'a> { #[inline] - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let secs = self.0.value(idx); let millis = secs .checked_mul(1000) @@ -1504,7 +1504,7 @@ struct TimestampSecondsToMillisEncoder<'a>(&'a PrimitiveArray TimestampSecondsToMillisEncoder<'a> { #[inline] - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let secs = self.0.value(idx); let millis = secs.checked_mul(1000).ok_or_else(|| { AvroError::InvalidArgument("timestamp(secs) * 1000 overflowed".into()) @@ -1518,7 +1518,7 @@ impl<'a> TimestampSecondsToMillisEncoder<'a> { struct Int8Encoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl Int8Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1528,7 +1528,7 @@ impl Int8Encoder<'_> { struct Int16Encoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl Int16Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1538,7 +1538,7 @@ impl Int16Encoder<'_> { struct UInt8Encoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl UInt8Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1548,7 +1548,7 @@ impl UInt8Encoder<'_> { struct UInt16Encoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl UInt16Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1558,7 +1558,7 @@ impl UInt16Encoder<'_> { struct UInt32Encoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl UInt32Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_long(out, self.0.value(idx) as i64) } } @@ -1568,7 +1568,7 @@ impl UInt32Encoder<'_> { struct UInt64FixedEncoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl UInt64FixedEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let v = self.0.value(idx); out.write_all(&v.to_le_bytes())?; Ok(()) @@ -1580,7 +1580,7 @@ impl UInt64FixedEncoder<'_> { struct Float16FixedEncoder<'a>(&'a Float16Array); #[cfg(feature = "avro_custom_types")] impl Float16FixedEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let v = self.0.value(idx); out.write_all(&v.to_le_bytes())?; Ok(()) @@ -1598,7 +1598,7 @@ impl Float16FixedEncoder<'_> { struct IntervalMonthDayNanoFixedEncoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl IntervalMonthDayNanoFixedEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let v = self.0.value(idx); let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(v); out.write_all(&months.to_le_bytes())?; @@ -1613,7 +1613,7 @@ impl IntervalMonthDayNanoFixedEncoder<'_> { struct IntervalYearMonthFixedEncoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl IntervalYearMonthFixedEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let months = self.0.value(idx); out.write_all(&months.to_le_bytes())?; Ok(()) @@ -1625,7 +1625,7 @@ impl IntervalYearMonthFixedEncoder<'_> { struct IntervalDayTimeFixedEncoder<'a>(&'a PrimitiveArray); #[cfg(feature = "avro_custom_types")] impl IntervalDayTimeFixedEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let dt = self.0.value(idx); out.write_all(&dt.days.to_le_bytes())?; out.write_all(&dt.milliseconds.to_le_bytes())?; @@ -1638,7 +1638,7 @@ impl IntervalDayTimeFixedEncoder<'_> { struct Int8ToIntEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl Int8ToIntEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1648,7 +1648,7 @@ impl Int8ToIntEncoder<'_> { struct Int16ToIntEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl Int16ToIntEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1658,7 +1658,7 @@ impl Int16ToIntEncoder<'_> { struct UInt8ToIntEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl UInt8ToIntEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1668,7 +1668,7 @@ impl UInt8ToIntEncoder<'_> { struct UInt16ToIntEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl UInt16ToIntEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_int(out, self.0.value(idx) as i32) } } @@ -1678,7 +1678,7 @@ impl UInt16ToIntEncoder<'_> { struct UInt32ToLongEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl UInt32ToLongEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_long(out, self.0.value(idx) as i64) } } @@ -1688,7 +1688,7 @@ impl UInt32ToLongEncoder<'_> { struct UInt64ToLongEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl UInt64ToLongEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let v = self.0.value(idx); if v > i64::MAX as u64 { return Err(AvroError::InvalidArgument(format!( @@ -1704,7 +1704,7 @@ impl UInt64ToLongEncoder<'_> { struct Float16ToFloatEncoder<'a>(&'a Float16Array); #[cfg(not(feature = "avro_custom_types"))] impl Float16ToFloatEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { out.write_all(&self.0.value(idx).to_f32().to_bits().to_le_bytes())?; Ok(()) } @@ -1715,7 +1715,7 @@ impl Float16ToFloatEncoder<'_> { struct Date64ToLongEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl Date64ToLongEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_long(out, self.0.value(idx)) } } @@ -1725,7 +1725,7 @@ impl Date64ToLongEncoder<'_> { struct Time64NanosToMicrosEncoder<'a>(&'a PrimitiveArray); #[cfg(not(feature = "avro_custom_types"))] impl Time64NanosToMicrosEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let nanos = self.0.value(idx); let micros = nanos / 1000; write_long(out, micros) @@ -1735,7 +1735,7 @@ impl Time64NanosToMicrosEncoder<'_> { /// Unified binary encoder generic over offset size (i32/i64). struct BinaryEncoder<'a, O: OffsetSizeTrait>(&'a GenericBinaryArray); impl<'a, O: OffsetSizeTrait> BinaryEncoder<'a, O> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_len_prefixed(out, self.0.value(idx)) } } @@ -1743,7 +1743,7 @@ impl<'a, O: OffsetSizeTrait> BinaryEncoder<'a, O> { /// BinaryView (byte view) encoder. struct BinaryViewEncoder<'a>(&'a BinaryViewArray); impl BinaryViewEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_len_prefixed(out, self.0.value(idx)) } } @@ -1751,14 +1751,14 @@ impl BinaryViewEncoder<'_> { /// StringView encoder. struct Utf8ViewEncoder<'a>(&'a StringViewArray); impl Utf8ViewEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_len_prefixed(out, self.0.value(idx).as_bytes()) } } struct F32Encoder<'a>(&'a arrow_array::Float32Array); impl F32Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { // Avro float: 4 bytes, IEEE-754 little-endian out.write_all(&self.0.value(idx).to_bits().to_le_bytes())?; Ok(()) @@ -1767,7 +1767,7 @@ impl F32Encoder<'_> { struct F64Encoder<'a>(&'a arrow_array::Float64Array); impl F64Encoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { // Avro double: 8 bytes, IEEE-754 little-endian out.write_all(&self.0.value(idx).to_bits().to_le_bytes()) .map_err(Into::into) @@ -1777,7 +1777,7 @@ impl F64Encoder<'_> { struct Utf8GenericEncoder<'a, O: OffsetSizeTrait>(&'a GenericStringArray); impl<'a, O: OffsetSizeTrait> Utf8GenericEncoder<'a, O> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { write_len_prefixed(out, self.0.value(idx).as_bytes()) } } @@ -1885,7 +1885,7 @@ struct EnumEncoder<'a> { keys: &'a PrimitiveArray, } impl EnumEncoder<'_> { - fn encode(&mut self, out: &mut W, row: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, row: usize) -> Result<(), AvroError> { write_int(out, self.keys.value(row)) } } @@ -2140,7 +2140,7 @@ impl<'a> FixedSizeListEncoder<'a> { /// Spec: a fixed is encoded as exactly `size` bytes, with no length prefix. struct FixedEncoder<'a>(&'a FixedSizeBinaryArray); impl FixedEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let v = self.0.value(idx); // &[u8] of fixed width out.write_all(v)?; Ok(()) @@ -2151,7 +2151,7 @@ impl FixedEncoder<'_> { /// Spec: uuid is a logical type over string (RFC‑4122). We output hyphenated form. struct UuidEncoder<'a>(&'a FixedSizeBinaryArray); impl UuidEncoder<'_> { - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let mut buf = [0u8; 1 + uuid::fmt::Hyphenated::LENGTH]; buf[0] = 0x48; let v = self.0.value(idx); @@ -2235,7 +2235,7 @@ impl IntervalToDurationParts for IntervalDayTimeType { struct DurationEncoder<'a, P: ArrowPrimitiveType + IntervalToDurationParts>(&'a PrimitiveArray

); impl<'a, P: ArrowPrimitiveType + IntervalToDurationParts> DurationEncoder<'a, P> { #[inline(always)] - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let parts = P::duration_parts(self.0.value(idx))?; let months = parts.months.to_le_bytes(); let days = parts.days.to_le_bytes(); @@ -2308,7 +2308,7 @@ impl<'a, const N: usize, A: DecimalBeBytes> DecimalEncoder<'a, N, A> { Self { arr, fixed_size } } - fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { + fn encode(&self, out: &mut W, idx: usize) -> Result<(), AvroError> { let be = self.arr.value_be_bytes(idx); match self.fixed_size { Some(n) => write_sign_extended(out, &be, n), diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs index 77f4cb300cd8..f58d84239051 100644 --- a/arrow-ipc/src/reader.rs +++ b/arrow-ipc/src/reader.rs @@ -870,7 +870,7 @@ fn get_dictionary_values( buf: &Buffer, batch: crate::DictionaryBatch, schema: &Schema, - dictionaries_by_id: &mut HashMap, + dictionaries_by_id: &HashMap, metadata: &MetadataVersion, require_alignment: bool, skip_validation: UnsafeFlag, @@ -1719,7 +1719,7 @@ impl StreamReader { &body.into(), dict, &self.schema, - &mut self.dictionaries_by_id, + &self.dictionaries_by_id, &version, false, self.skip_validation.clone(), diff --git a/parquet-variant-compute/src/arrow_to_variant.rs b/parquet-variant-compute/src/arrow_to_variant.rs index b9e7fff06461..3eed7eec6ce0 100644 --- a/parquet-variant-compute/src/arrow_to_variant.rs +++ b/parquet-variant-compute/src/arrow_to_variant.rs @@ -501,7 +501,7 @@ pub(crate) struct NullArrowToVariantBuilder; impl NullArrowToVariantBuilder { fn append_row( - &mut self, + &self, builder: &mut impl VariantBuilderExt, _index: usize, ) -> Result<(), ArrowError> { diff --git a/parquet-variant-compute/src/unshred_variant.rs b/parquet-variant-compute/src/unshred_variant.rs index 18cc8a8d7522..14afb8db1274 100644 --- a/parquet-variant-compute/src/unshred_variant.rs +++ b/parquet-variant-compute/src/unshred_variant.rs @@ -361,7 +361,7 @@ struct NullUnshredVariantBuilder; impl NullUnshredVariantBuilder { fn append_row( - &mut self, + &self, builder: &mut impl VariantBuilderExt, _metadata: &VariantMetadata, _index: usize, @@ -382,7 +382,7 @@ impl<'a> ValueOnlyUnshredVariantBuilder<'a> { } fn append_row( - &mut self, + &self, builder: &mut impl VariantBuilderExt, metadata: &VariantMetadata, index: usize, @@ -462,7 +462,7 @@ impl<'a, T: AppendToVariantBuilder> UnshredPrimitiveRowBuilder<'a, T> { } fn append_row( - &mut self, + &self, builder: &mut impl VariantBuilderExt, metadata: &VariantMetadata, index: usize, @@ -570,7 +570,7 @@ impl<'a, T: TimestampType> TimestampUnshredRowBuilder<'a, T> { } fn append_row( - &mut self, + &self, builder: &mut impl VariantBuilderExt, metadata: &VariantMetadata, index: usize, @@ -614,7 +614,7 @@ where } fn append_row( - &mut self, + &self, builder: &mut impl VariantBuilderExt, metadata: &VariantMetadata, index: usize, diff --git a/parquet/src/arrow/array_reader/cached_array_reader.rs b/parquet/src/arrow/array_reader/cached_array_reader.rs index 73f3ba6c8fb2..5e4d91ce307b 100644 --- a/parquet/src/arrow/array_reader/cached_array_reader.rs +++ b/parquet/src/arrow/array_reader/cached_array_reader.rs @@ -165,7 +165,7 @@ impl CachedArrayReader { /// Remove batches from cache that have been completely consumed /// This is only called for Consumer role readers - fn cleanup_consumed_batches(&mut self) { + fn cleanup_consumed_batches(&self) { let current_batch_id = self.get_batch_id_from_position(self.outer_position); // Remove batches that are at least one batch behind the current position diff --git a/parquet/src/arrow/array_reader/fixed_len_byte_array.rs b/parquet/src/arrow/array_reader/fixed_len_byte_array.rs index 91e5076f45bf..436e1db343f1 100644 --- a/parquet/src/arrow/array_reader/fixed_len_byte_array.rs +++ b/parquet/src/arrow/array_reader/fixed_len_byte_array.rs @@ -558,7 +558,7 @@ impl ColumnValueDecoder for ValueDecoder { // `offset`. Values will be appended to `dst`. fn read_byte_stream_split( dst: &mut Vec, - src: &mut Bytes, + src: &Bytes, offset: usize, num_values: usize, data_width: usize, diff --git a/parquet/src/arrow/arrow_reader/mod.rs b/parquet/src/arrow/arrow_reader/mod.rs index adf148d57714..5d8d0396f7af 100644 --- a/parquet/src/arrow/arrow_reader/mod.rs +++ b/parquet/src/arrow/arrow_reader/mod.rs @@ -1310,7 +1310,7 @@ struct ReaderPageIterator { impl ReaderPageIterator { /// Return the next SerializedPageReader - fn next_page_reader(&mut self, rg_idx: usize) -> Result> { + fn next_page_reader(&self, rg_idx: usize) -> Result> { let rg = self.metadata.row_group(rg_idx); let column_chunk_metadata = rg.column(self.column_idx); let offset_index = self.metadata.offset_index(); diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 3c6b8cd1c2e6..3d3e523ce1f6 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -818,7 +818,13 @@ impl ArrowPageWriter { self.page_encryptor.as_mut() } + // Mirrors the signature of the encryption-enabled version above, so that the + // callers do not need a `cfg` of their own. #[cfg(not(feature = "encryption"))] + #[expect( + clippy::needless_pass_by_ref_mut, + reason = "mirrors the encryption-enabled signature" + )] fn page_encryptor_mut(&mut self) -> Option<&mut PageEncryptor> { None } diff --git a/parquet/src/column/page_encryption_disabled.rs b/parquet/src/column/page_encryption_disabled.rs index 71f25862cc34..e2f227ff5cc9 100644 --- a/parquet/src/column/page_encryption_disabled.rs +++ b/parquet/src/column/page_encryption_disabled.rs @@ -15,6 +15,13 @@ // specific language governing permissions and limitations // under the License. +// The methods below mirror the signatures of the real `PageEncryptor`, so that the +// callers do not need a `cfg` of their own. +#![expect( + clippy::needless_pass_by_ref_mut, + reason = "mirrors the encryption-enabled `PageEncryptor`" +)] + use crate::column::page::CompressedPage; use crate::errors::Result; use crate::file::metadata::thrift::PageHeader; diff --git a/parquet/src/column/reader/decoder.rs b/parquet/src/column/reader/decoder.rs index 053db813ce5d..4e579f8f0d70 100644 --- a/parquet/src/column/reader/decoder.rs +++ b/parquet/src/column/reader/decoder.rs @@ -392,7 +392,7 @@ impl RepetitionLevelDecoderImpl { /// and returns the number of "complete" records along with the corresponding number of values /// /// A "complete" record is one where the buffer contains a subsequent repetition level of 0 - fn count_records(&mut self, records_to_read: usize, num_levels: usize) -> (bool, usize, usize) { + fn count_records(&self, records_to_read: usize, num_levels: usize) -> (bool, usize, usize) { let mut records_read = 0; let levels = num_levels.min(self.buffer_len - self.buffer_offset); diff --git a/parquet/src/file/metadata/mod.rs b/parquet/src/file/metadata/mod.rs index 6fb136dbfe30..3b4451c21bd3 100644 --- a/parquet/src/file/metadata/mod.rs +++ b/parquet/src/file/metadata/mod.rs @@ -1781,7 +1781,7 @@ mod tests { let mut writer = ThriftCompactOutputProtocol::new(&mut buf); row_group_meta.write_thrift(&mut writer).unwrap(); - let row_group_res = read_row_group(&mut buf, schema_descr).unwrap(); + let row_group_res = read_row_group(&buf, schema_descr).unwrap(); assert_eq!(row_group_res, row_group_meta); } @@ -1863,7 +1863,7 @@ mod tests { let mut writer = ThriftCompactOutputProtocol::new(&mut buf); row_group_meta_2cols.write_thrift(&mut writer).unwrap(); - let err = read_row_group(&mut buf, schema_descr_3cols) + let err = read_row_group(&buf, schema_descr_3cols) .unwrap_err() .to_string(); assert_eq!( @@ -1913,7 +1913,7 @@ mod tests { let mut buf = Vec::new(); let mut writer = ThriftCompactOutputProtocol::new(&mut buf); col_metadata.write_thrift(&mut writer).unwrap(); - let col_chunk_res = read_column_chunk(&mut buf, column_descr.clone()).unwrap(); + let col_chunk_res = read_column_chunk(&buf, column_descr.clone()).unwrap(); let expected_metadata = ColumnChunkMetaData::builder(column_descr) .set_encodings_mask(EncodingMask::new_from_encodings( @@ -1978,7 +1978,7 @@ mod tests { let options = ParquetMetaDataOptions::new().with_encoding_stats_as_mask(false); let col_chunk_res = - read_column_chunk_with_options(&mut buf, column_descr, Some(&options)).unwrap(); + read_column_chunk_with_options(&buf, column_descr, Some(&options)).unwrap(); assert_eq!(col_chunk_res, col_metadata); } @@ -1994,7 +1994,7 @@ mod tests { let mut buf = Vec::new(); let mut writer = ThriftCompactOutputProtocol::new(&mut buf); col_metadata.write_thrift(&mut writer).unwrap(); - let col_chunk_res = read_column_chunk(&mut buf, column_descr).unwrap(); + let col_chunk_res = read_column_chunk(&buf, column_descr).unwrap(); assert_eq!(col_chunk_res, col_metadata); } diff --git a/parquet/src/file/metadata/thrift/mod.rs b/parquet/src/file/metadata/thrift/mod.rs index f8d50e07dcc1..3915e96a802a 100644 --- a/parquet/src/file/metadata/thrift/mod.rs +++ b/parquet/src/file/metadata/thrift/mod.rs @@ -1754,7 +1754,7 @@ pub(crate) mod tests { // for testing. decode thrift encoded RowGroup pub(crate) fn read_row_group( - buf: &mut [u8], + buf: &[u8], schema_descr: Arc, ) -> Result { let mut reader = ThriftSliceInputProtocol::new(buf); @@ -1762,14 +1762,14 @@ pub(crate) mod tests { } pub(crate) fn read_column_chunk( - buf: &mut [u8], + buf: &[u8], column_descr: Arc, ) -> Result { read_column_chunk_with_options(buf, column_descr, None) } pub(crate) fn read_column_chunk_with_options( - buf: &mut [u8], + buf: &[u8], column_descr: Arc, options: Option<&ParquetMetaDataOptions>, ) -> Result { diff --git a/parquet/src/file/writer.rs b/parquet/src/file/writer.rs index aa17a5274a97..a4611bfce581 100644 --- a/parquet/src/file/writer.rs +++ b/parquet/src/file/writer.rs @@ -1072,7 +1072,13 @@ impl<'a, W: Write> SerializedPageWriter<'a, W> { } } +// These mirror the signatures of the encryption-enabled versions above, so that the +// callers do not need a `cfg` of their own. #[cfg(not(feature = "encryption"))] +#[expect( + clippy::needless_pass_by_ref_mut, + reason = "mirrors the encryption-enabled signatures" +)] impl<'a, W: Write> SerializedPageWriter<'a, W> { fn page_encryptor_mut(&mut self) -> Option<&mut PageEncryptor> { None From cb937b6c0ac9dcb800c2c8b88a34a700339195e5 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:55:43 +0200 Subject: [PATCH 14/17] Enable `clippy::match_wildcard_for_single_variants` A `_` arm that covers exactly one variant silently swallows every variant added later. Naming the variant makes the compiler point at the match when the enum grows. `get_encoder` keeps `Encoding::BIT_PACKED` explicit and gets an `#[expect(deprecated)]`: rejecting that encoding is the whole point of the arm. --- Cargo.toml | 1 + arrow-avro/src/codec.rs | 2 +- arrow-buffer/src/buffer/immutable.rs | 2 +- arrow-buffer/src/buffer/mutable.rs | 2 +- parquet-variant-compute/src/shred_variant.rs | 4 ++-- .../arrow/arrow_reader/selection/boolean.rs | 10 ++++---- .../src/arrow/arrow_reader/selection/mod.rs | 2 +- parquet/src/arrow/arrow_writer/mod.rs | 2 +- parquet/src/arrow/buffer/dictionary_buffer.rs | 6 ++--- parquet/src/arrow/schema/primitive.rs | 2 +- parquet/src/basic.rs | 2 +- parquet/src/column/chunker/cdc.rs | 2 +- parquet/src/column/page.rs | 2 +- parquet/src/column/page_encryption.rs | 2 +- parquet/src/column/writer/mod.rs | 4 ++-- parquet/src/compression.rs | 2 +- parquet/src/encodings/encoding/mod.rs | 3 ++- .../src/file/metadata/thrift/encryption.rs | 2 +- parquet/src/file/page_index/column_index.rs | 2 +- parquet/src/file/serialized_reader.rs | 8 +++---- parquet/src/parquet_thrift.rs | 2 +- parquet/src/record/reader.rs | 2 +- parquet/src/schema/types.rs | 24 ++++++++++--------- parquet/src/schema/visitor.rs | 2 +- parquet_derive/src/parquet_field.rs | 2 +- 25 files changed, 49 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e4c9b451b7c5..bea3cc1215ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -220,6 +220,7 @@ manual_is_variant_and = "warn" manual_midpoint = "warn" manual_string_new = "warn" match_wild_err_arm = "warn" +match_wildcard_for_single_variants = "warn" mismatching_type_param_order = "warn" mut_mut = "warn" mutex_integer = "warn" diff --git a/arrow-avro/src/codec.rs b/arrow-avro/src/codec.rs index ff3486db6235..76f642942bfe 100644 --- a/arrow-avro/src/codec.rs +++ b/arrow-avro/src/codec.rs @@ -2243,7 +2243,7 @@ impl<'a> Maker<'a> { Entry::Vacant(e) => { e.insert(idx); } - _ => {} + Entry::Occupied(_) => {} } } } diff --git a/arrow-buffer/src/buffer/immutable.rs b/arrow-buffer/src/buffer/immutable.rs index 551bb1a9215b..f44d9d75d228 100644 --- a/arrow-buffer/src/buffer/immutable.rs +++ b/arrow-buffer/src/buffer/immutable.rs @@ -434,7 +434,7 @@ impl Buffer { pub fn into_vec(self) -> Result, Self> { let layout = match self.data.deallocation() { Deallocation::Standard(l) => l, - _ => return Err(self), // Custom allocation + Deallocation::Custom(..) => return Err(self), }; if self.ptr != self.data.as_ptr() { diff --git a/arrow-buffer/src/buffer/mutable.rs b/arrow-buffer/src/buffer/mutable.rs index e83b0c47082d..629cdff3db6b 100644 --- a/arrow-buffer/src/buffer/mutable.rs +++ b/arrow-buffer/src/buffer/mutable.rs @@ -232,7 +232,7 @@ impl MutableBuffer { pub(crate) fn from_bytes(bytes: Bytes) -> Result { let layout = match bytes.deallocation() { Deallocation::Standard(layout) => *layout, - _ => return Err(bytes), + Deallocation::Custom(..) => return Err(bytes), }; let len = bytes.len(); diff --git a/parquet-variant-compute/src/shred_variant.rs b/parquet-variant-compute/src/shred_variant.rs index 03efb7c177cd..ae3ee4f0a3c2 100644 --- a/parquet-variant-compute/src/shred_variant.rs +++ b/parquet-variant-compute/src/shred_variant.rs @@ -639,11 +639,11 @@ impl VariantSchemaNode { // Ensure this node is a Struct node let children = match self { Self::Struct(children) => children, - _ => { + Self::Leaf(_) => { *self = Self::Struct(BTreeMap::new()); match self { Self::Struct(children) => children, - _ => unreachable!(), + Self::Leaf(_) => unreachable!(), } } }; diff --git a/parquet/src/arrow/arrow_reader/selection/boolean.rs b/parquet/src/arrow/arrow_reader/selection/boolean.rs index 5985d9c12ed2..1196fac2196b 100644 --- a/parquet/src/arrow/arrow_reader/selection/boolean.rs +++ b/parquet/src/arrow/arrow_reader/selection/boolean.rs @@ -386,13 +386,13 @@ mod tests { let _ = selection.iter().count(); match &selection.inner { RowSelectionInner::Mask(m) => assert!(m.selectors.get().is_some()), - _ => unreachable!(), + RowSelectionInner::Selectors(_) => unreachable!(), } let cloned = selection.clone(); match &cloned.inner { RowSelectionInner::Mask(m) => assert!(m.selectors.get().is_none()), - _ => unreachable!(), + RowSelectionInner::Selectors(_) => unreachable!(), } let round_tripped: Vec = cloned.iter().copied().collect(); @@ -417,7 +417,7 @@ mod tests { fn cached_selectors_ptr(selection: &RowSelection) -> Option<*const RowSelector> { match &selection.inner { RowSelectionInner::Mask(m) => m.selectors.get().map(|s| s.as_ptr()), - _ => unreachable!(), + RowSelectionInner::Selectors(_) => unreachable!(), } } @@ -454,7 +454,7 @@ mod tests { let selection = RowSelection::from_boolean_buffer(interleaved_mask()); let mask = match &selection.inner { RowSelectionInner::Mask(m) => m, - _ => unreachable!(), + RowSelectionInner::Selectors(_) => unreachable!(), }; // Uncached: converts into a temporary, leaving the cache empty. @@ -464,7 +464,7 @@ mod tests { let expected: Vec = selection.iter().copied().collect(); let mask = match &selection.inner { RowSelectionInner::Mask(m) => m, - _ => unreachable!(), + RowSelectionInner::Selectors(_) => unreachable!(), }; match mask.borrowed_selectors() { Cow::Borrowed(selectors) => assert_eq!(selectors, expected.as_slice()), diff --git a/parquet/src/arrow/arrow_reader/selection/mod.rs b/parquet/src/arrow/arrow_reader/selection/mod.rs index 517022f17354..d3fce6c5918e 100644 --- a/parquet/src/arrow/arrow_reader/selection/mod.rs +++ b/parquet/src/arrow/arrow_reader/selection/mod.rs @@ -229,7 +229,7 @@ impl RowSelection { pub fn as_mask(&self) -> Option<&BooleanBuffer> { match &self.inner { RowSelectionInner::Mask(m) => Some(m.mask()), - _ => None, + RowSelectionInner::Selectors(_) => None, } } diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 3d3e523ce1f6..71d122b93544 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -1697,7 +1697,7 @@ fn write_leaf( let array = column.as_primitive::(); get_interval_dt_array_slice(array, indices.iter().copied()) } - _ => { + IntervalUnit::MonthDayNano => { return Err(ParquetError::NYI(format!( "Attempting to write an Arrow interval type {interval_unit:?} to parquet that is not yet implemented" ))); diff --git a/parquet/src/arrow/buffer/dictionary_buffer.rs b/parquet/src/arrow/buffer/dictionary_buffer.rs index 96099b3886f5..8aa367f8d821 100644 --- a/parquet/src/arrow/buffer/dictionary_buffer.rs +++ b/parquet/src/arrow/buffer/dictionary_buffer.rs @@ -80,10 +80,10 @@ impl DictionaryBuffer { }; match self { Self::Dict { keys, .. } => Some(keys), - _ => unreachable!(), + Self::Values { .. } => unreachable!(), } } - _ => None, + Self::Values { .. } => None, } } @@ -116,7 +116,7 @@ impl DictionaryBuffer { *self = Self::Values { values: spilled }; match self { Self::Values { values } => Ok(values), - _ => unreachable!(), + Self::Dict { .. } => unreachable!(), } } } diff --git a/parquet/src/arrow/schema/primitive.rs b/parquet/src/arrow/schema/primitive.rs index 2ca9b9b35e5c..ea35f68031cf 100644 --- a/parquet/src/arrow/schema/primitive.rs +++ b/parquet/src/arrow/schema/primitive.rs @@ -370,7 +370,7 @@ mod tests { precision, scale, }, - _ => unreachable!(), + Type::GroupType { .. } => unreachable!(), } } diff --git a/parquet/src/basic.rs b/parquet/src/basic.rs index af2d4c492ede..c92b5286ffff 100644 --- a/parquet/src/basic.rs +++ b/parquet/src/basic.rs @@ -856,7 +856,7 @@ impl EdgeInterpolationAlgorithm { Self::THOMAS => Ok(parquet_geospatial::WkbEdges::Thomas), Self::ANDOYER => Ok(parquet_geospatial::WkbEdges::Andoyer), Self::KARNEY => Ok(parquet_geospatial::WkbEdges::Karney), - unknown => Err(general_err!( + unknown @ Self::_Unknown(_) => Err(general_err!( "Unknown edge interpolation algorithm: {}", unknown )), diff --git a/parquet/src/column/chunker/cdc.rs b/parquet/src/column/chunker/cdc.rs index ca59913701dd..28a8bb3c0676 100644 --- a/parquet/src/column/chunker/cdc.rs +++ b/parquet/src/column/chunker/cdc.rs @@ -1024,7 +1024,7 @@ mod arrow_tests { crate::basic::PageType::DICTIONARY_PAGE => { info.has_dictionary_page = true; } - _ => {} + crate::basic::PageType::INDEX_PAGE => {} } } result.push(info); diff --git a/parquet/src/column/page.rs b/parquet/src/column/page.rs index ed80e279a03a..b0e60b9f0dfa 100644 --- a/parquet/src/column/page.rs +++ b/parquet/src/column/page.rs @@ -382,7 +382,7 @@ impl TryFrom<&crate::file::metadata::thrift::PageHeader> for PageMetadata { is_dict: false, }) } - other => Err(ParquetError::General(format!( + other @ PageType::INDEX_PAGE => Err(ParquetError::General(format!( "page type {other:?} cannot be converted to PageMetadata" ))), } diff --git a/parquet/src/column/page_encryption.rs b/parquet/src/column/page_encryption.rs index de9506342931..e9729a8b7ad8 100644 --- a/parquet/src/column/page_encryption.rs +++ b/parquet/src/column/page_encryption.rs @@ -99,7 +99,7 @@ impl PageEncryptor { PageType::DATA_PAGE => ModuleType::DataPageHeader, PageType::DATA_PAGE_V2 => ModuleType::DataPageHeader, PageType::DICTIONARY_PAGE => ModuleType::DictionaryPageHeader, - _ => { + PageType::INDEX_PAGE => { return Err(general_err!( "Unsupported page type for page header encryption: {:?}", page_header.r#type diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index f351ec6606f7..7600febc851f 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -1650,7 +1650,7 @@ impl<'a, E: ColumnValueEncoder> GenericColumnWriter<'a, E> { ); self.column_metrics.dictionary_page_offset = Some(page_spec.offset); } - _ => {} + PageType::INDEX_PAGE => {} } } @@ -5048,7 +5048,7 @@ mod tests { PageType::DICTIONARY_PAGE => { collected.dict_page_size = collected.dict_page_size.max(page.buffer().len()); } - _ => {} + PageType::INDEX_PAGE => {} } } collected diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index f3dd0e9e86e6..8d25891e90a3 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -194,7 +194,7 @@ pub fn create_codec(codec: CodecType, _options: &CodecOptions) -> Result Ok(None), - _ => Err(nyi_err!("The codec type {} is not supported yet", codec)), + CodecType::LZO => Err(nyi_err!("The codec type {} is not supported yet", codec)), } } diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 06ad3ac10e11..b5fd5c78f7e0 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -102,7 +102,8 @@ pub fn get_encoder( )), _ => Box::new(ByteStreamSplitEncoder::new()), }, - e => return Err(nyi_err!("Encoding {} is not supported", e)), + #[expect(deprecated, reason = "BIT_PACKED is the encoding we reject here")] + e @ Encoding::BIT_PACKED => return Err(nyi_err!("Encoding {} is not supported", e)), }; Ok(encoder) } diff --git a/parquet/src/file/metadata/thrift/encryption.rs b/parquet/src/file/metadata/thrift/encryption.rs index f71150dff329..4e40acbf8186 100644 --- a/parquet/src/file/metadata/thrift/encryption.rs +++ b/parquet/src/file/metadata/thrift/encryption.rs @@ -258,7 +258,7 @@ pub(crate) fn parquet_metadata_with_encryption( .map_err(|e| general_err!("Could not parse crypto metadata: {}", e))?; let supply_aad_prefix = match &t_file_crypto_metadata.encryption_algorithm { EncryptionAlgorithm::AES_GCM_V1(algo) => algo.supply_aad_prefix, - _ => Some(false), + EncryptionAlgorithm::AES_GCM_CTR_V1(_) => Some(false), } .unwrap_or(false); if supply_aad_prefix && file_decryption_properties.aad_prefix().is_none() { diff --git a/parquet/src/file/page_index/column_index.rs b/parquet/src/file/page_index/column_index.rs index 665b4bc454b0..b7a77fdc0d78 100644 --- a/parquet/src/file/page_index/column_index.rs +++ b/parquet/src/file/page_index/column_index.rs @@ -752,7 +752,7 @@ impl WriteThrift for ColumnIndexMetaData { ColumnIndexMetaData::DOUBLE(index) => index.write_thrift(writer), ColumnIndexMetaData::BYTE_ARRAY(index) => index.write_thrift(writer), ColumnIndexMetaData::FIXED_LEN_BYTE_ARRAY(index) => index.write_thrift(writer), - _ => Err(general_err!("Cannot serialize NONE index")), + ColumnIndexMetaData::NONE => Err(general_err!("Cannot serialize NONE index")), } } } diff --git a/parquet/src/file/serialized_reader.rs b/parquet/src/file/serialized_reader.rs index 80ec15b6ca68..342d2f8afdb1 100644 --- a/parquet/src/file/serialized_reader.rs +++ b/parquet/src/file/serialized_reader.rs @@ -512,7 +512,7 @@ pub(crate) fn decode_page( statistics: statistics::from_thrift_page_stats(physical_type, header.statistics)?, } } - _ => { + PageType::INDEX_PAGE => { // For unknown page type (e.g., INDEX_PAGE), skip and read next. return Err(general_err!( "Page type {:?} is not supported", @@ -1441,7 +1441,7 @@ mod tests { assert!(statistics.is_none()); true } - _ => false, + Page::DataPageV2 { .. } => false, }; assert!(is_expected_page); page_count += 1; @@ -1536,7 +1536,7 @@ mod tests { assert!(statistics.is_none()); // page stats are no longer read true } - _ => false, + Page::DataPage { .. } => false, }; assert!(is_expected_page); page_count += 1; @@ -1635,7 +1635,7 @@ mod tests { assert!(statistics.is_none()); // page stats are no longer read true } - _ => false, + Page::DataPage { .. } => false, }; assert!(is_expected_page); page_count += 1; diff --git a/parquet/src/parquet_thrift.rs b/parquet/src/parquet_thrift.rs index a3da8574119d..50a1235ce3f3 100644 --- a/parquet/src/parquet_thrift.rs +++ b/parquet/src/parquet_thrift.rs @@ -542,7 +542,7 @@ pub(crate) trait ThriftCompactInputProtocol<'a> { } // see https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md#universal-unique-identifier-encoding FieldType::Uuid => self.skip_bytes(16), - _ => Err(ThriftProtocolError::SkipUnsupportedType(field_type)), + FieldType::Stop => Err(ThriftProtocolError::SkipUnsupportedType(field_type)), } } } diff --git a/parquet/src/record/reader.rs b/parquet/src/record/reader.rs index 7a8384c93613..caad06ab5d0c 100644 --- a/parquet/src/record/reader.rs +++ b/parquet/src/record/reader.rs @@ -123,7 +123,7 @@ impl TreeBuilder { curr_def_level += 1; curr_rep_level += 1; } - _ => {} + Repetition::REQUIRED => {} } path.push(String::from(field.name())); diff --git a/parquet/src/schema/types.rs b/parquet/src/schema/types.rs index a545affbfddb..ff32da1b3b14 100644 --- a/parquet/src/schema/types.rs +++ b/parquet/src/schema/types.rs @@ -111,7 +111,7 @@ impl Type { pub fn get_fields(&self) -> &[TypePtr] { match *self { Type::GroupType { ref fields, .. } => &fields[..], - _ => panic!("Cannot call get_fields() on a non-group type"), + Type::PrimitiveType { .. } => panic!("Cannot call get_fields() on a non-group type"), } } @@ -124,7 +124,9 @@ impl Type { physical_type, .. } => physical_type, - _ => panic!("Cannot call get_physical_type() on a non-primitive type"), + Type::GroupType { .. } => { + panic!("Cannot call get_physical_type() on a non-primitive type") + } } } @@ -133,7 +135,7 @@ impl Type { pub fn get_precision(&self) -> i32 { match *self { Type::PrimitiveType { precision, .. } => precision, - _ => panic!("Cannot call get_precision() on non-primitive type"), + Type::GroupType { .. } => panic!("Cannot call get_precision() on non-primitive type"), } } @@ -142,7 +144,7 @@ impl Type { pub fn get_scale(&self) -> i32 { match *self { Type::PrimitiveType { scale, .. } => scale, - _ => panic!("Cannot call get_scale() on non-primitive type"), + Type::GroupType { .. } => panic!("Cannot call get_scale() on non-primitive type"), } } @@ -197,7 +199,7 @@ impl Type { pub fn is_schema(&self) -> bool { match *self { Type::GroupType { ref basic_info, .. } => !basic_info.has_repetition(), - _ => false, + Type::PrimitiveType { .. } => false, } } @@ -954,7 +956,7 @@ impl ColumnDescriptor { pub fn physical_type(&self) -> PhysicalType { match self.primitive_type.as_ref() { Type::PrimitiveType { physical_type, .. } => *physical_type, - _ => panic!("Expected primitive type!"), + Type::GroupType { .. } => panic!("Expected primitive type!"), } } @@ -963,7 +965,7 @@ impl ColumnDescriptor { pub fn type_length(&self) -> i32 { match self.primitive_type.as_ref() { Type::PrimitiveType { type_length, .. } => *type_length, - _ => panic!("Expected primitive type!"), + Type::GroupType { .. } => panic!("Expected primitive type!"), } } @@ -972,7 +974,7 @@ impl ColumnDescriptor { pub fn type_precision(&self) -> i32 { match self.primitive_type.as_ref() { Type::PrimitiveType { precision, .. } => *precision, - _ => panic!("Expected primitive type!"), + Type::GroupType { .. } => panic!("Expected primitive type!"), } } @@ -981,7 +983,7 @@ impl ColumnDescriptor { pub fn type_scale(&self) -> i32 { match self.primitive_type.as_ref() { Type::PrimitiveType { scale, .. } => *scale, - _ => panic!("Expected primitive type!"), + Type::GroupType { .. } => panic!("Expected primitive type!"), } } @@ -1232,7 +1234,7 @@ fn build_tree<'a>( max_rep_level += 1; repeated_ancestor_def_level = max_def_level; } - _ => {} + Repetition::REQUIRED => {} } match tp.as_ref() { @@ -1461,7 +1463,7 @@ mod tests { Type::PrimitiveType { physical_type, .. } => { assert_eq!(physical_type, PhysicalType::INT32); } - _ => panic!(), + Type::GroupType { .. } => panic!(), } } diff --git a/parquet/src/schema/visitor.rs b/parquet/src/schema/visitor.rs index 7a10d3a5ffd6..2ce8ced668f4 100644 --- a/parquet/src/schema/visitor.rs +++ b/parquet/src/schema/visitor.rs @@ -88,7 +88,7 @@ pub trait TypeVisitor { } } } - _ => Err(General( + Type::GroupType { .. } => Err(General( "Group element type of list can only contain one field.".to_string(), )), } diff --git a/parquet_derive/src/parquet_field.rs b/parquet_derive/src/parquet_field.rs index 07a04a2a2479..b5171c23c51a 100644 --- a/parquet_derive/src/parquet_field.rs +++ b/parquet_derive/src/parquet_field.rs @@ -193,7 +193,7 @@ impl Field { }, _ => unimplemented!("Unsupported definition encountered"), }, - _ => unimplemented!("Unsupported definition encountered"), + Type::Option(_) => unimplemented!("Unsupported definition encountered"), } } }, From af756a414aa893b81bc786f011b129069639f2e6 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 10:59:23 +0200 Subject: [PATCH 15/17] Enable `clippy::ptr_as_ptr` `pointer::cast` cannot silently change constness the way `as` can, and it makes the target type explicit at the call site. This matters here: nearly every site feeds a `from_raw_parts` in unsafe code. --- Cargo.toml | 1 + arrow-array/src/array/byte_view_array.rs | 4 +++- arrow-array/src/ffi.rs | 4 ++-- arrow-array/src/ffi_stream.rs | 6 +++--- arrow-array/src/trusted_len.rs | 2 +- arrow-buffer/src/bigint/div.rs | 4 ++-- arrow-buffer/src/buffer/immutable.rs | 4 ++-- arrow-buffer/src/buffer/mutable.rs | 4 ++-- arrow-buffer/src/buffer/scalar.rs | 2 +- arrow-buffer/src/builder/mod.rs | 4 ++-- arrow-buffer/src/native.rs | 4 ++-- arrow-buffer/src/util/bit_chunk_iterator.rs | 4 ++-- arrow-buffer/src/util/bit_mask.rs | 8 ++++---- arrow-buffer/src/util/bit_util.rs | 2 +- arrow-data/src/ffi.rs | 10 +++++----- arrow-ord/src/sort.rs | 2 +- arrow-schema/src/ffi.rs | 11 ++++++----- arrow/tests/array_validation.rs | 2 +- parquet/src/arrow/buffer/dictionary_buffer.rs | 4 ++-- parquet/src/bloom_filter/mod.rs | 2 +- parquet/src/data_type.rs | 12 ++++++------ 21 files changed, 50 insertions(+), 46 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bea3cc1215ba..10941a5b1f09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -237,6 +237,7 @@ or_fun_call = "warn" path_buf_push_overwrite = "warn" pathbuf_init_then_push = "warn" precedence_bits = "warn" +ptr_as_ptr = "warn" ptr_cast_constness = "warn" ptr_offset_by_literal = "warn" pub_without_shorthand = "warn" diff --git a/arrow-array/src/array/byte_view_array.rs b/arrow-array/src/array/byte_view_array.rs index 8f23f8fd443a..eaf8779fd6c2 100644 --- a/arrow-array/src/array/byte_view_array.rs +++ b/arrow-array/src/array/byte_view_array.rs @@ -358,7 +358,9 @@ impl GenericByteViewArray { debug_assert!(len <= MAX_INLINE_VIEW_LEN as usize); unsafe { std::slice::from_raw_parts( - (std::ptr::from_ref::(view) as *const u8).wrapping_add(4), + std::ptr::from_ref::(view) + .cast::() + .wrapping_add(4), len, ) } diff --git a/arrow-array/src/ffi.rs b/arrow-array/src/ffi.rs index 07ac0782ceab..f5eb9b279d4f 100644 --- a/arrow-array/src/ffi.rs +++ b/arrow-array/src/ffi.rs @@ -481,7 +481,7 @@ impl ImportedArrowArray<'_> { // first buffer is the null buffer => add(1) // we assume that pointer is aligned for `i32`, as Utf8 uses `i32` offsets. #[expect(clippy::cast_ptr_alignment)] - let offset_buffer = self.array.buffer(1) as *const i32; + let offset_buffer = self.array.buffer(1).cast::(); // get last offset (unsafe { *offset_buffer.add(len / size_of::() - 1) }) as usize } @@ -495,7 +495,7 @@ impl ImportedArrowArray<'_> { // first buffer is the null buffer => add(1) // we assume that pointer is aligned for `i64`, as Large uses `i64` offsets. #[expect(clippy::cast_ptr_alignment)] - let offset_buffer = self.array.buffer(1) as *const i64; + let offset_buffer = self.array.buffer(1).cast::(); // get last offset (unsafe { *offset_buffer.add(len / size_of::() - 1) }) as usize } diff --git a/arrow-array/src/ffi_stream.rs b/arrow-array/src/ffi_stream.rs index aeb7ca091897..7df336e06fa1 100644 --- a/arrow-array/src/ffi_stream.rs +++ b/arrow-array/src/ffi_stream.rs @@ -122,7 +122,7 @@ unsafe extern "C" fn release_stream(stream: *mut FFI_ArrowArrayStream) { stream.get_next = None; stream.get_last_error = None; - let private_data = unsafe { Box::from_raw(stream.private_data as *mut StreamPrivateData) }; + let private_data = unsafe { Box::from_raw(stream.private_data.cast::()) }; drop(private_data); stream.release = None; @@ -182,7 +182,7 @@ impl FFI_ArrowArrayStream { get_next: Some(get_next), get_last_error: Some(get_last_error), release: Some(release_stream), - private_data: Box::into_raw(private_data) as *mut c_void, + private_data: Box::into_raw(private_data).cast::(), } } @@ -220,7 +220,7 @@ struct ExportedArrayStream { impl ExportedArrayStream { fn get_private_data(&mut self) -> &mut StreamPrivateData { - unsafe { &mut *((*self.stream).private_data as *mut StreamPrivateData) } + unsafe { &mut *(*self.stream).private_data.cast::() } } pub fn get_schema(&mut self, out: *mut FFI_ArrowSchema) -> i32 { diff --git a/arrow-array/src/trusted_len.rs b/arrow-array/src/trusted_len.rs index 8a3c3edec036..6ce2da880600 100644 --- a/arrow-array/src/trusted_len.rs +++ b/arrow-array/src/trusted_len.rs @@ -37,7 +37,7 @@ where let mut buffer = MutableBuffer::new(len); let dst_null = null.as_mut_ptr(); - let mut dst = buffer.as_mut_ptr() as *mut T; + let mut dst = buffer.as_mut_ptr().cast::(); for (i, item) in iterator.enumerate() { let item = item.borrow(); if let Some(item) = item { diff --git a/arrow-buffer/src/bigint/div.rs b/arrow-buffer/src/bigint/div.rs index fb5bf76c0f7d..fbed732e718d 100644 --- a/arrow-buffer/src/bigint/div.rs +++ b/arrow-buffer/src/bigint/div.rs @@ -290,13 +290,13 @@ impl std::ops::Deref for ArrayPlusOne { #[inline] fn deref(&self) -> &Self::Target { let x = std::ptr::from_ref::(self); - unsafe { std::slice::from_raw_parts(x as *const T, N + 1) } + unsafe { std::slice::from_raw_parts(x.cast::(), N + 1) } } } impl std::ops::DerefMut for ArrayPlusOne { fn deref_mut(&mut self) -> &mut Self::Target { let x = std::ptr::from_mut::(self); - unsafe { std::slice::from_raw_parts_mut(x as *mut T, N + 1) } + unsafe { std::slice::from_raw_parts_mut(x.cast::(), N + 1) } } } diff --git a/arrow-buffer/src/buffer/immutable.rs b/arrow-buffer/src/buffer/immutable.rs index f44d9d75d228..3854db9b60b4 100644 --- a/arrow-buffer/src/buffer/immutable.rs +++ b/arrow-buffer/src/buffer/immutable.rs @@ -453,7 +453,7 @@ impl Buffer { Arc::try_unwrap(self.data) .map(|bytes| unsafe { - let ptr = bytes.ptr().as_ptr() as _; + let ptr = bytes.ptr().as_ptr().cast(); std::mem::forget(bytes); // Safety // Verified that bytes layout matches that of Vec @@ -902,7 +902,7 @@ mod tests { let mut vector = vec![1_i32, 2, 3, 4, 5]; let buffer = unsafe { Buffer::from_custom_allocation( - NonNull::new_unchecked(vector.as_mut_ptr() as *mut u8), + NonNull::new_unchecked(vector.as_mut_ptr().cast::()), vector.len() * std::mem::size_of::(), Arc::new(vector), ) diff --git a/arrow-buffer/src/buffer/mutable.rs b/arrow-buffer/src/buffer/mutable.rs index 629cdff3db6b..1b0d9b286519 100644 --- a/arrow-buffer/src/buffer/mutable.rs +++ b/arrow-buffer/src/buffer/mutable.rs @@ -657,7 +657,7 @@ impl MutableBuffer { // this assumes that `[ToByteSlice]` can be copied directly // without calling `to_byte_slice` for each element, // which is correct for all ArrowNativeType implementations. - let src = items.as_ptr() as *const u8; + let src = items.as_ptr().cast::(); let dst = self.data.as_ptr().add(self.len); std::ptr::copy_nonoverlapping(src, dst, additional); } @@ -1182,7 +1182,7 @@ impl Drop for MutableBuffer { fn drop(&mut self) { if self.layout.size() != 0 { // Safety: data was allocated with standard allocator with given layout - unsafe { std::alloc::dealloc(self.data.as_ptr() as _, self.layout) }; + unsafe { std::alloc::dealloc(self.data.as_ptr().cast(), self.layout) }; } } } diff --git a/arrow-buffer/src/buffer/scalar.rs b/arrow-buffer/src/buffer/scalar.rs index 753f15c6f540..e46785ebb445 100644 --- a/arrow-buffer/src/buffer/scalar.rs +++ b/arrow-buffer/src/buffer/scalar.rs @@ -161,7 +161,7 @@ impl Deref for ScalarBuffer { // SAFETY: Verified alignment in From unsafe { std::slice::from_raw_parts( - self.buffer.as_ptr() as *const T, + self.buffer.as_ptr().cast::(), self.buffer.len() / std::mem::size_of::(), ) } diff --git a/arrow-buffer/src/builder/mod.rs b/arrow-buffer/src/builder/mod.rs index 053813c715cc..289374359a5a 100644 --- a/arrow-buffer/src/builder/mod.rs +++ b/arrow-buffer/src/builder/mod.rs @@ -266,7 +266,7 @@ impl BufferBuilder { // - MutableBuffer is aligned and initialized for len elements of T // - MutableBuffer corresponds to a single allocation // - MutableBuffer does not support modification whilst active immutable borrows - unsafe { std::slice::from_raw_parts(self.buffer.as_ptr() as _, self.len()) } + unsafe { std::slice::from_raw_parts(self.buffer.as_ptr().cast(), self.len()) } } /// View the contents of this buffer as a mutable slice @@ -290,7 +290,7 @@ impl BufferBuilder { // - MutableBuffer is aligned and initialized for len elements of T // - MutableBuffer corresponds to a single allocation // - MutableBuffer does not support modification whilst active immutable borrows - unsafe { std::slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as _, self.len()) } + unsafe { std::slice::from_raw_parts_mut(self.buffer.as_mut_ptr().cast(), self.len()) } } /// Shorten this BufferBuilder to `len` items diff --git a/arrow-buffer/src/native.rs b/arrow-buffer/src/native.rs index 72dc32601212..4236ac8a7311 100644 --- a/arrow-buffer/src/native.rs +++ b/arrow-buffer/src/native.rs @@ -273,7 +273,7 @@ pub trait ToByteSlice { impl ToByteSlice for [T] { #[inline] fn to_byte_slice(&self) -> &[u8] { - let raw_ptr = self.as_ptr() as *const u8; + let raw_ptr = self.as_ptr().cast::(); unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of_val(self)) } } } @@ -281,7 +281,7 @@ impl ToByteSlice for [T] { impl ToByteSlice for T { #[inline] fn to_byte_slice(&self) -> &[u8] { - let raw_ptr = std::ptr::from_ref::(self) as *const u8; + let raw_ptr = std::ptr::from_ref::(self).cast::(); unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of::()) } } } diff --git a/arrow-buffer/src/util/bit_chunk_iterator.rs b/arrow-buffer/src/util/bit_chunk_iterator.rs index 5fda66501a41..2c4e684917ba 100644 --- a/arrow-buffer/src/util/bit_chunk_iterator.rs +++ b/arrow-buffer/src/util/bit_chunk_iterator.rs @@ -368,7 +368,7 @@ impl Iterator for BitChunkIterator<'_> { // cast to *const u64 should be fine since we are using read_unaligned below #[expect(clippy::cast_ptr_alignment)] - let raw_data = self.buffer.as_ptr() as *const u64; + let raw_data = self.buffer.as_ptr().cast::(); // bit-packed buffers are stored starting with the least-significant byte first // so when reading as u64 on a big-endian machine, the bytes need to be swapped @@ -382,7 +382,7 @@ impl Iterator for BitChunkIterator<'_> { // the constructor ensures that bit_offset is in 0..8 // that means we need to read at most one additional byte to fill in the high bits let next = - unsafe { std::ptr::read_unaligned(raw_data.add(index + 1) as *const u8) as u64 }; + unsafe { std::ptr::read_unaligned(raw_data.add(index + 1).cast::()) as u64 }; (current >> bit_offset) | (next << (64 - bit_offset)) }; diff --git a/arrow-buffer/src/util/bit_mask.rs b/arrow-buffer/src/util/bit_mask.rs index 42b42cb2d6e5..444a72bdbbbf 100644 --- a/arrow-buffer/src/util/bit_mask.rs +++ b/arrow-buffer/src/util/bit_mask.rs @@ -85,7 +85,7 @@ unsafe fn set_upto_64bits( let write_shift = offset_write % 8; if len >= 64 { - let chunk = unsafe { (data.as_ptr().add(read_byte) as *const u64).read_unaligned() }; + let chunk = unsafe { data.as_ptr().add(read_byte).cast::().read_unaligned() }; if read_shift == 0 { if write_shift == 0 { // no shifting necessary @@ -143,7 +143,7 @@ unsafe fn read_bytes_to_u64(data: &[u8], offset: usize, count: usize) -> u64 { debug_assert!(count <= 8); let mut tmp: u64 = 0; let src = unsafe { data.as_ptr().add(offset) }; - unsafe { std::ptr::copy_nonoverlapping(src, std::ptr::from_mut(&mut tmp) as *mut u8, count) }; + unsafe { std::ptr::copy_nonoverlapping(src, std::ptr::from_mut(&mut tmp).cast::(), count) }; tmp } @@ -151,7 +151,7 @@ unsafe fn read_bytes_to_u64(data: &[u8], offset: usize, count: usize) -> u64 { /// The caller must ensure `data` has `offset..(offset + 8)` range #[inline] unsafe fn write_u64_bytes(data: &mut [u8], offset: usize, chunk: u64) { - let ptr = unsafe { data.as_mut_ptr().add(offset) } as *mut u64; + let ptr = unsafe { data.as_mut_ptr().add(offset) }.cast::(); unsafe { ptr.write_unaligned(chunk) }; } @@ -164,7 +164,7 @@ unsafe fn write_u64_bytes(data: &mut [u8], offset: usize, chunk: u64) { unsafe fn or_write_u64_bytes(data: &mut [u8], offset: usize, chunk: u64) { let ptr = unsafe { data.as_mut_ptr().add(offset) }; let chunk = chunk | (unsafe { *ptr }) as u64; - unsafe { (ptr as *mut u64).write_unaligned(chunk) }; + unsafe { ptr.cast::().write_unaligned(chunk) }; } #[cfg(test)] diff --git a/arrow-buffer/src/util/bit_util.rs b/arrow-buffer/src/util/bit_util.rs index ecfa00d1a297..0f0a89078252 100644 --- a/arrow-buffer/src/util/bit_util.rs +++ b/arrow-buffer/src/util/bit_util.rs @@ -554,7 +554,7 @@ impl<'a> U64UnalignedSlice<'a> { assert!(u64_len_in_bytes <= left_buffer_mut.len()); let (bytes_for_u64, remainder) = left_buffer_mut.split_at_mut(u64_len_in_bytes); - let ptr = bytes_for_u64.as_mut_ptr() as *mut u64; + let ptr = bytes_for_u64.as_mut_ptr().cast::(); let this = Self { ptr, diff --git a/arrow-data/src/ffi.rs b/arrow-data/src/ffi.rs index e82db398ba97..fd1a99e9dbea 100644 --- a/arrow-data/src/ffi.rs +++ b/arrow-data/src/ffi.rs @@ -84,7 +84,7 @@ unsafe extern "C" fn release_array(array: *mut FFI_ArrowArray) { let array = unsafe { &mut *array }; // take ownership of `private_data`, therefore dropping it` - let private = unsafe { Box::from_raw(array.private_data as *mut ArrayPrivateData) }; + let private = unsafe { Box::from_raw(array.private_data.cast::()) }; for child in private.children.iter() { let _ = unsafe { Box::from_raw(*child) }; } @@ -167,7 +167,7 @@ impl FFI_ArrowArray { let buffers_ptr = buffers .iter() .filter_map(|maybe_buffer| match maybe_buffer { - Some(b) => Some(b.as_ptr() as *const c_void), + Some(b) => Some(b.as_ptr().cast::()), // This is for null buffer. We only put a null pointer for // null buffer if by spec it can contain null mask. None if data_layout.can_contain_null_mask => Some(std::ptr::null()), @@ -215,7 +215,7 @@ impl FFI_ArrowArray { children: private_data.children.as_mut_ptr(), dictionary, release: Some(release_array), - private_data: Box::into_raw(private_data) as *mut c_void, + private_data: Box::into_raw(private_data).cast::(), } } @@ -306,7 +306,7 @@ impl FFI_ArrowArray { assert!(index < self.num_buffers()); // SAFETY: // If buffers is not null must be valid for reads up to num_buffers - unsafe { std::ptr::read_unaligned((self.buffers as *mut *const u8).add(index)) } + unsafe { std::ptr::read_unaligned(self.buffers.cast::<*const u8>().add(index)) } } /// Returns the number of buffers @@ -357,7 +357,7 @@ mod tests { assert_eq!(0, ffi_array.n_buffers); let private_data = - unsafe { Box::from_raw(ffi_array.private_data as *mut ArrayPrivateData) }; + unsafe { Box::from_raw(ffi_array.private_data.cast::()) }; assert_eq!(0, private_data.buffers_ptr.len()); diff --git a/arrow-ord/src/sort.rs b/arrow-ord/src/sort.rs index 720da4d56637..1bdb3e986b05 100644 --- a/arrow-ord/src/sort.rs +++ b/arrow-ord/src/sort.rs @@ -373,7 +373,7 @@ fn sort_bytes( let len = slice.len() as u64; // Compute the 4‑byte prefix in BE order, or left‑pad if shorter let prefix = if slice.len() >= 4 { - let raw = std::ptr::read_unaligned(slice.as_ptr() as *const u32); + let raw = std::ptr::read_unaligned(slice.as_ptr().cast::()); u32::from_be(raw) } else if slice.is_empty() { // Handle empty slice case to avoid shift overflow diff --git a/arrow-schema/src/ffi.rs b/arrow-schema/src/ffi.rs index 3788e8033851..657e58f1c61e 100644 --- a/arrow-schema/src/ffi.rs +++ b/arrow-schema/src/ffi.rs @@ -114,7 +114,8 @@ unsafe extern "C" fn release_schema(schema: *mut FFI_ArrowSchema) { drop(unsafe { CString::from_raw(schema.name.cast_mut()) }); } if !schema.private_data.is_null() { - let private_data = unsafe { Box::from_raw(schema.private_data as *mut SchemaPrivateData) }; + let private_data = + unsafe { Box::from_raw(schema.private_data.cast::()) }; for child in private_data.children.iter() { drop(unsafe { Box::from_raw(*child) }) } @@ -163,7 +164,7 @@ impl FFI_ArrowSchema { this.dictionary = dictionary_ptr; - this.private_data = Box::into_raw(private_data) as *mut c_void; + this.private_data = Box::into_raw(private_data).cast::(); Ok(this) } @@ -228,7 +229,7 @@ impl FFI_ArrowSchema { metadata_serialized.extend_from_slice(value.as_ref().as_bytes()); } - self.metadata = metadata_serialized.as_ptr() as *const c_char; + self.metadata = metadata_serialized.as_ptr().cast::(); Some(metadata_serialized) } else { self.metadata = std::ptr::null_mut(); @@ -236,9 +237,9 @@ impl FFI_ArrowSchema { }; unsafe { - let mut private_data = Box::from_raw(self.private_data as *mut SchemaPrivateData); + let mut private_data = Box::from_raw(self.private_data.cast::()); private_data.metadata = new_metadata; - self.private_data = Box::into_raw(private_data) as *mut c_void; + self.private_data = Box::into_raw(private_data).cast::(); } Ok(self) diff --git a/arrow/tests/array_validation.rs b/arrow/tests/array_validation.rs index d34032b7cbaa..b92ccae3c98b 100644 --- a/arrow/tests/array_validation.rs +++ b/arrow/tests/array_validation.rs @@ -1027,7 +1027,7 @@ fn test_string_data_from_foreign() { }; let offsets_buffer = unsafe { Buffer::from_custom_allocation( - NonNull::new_unchecked(offsets.as_mut_ptr() as *mut u8), + NonNull::new_unchecked(offsets.as_mut_ptr().cast::()), offsets.len() * std::mem::size_of::(), Arc::new(offsets), ) diff --git a/parquet/src/arrow/buffer/dictionary_buffer.rs b/parquet/src/arrow/buffer/dictionary_buffer.rs index 8aa367f8d821..e281403299a0 100644 --- a/parquet/src/arrow/buffer/dictionary_buffer.rs +++ b/parquet/src/arrow/buffer/dictionary_buffer.rs @@ -62,8 +62,8 @@ impl DictionaryBuffer { // Need to discard fat pointer for equality check // - https://stackoverflow.com/a/67114787 // - https://github.com/rust-lang/rust/issues/46139 - let values_ptr = std::ptr::from_ref(values.as_ref()) as *const (); - let dict_ptr = std::ptr::from_ref(dictionary.as_ref()) as *const (); + let values_ptr = std::ptr::from_ref(values.as_ref()).cast::<()>(); + let dict_ptr = std::ptr::from_ref(dictionary.as_ref()).cast::<()>(); if values_ptr == dict_ptr { Some(keys) } else if keys.is_empty() { diff --git a/parquet/src/bloom_filter/mod.rs b/parquet/src/bloom_filter/mod.rs index 8e89ba406b59..2d1214d7f56c 100644 --- a/parquet/src/bloom_filter/mod.rs +++ b/parquet/src/bloom_filter/mod.rs @@ -446,7 +446,7 @@ impl Sbbf { // Safety: Block is repr(transparent) and [u32; 8] can be reinterpreted as [u8; 32]. let slice = unsafe { std::slice::from_raw_parts( - self.0.as_ptr() as *const u8, + self.0.as_ptr().cast::(), self.0.len() * size_of::(), ) }; diff --git a/parquet/src/data_type.rs b/parquet/src/data_type.rs index 3af311cfbd62..14adbdc70819 100644 --- a/parquet/src/data_type.rs +++ b/parquet/src/data_type.rs @@ -554,7 +554,7 @@ macro_rules! gen_as_bytes { // resulting slice always refers to initialized memory. unsafe { std::slice::from_raw_parts( - std::ptr::from_ref::<$source_ty>(self) as *const u8, + std::ptr::from_ref::<$source_ty>(self).cast::(), std::mem::size_of::<$source_ty>(), ) } @@ -569,7 +569,7 @@ macro_rules! gen_as_bytes { // resulting slice always refers to initialized memory. unsafe { std::slice::from_raw_parts( - self_.as_ptr() as *const u8, + self_.as_ptr().cast::(), std::mem::size_of_val(self_), ) } @@ -583,7 +583,7 @@ macro_rules! gen_as_bytes { // invalid bit patterns, so all writes to the resulting slice will be valid. unsafe { std::slice::from_raw_parts_mut( - self_.as_mut_ptr() as *mut u8, + self_.as_mut_ptr().cast::(), std::mem::size_of_val(self_), ) } @@ -627,7 +627,7 @@ impl AsBytes for bool { fn as_bytes(&self) -> &[u8] { // SAFETY: a bool is guaranteed to be either 0x00 or 0x01 in memory, so the memory is // valid. - unsafe { std::slice::from_raw_parts(std::ptr::from_ref::(self) as *const u8, 1) } + unsafe { std::slice::from_raw_parts(std::ptr::from_ref::(self).cast::(), 1) } } } @@ -635,7 +635,7 @@ impl AsBytes for Int96 { fn as_bytes(&self) -> &[u8] { // SAFETY: Int96::data is a &[u32; 3]. unsafe { - std::slice::from_raw_parts(std::ptr::from_ref::<[u32]>(self.data()) as *const u8, 12) + std::slice::from_raw_parts(std::ptr::from_ref::<[u32]>(self.data()).cast::(), 12) } } } @@ -831,7 +831,7 @@ pub(crate) mod private { // SAFETY: Self is one of i32, i64, f32, f64, which have no padding. let raw = unsafe { std::slice::from_raw_parts( - values.as_ptr() as *const u8, + values.as_ptr().cast::(), std::mem::size_of_val(values), ) }; From 8469269e1d729ae2d044efcf4502bb65dd3da3bf Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 13 Aug 2026 11:03:54 +0200 Subject: [PATCH 16/17] Enable `clippy::explicit_iter_loop` `for x in &collection` is the shorter spelling of `for x in collection.iter()`, and it makes the borrow visible at a glance. --- Cargo.toml | 1 + .../src/builder/generic_bytes_view_builder.rs | 2 +- arrow-avro/src/reader/record.rs | 4 ++-- arrow-avro/src/writer/encoder.rs | 8 ++++---- arrow-buffer/benches/i256.rs | 4 ++-- arrow-buffer/src/buffer/offset.rs | 2 +- arrow-cast/src/base64.rs | 4 ++-- arrow-cast/src/cast/dictionary.rs | 6 +++--- arrow-cast/src/cast/mod.rs | 10 +++++----- arrow-csv/src/reader/mod.rs | 2 +- arrow-data/src/data.rs | 4 ++-- arrow-data/src/ffi.rs | 2 +- arrow-data/src/transform/fixed_size_list.rs | 4 ++-- arrow-data/src/transform/union.rs | 4 ++-- arrow-flight/src/utils.rs | 4 ++-- arrow-json/src/writer/encoder.rs | 2 +- arrow-json/src/writer/mod.rs | 2 +- arrow-row/src/lib.rs | 4 ++-- arrow-schema/src/ffi.rs | 2 +- arrow-schema/src/fields.rs | 2 +- arrow-select/src/coalesce.rs | 10 +++++----- arrow-select/src/concat.rs | 20 +++++++++---------- arrow-select/src/interleave.rs | 2 +- arrow/benches/row_format.rs | 2 +- .../src/variant_to_arrow.rs | 2 +- parquet-variant-json/src/from_json.rs | 2 +- parquet-variant/src/builder/metadata.rs | 2 +- parquet/src/arrow/array_reader/byte_array.rs | 2 +- .../src/arrow/array_reader/byte_view_array.rs | 4 ++-- .../src/arrow/array_reader/struct_array.rs | 4 ++-- parquet/src/arrow/arrow_reader/mod.rs | 2 +- .../arrow/push_decoder/reader_builder/mod.rs | 2 +- parquet/src/bloom_filter/mod.rs | 2 +- parquet/src/column/writer/mod.rs | 2 +- parquet/src/encryption/decrypt.rs | 2 +- parquet/src/encryption/encrypt.rs | 2 +- parquet/src/file/metadata/mod.rs | 2 +- parquet/src/schema/printer.rs | 2 +- parquet/src/schema/types.rs | 4 ++-- parquet/tests/arrow_writer/mod.rs | 2 +- parquet/tests/encryption/encryption.rs | 2 +- parquet/tests/encryption/encryption_util.rs | 2 +- 42 files changed, 75 insertions(+), 74 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 10941a5b1f09..5b2a9874f99a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -180,6 +180,7 @@ exit = "warn" expl_impl_clone_on_copy = "warn" explicit_deref_methods = "warn" explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" filter_map_next = "warn" flat_map_option = "warn" float_cmp_const = "warn" diff --git a/arrow-array/src/builder/generic_bytes_view_builder.rs b/arrow-array/src/builder/generic_bytes_view_builder.rs index 4886d56e7ffa..170366a92075 100644 --- a/arrow-array/src/builder/generic_bytes_view_builder.rs +++ b/arrow-array/src/builder/generic_bytes_view_builder.rs @@ -983,7 +983,7 @@ mod tests { // All views should be identical let first_view = array.views()[0]; - for view in array.views().iter() { + for view in array.views() { assert_eq!(*view, first_view); } } diff --git a/arrow-avro/src/reader/record.rs b/arrow-avro/src/reader/record.rs index 1d5019e95fed..9689e3df205f 100644 --- a/arrow-avro/src/reader/record.rs +++ b/arrow-avro/src/reader/record.rs @@ -2513,7 +2513,7 @@ impl Projector { buf: &mut AvroCursor<'_>, encodings: &mut [Decoder], ) -> Result<(), AvroError> { - for field_proj in self.writer_projections.iter() { + for field_proj in &self.writer_projections { match field_proj { FieldProjection::ToReader(index) => encodings[*index].decode(buf)?, FieldProjection::Skip(skipper) => skipper.skip(buf)?, @@ -2716,7 +2716,7 @@ impl Skipper { Ok(()) } Self::Struct(fields) => { - for f in fields.iter() { + for f in fields { f.skip(buf)? } Ok(()) diff --git a/arrow-avro/src/writer/encoder.rs b/arrow-avro/src/writer/encoder.rs index 29dfa8e5aea0..6da54467b70b 100644 --- a/arrow-avro/src/writer/encoder.rs +++ b/arrow-avro/src/writer/encoder.rs @@ -891,7 +891,7 @@ impl RecordEncoder { ) -> Result>, AvroError> { let arrays = batch.columns(); let mut out = Vec::with_capacity(self.columns.len()); - for col_plan in self.columns.iter() { + for col_plan in &self.columns { let arrow_index = col_plan.arrow_index; let array = arrays.get(arrow_index).ok_or_else(|| { AvroError::SchemaError(format!("Column index {arrow_index} out of range")) @@ -924,7 +924,7 @@ impl RecordEncoder { let n = batch.num_rows(); let prefix = self.prefix.as_ref().map(|p| p.as_slice()); for_rows_with_prefix!(n, prefix, out, |row| { - for enc in column_encoders.iter_mut() { + for enc in &mut column_encoders { enc.encode(out, row)?; } }); @@ -983,7 +983,7 @@ impl RecordEncoder { }); } else { for_rows_with_prefix!(n, prefix_bytes, w, |row| { - for enc in column_encoders.iter_mut() { + for enc in &mut column_encoders { enc.encode(&mut w, row)?; } offsets.push(w.get_ref().len()); @@ -1972,7 +1972,7 @@ impl<'a> StructEncoder<'a> { } fn encode(&mut self, out: &mut W, idx: usize) -> Result<(), AvroError> { - for encoder in self.encoders.iter_mut() { + for encoder in &mut self.encoders { encoder.encode(out, idx)?; } Ok(()) diff --git a/arrow-buffer/benches/i256.rs b/arrow-buffer/benches/i256.rs index 2e1d63d2e358..435f43c71e9a 100644 --- a/arrow-buffer/benches/i256.rs +++ b/arrow-buffer/benches/i256.rs @@ -37,14 +37,14 @@ fn criterion_benchmark(c: &mut Criterion) { i256::MAX, ]; - for number in numbers.iter() { + for number in &numbers { let t = hint::black_box(number.to_string()); c.bench_function(&format!("i256_parse({t})"), |b| { b.iter(|| i256::from_str(&t).unwrap()); }); } - for number in numbers.iter() { + for number in &numbers { c.bench_function(&format!("i256_to_f64({number})"), |b| { b.iter(|| (*number).to_f64().unwrap()) }); diff --git a/arrow-buffer/src/buffer/offset.rs b/arrow-buffer/src/buffer/offset.rs index 86ce100c23a9..c65730f0044b 100644 --- a/arrow-buffer/src/buffer/offset.rs +++ b/arrow-buffer/src/buffer/offset.rs @@ -371,7 +371,7 @@ impl OffsetBuffer { let shifted_offsets: Vec = match self.into_inner().into_inner().into_vec() { // If we can reuse the buffer, update in place Ok(mut v) => { - for offset in v.iter_mut() { + for offset in &mut v { *offset = *offset - rhs; } v diff --git a/arrow-cast/src/base64.rs b/arrow-cast/src/base64.rs index 1c1b53eb201e..be092e12cfb9 100644 --- a/arrow-cast/src/base64.rs +++ b/arrow-cast/src/base64.rs @@ -70,7 +70,7 @@ pub fn b64_decode( offsets.push(O::usize_as(0)); let mut offset = 0; - for v in array.iter() { + for v in array { if let Some(v) = v { let len = engine.decode_slice(v, &mut buffer[offset..]).unwrap(); // This cannot overflow as `len` is less than `v.len()` and `a` is valid @@ -150,7 +150,7 @@ mod tests { output_buf: &mut [u8], ) -> Result { let len = BASE64_STANDARD.encode_slice(input, output_buf)?; - for b in output_buf[..len].iter_mut() { + for b in &mut output_buf[..len] { *b = 0xFF; // invalid UTF-8, but correct length } Ok(len) diff --git a/arrow-cast/src/cast/dictionary.rs b/arrow-cast/src/cast/dictionary.rs index 0a9751dfa85b..367084cbdc7e 100644 --- a/arrow-cast/src/cast/dictionary.rs +++ b/arrow-cast/src/cast/dictionary.rs @@ -136,7 +136,7 @@ fn view_from_dict_values::with_capacity(keys.len()); builder.append_block(value_buffer.clone()); - for i in keys.iter() { + for i in keys { match i { Some(v) => { let idx = v.to_usize().ok_or_else(|| { @@ -456,7 +456,7 @@ where .ok_or_else(|| { ArrowError::ComputeError("Internal Error: Cannot cast to StringViewArray".to_string()) })?; - for v in string_view.iter() { + for v in string_view { match v { Some(v) => { b.append(v)?; @@ -487,7 +487,7 @@ where .ok_or_else(|| { ArrowError::ComputeError("Internal Error: Cannot cast to BinaryViewArray".to_string()) })?; - for v in binary_view.iter() { + for v in binary_view { match v { Some(v) => { b.append(v)?; diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index 3cab0def6b12..e698293dd4c8 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -2856,7 +2856,7 @@ where let mut byte_array_builder = GenericByteBuilder::::with_capacity(len, bytes); - for val in view_array.iter() { + for val in &view_array { byte_array_builder.append_option(val); } @@ -7737,7 +7737,7 @@ mod tests { { let string_view_array = { let mut builder = StringViewBuilder::new().with_fixed_block_size(8); // multiple buffers. - for s in VIEW_TEST_DATA.iter() { + for s in &VIEW_TEST_DATA { builder.append_option(*s); } builder.finish() @@ -7772,7 +7772,7 @@ mod tests { { let view_array = { let mut builder = BinaryViewBuilder::new().with_fixed_block_size(8); // multiple buffers. - for s in VIEW_TEST_DATA.iter() { + for s in &VIEW_TEST_DATA { builder.append_option(*s); } builder.finish() @@ -9850,7 +9850,7 @@ mod tests { 3, )) as ArrayRef; - for (values, lengths) in cases.iter() { + for (values, lengths) in &cases { let array = Arc::new(ListArray::new( field.clone(), OffsetBuffer::from_lengths(lengths.clone()), @@ -9925,7 +9925,7 @@ mod tests { 3, )) as ArrayRef; - for (values, offsets, lengths) in cases.iter() { + for (values, offsets, lengths) in &cases { let array = Arc::new(ListViewArray::new( field.clone(), offsets.clone().into(), diff --git a/arrow-csv/src/reader/mod.rs b/arrow-csv/src/reader/mod.rs index 64b1ef494206..7cb8dd591342 100644 --- a/arrow-csv/src/reader/mod.rs +++ b/arrow-csv/src/reader/mod.rs @@ -472,7 +472,7 @@ pub fn infer_schema_from_files( ..Default::default() }; - for fname in files.iter() { + for fname in files { let f = File::open(fname)?; let (schema, records_read) = format.infer_schema(f, Some(records_to_read))?; if records_read == 0 { diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs index 5f0586005f11..fa995f709562 100644 --- a/arrow-data/src/data.rs +++ b/arrow-data/src/data.rs @@ -529,7 +529,7 @@ impl ArrayData { let mut result: usize = 0; let layout = layout(&self.data_type); - for spec in layout.buffers.iter() { + for spec in &layout.buffers { match spec { BufferSpec::FixedWidth { byte_width, .. } => { // Offset buffers contain len+1 elements: one boundary per element @@ -863,7 +863,7 @@ impl ArrayData { } } // align children data recursively - for data in self.child_data.iter_mut() { + for data in &mut self.child_data { data.align_buffers() } } diff --git a/arrow-data/src/ffi.rs b/arrow-data/src/ffi.rs index fd1a99e9dbea..9aed46d8d191 100644 --- a/arrow-data/src/ffi.rs +++ b/arrow-data/src/ffi.rs @@ -85,7 +85,7 @@ unsafe extern "C" fn release_array(array: *mut FFI_ArrowArray) { // take ownership of `private_data`, therefore dropping it` let private = unsafe { Box::from_raw(array.private_data.cast::()) }; - for child in private.children.iter() { + for child in &private.children { let _ = unsafe { Box::from_raw(*child) }; } if !private.dictionary.is_null() { diff --git a/arrow-data/src/transform/fixed_size_list.rs b/arrow-data/src/transform/fixed_size_list.rs index 139ee45e51d0..de791884b9e9 100644 --- a/arrow-data/src/transform/fixed_size_list.rs +++ b/arrow-data/src/transform/fixed_size_list.rs @@ -28,7 +28,7 @@ pub(super) fn build_extend(array: &ArrayData) -> Extend<'_> { Box::new( move |mutable: &mut _MutableArrayData, index: usize, start: usize, len: usize| { - for child in mutable.child_data.iter_mut() { + for child in &mut mutable.child_data { child.try_extend(index, start * size, (start + len) * size)?; } Ok(()) @@ -42,7 +42,7 @@ pub(super) fn extend_nulls(mutable: &mut _MutableArrayData, len: usize) -> Resul _ => unreachable!(), }; - for child in mutable.child_data.iter_mut() { + for child in &mut mutable.child_data { child.try_extend_nulls(len * size)?; } Ok(()) diff --git a/arrow-data/src/transform/union.rs b/arrow-data/src/transform/union.rs index ba7015f7a984..dee5ea8e8ee4 100644 --- a/arrow-data/src/transform/union.rs +++ b/arrow-data/src/transform/union.rs @@ -29,7 +29,7 @@ pub(super) fn build_extend_sparse(array: &ArrayData) -> Extend<'_> { .buffer1 .extend_from_slice(&type_ids[start..start + len]); - for child in mutable.child_data.iter_mut() { + for child in &mut mutable.child_data { child.try_extend(index, start, start + len)?; } Ok(()) @@ -111,7 +111,7 @@ pub(super) fn extend_nulls_sparse( mutable.buffer1.extend_from_slice(&vec![first_type_id; len]); // Sparse: extend nulls in ALL children - for child in mutable.child_data.iter_mut() { + for child in &mut mutable.child_data { child.try_extend_nulls(len)?; } Ok(()) diff --git a/arrow-flight/src/utils.rs b/arrow-flight/src/utils.rs index 07a1801914fe..2f4fc00f6465 100644 --- a/arrow-flight/src/utils.rs +++ b/arrow-flight/src/utils.rs @@ -44,7 +44,7 @@ pub fn flight_data_to_batches(flight_data: &[FlightData]) -> Result { // Nulls can only be dropped in explicit mode let drop_nulls = (self.struct_mode == StructMode::ObjectOnly) && !self.explicit_nulls; - for field_encoder in self.encoders.iter_mut() { + for field_encoder in &mut self.encoders { let is_null = field_encoder.is_null(idx); if is_null && drop_nulls { continue; diff --git a/arrow-json/src/writer/mod.rs b/arrow-json/src/writer/mod.rs index 3596d418839f..35202bf96221 100644 --- a/arrow-json/src/writer/mod.rs +++ b/arrow-json/src/writer/mod.rs @@ -2317,7 +2317,7 @@ mod tests { }; // check that the fields are supported let fields = fields.iter().map(|(_, f)| f).collect::>(); - for f in fields.iter() { + for f in &fields { match f.data_type() { DataType::Null => {} DataType::Int32 => {} diff --git a/arrow-row/src/lib.rs b/arrow-row/src/lib.rs index 91e4f029afc1..e1c53c2a018f 100644 --- a/arrow-row/src/lib.rs +++ b/arrow-row/src/lib.rs @@ -2383,7 +2383,7 @@ unsafe fn decode_column( unsafe { converter.convert_raw(&mut sparse_data, validate_utf8) }?; // advance row slices by the bytes consumed for rows that belong to this field - for (row_idx, child_row) in field_rows.iter() { + for (row_idx, child_row) in field_rows { let remaining_len = sparse_data[*row_idx].len(); let consumed_length = 1 + child_row.len() - remaining_len; rows[*row_idx] = &rows[*row_idx][consumed_length..]; @@ -5391,7 +5391,7 @@ mod tests { let second = Int32Array::from(vec![Some(2), None, Some(4)]); let arrays = [Arc::new(first) as ArrayRef, Arc::new(second) as ArrayRef]; - for array in arrays.iter() { + for array in &arrays { rows.clear(); converter .append(&mut rows, std::slice::from_ref(array)) diff --git a/arrow-schema/src/ffi.rs b/arrow-schema/src/ffi.rs index 657e58f1c61e..3e69b05f5dca 100644 --- a/arrow-schema/src/ffi.rs +++ b/arrow-schema/src/ffi.rs @@ -116,7 +116,7 @@ unsafe extern "C" fn release_schema(schema: *mut FFI_ArrowSchema) { if !schema.private_data.is_null() { let private_data = unsafe { Box::from_raw(schema.private_data.cast::()) }; - for child in private_data.children.iter() { + for child in &private_data.children { drop(unsafe { Box::from_raw(*child) }) } if !private_data.dictionary.is_null() { diff --git a/arrow-schema/src/fields.rs b/arrow-schema/src/fields.rs index 7f6bc2117263..2e6242f95051 100644 --- a/arrow-schema/src/fields.rs +++ b/arrow-schema/src/fields.rs @@ -593,7 +593,7 @@ impl UnionFields { let mut output: Vec<_> = self.iter().map(|(id, f)| (id, f.clone())).collect(); for (field_type_id, from_field) in other.iter() { let mut is_new_field = true; - for (self_type_id, self_field) in output.iter_mut() { + for (self_type_id, self_field) in &mut output { if from_field == self_field { // If the nested fields in two unions are the same, they must have same // type id. diff --git a/arrow-select/src/coalesce.rs b/arrow-select/src/coalesce.rs index 5a567a92348a..49d198c98f7e 100644 --- a/arrow-select/src/coalesce.rs +++ b/arrow-select/src/coalesce.rs @@ -500,7 +500,7 @@ impl BatchCoalescer { debug_assert!(remaining_rows > 0); // Copy remaining_rows from each array - for in_progress in self.in_progress_arrays.iter_mut() { + for in_progress in &mut self.in_progress_arrays { in_progress.copy_rows(offset, remaining_rows)?; } @@ -514,7 +514,7 @@ impl BatchCoalescer { // Add any the remaining rows to the buffer self.buffered_rows += num_rows; if num_rows > 0 { - for in_progress in self.in_progress_arrays.iter_mut() { + for in_progress in &mut self.in_progress_arrays { in_progress.copy_rows(offset, num_rows)?; } } @@ -525,7 +525,7 @@ impl BatchCoalescer { } // clear in progress sources (to allow the memory to be freed) - for in_progress in self.in_progress_arrays.iter_mut() { + for in_progress in &mut self.in_progress_arrays { in_progress.set_source(None); } @@ -2180,12 +2180,12 @@ mod tests { // Only need to normalize StringViews (as == also tests for memory layout) let (schema, mut columns, row_count) = batch.into_parts(); - for column in columns.iter_mut() { + for column in &mut columns { if let Some(string_view) = column.as_string_view_opt() { // Re-create the StringViewArray to ensure memory layout is // consistent let mut builder = StringViewBuilder::new(); - for s in string_view.iter() { + for s in string_view { builder.append_option(s); } *column = Arc::new(builder.finish()); diff --git a/arrow-select/src/concat.rs b/arrow-select/src/concat.rs index 46f309556564..921d28645242 100644 --- a/arrow-select/src/concat.rs +++ b/arrow-select/src/concat.rs @@ -91,7 +91,7 @@ fn fixed_size_list_capacity(arrays: &[&dyn Array], data_type: &DataType) -> Capa fn concat_byte_view(arrays: &[&dyn Array]) -> Result { let mut builder = GenericByteViewBuilder::::with_capacity(arrays.iter().map(|a| a.len()).sum()); - for &array in arrays.iter() { + for &array in arrays { builder.append_array(array.as_byte_view()); } Ok(Arc::new(builder.finish())) @@ -309,7 +309,7 @@ fn concat_list_view( let mut offsets = MutableBuffer::with_capacity(lists.iter().map(|l| l.offsets().len()).sum()); let mut global_offset = OffsetSize::zero(); - for l in lists.iter() { + for l in &lists { for &offset in l.offsets() { offsets.push(offset + global_offset); } @@ -1084,7 +1084,7 @@ mod tests { Some(vec![Some(10), Some(20)]), ]; let mut list1_array = ListViewBuilder::new(Int64Builder::new()); - for v in list1.iter() { + for v in &list1 { list1_array.append_option(v.clone()); } let list1_array = list1_array.finish(); @@ -1095,14 +1095,14 @@ mod tests { Some(vec![Some(102), Some(103)]), ]; let mut list2_array = ListViewBuilder::new(Int64Builder::new()); - for v in list2.iter() { + for v in &list2 { list2_array.append_option(v.clone()); } let list2_array = list2_array.finish(); let list3 = [Some(vec![Some(1000), Some(1001)])]; let mut list3_array = ListViewBuilder::new(Int64Builder::new()); - for v in list3.iter() { + for v in &list3 { list3_array.append_option(v.clone()); } let list3_array = list3_array.finish(); @@ -1111,7 +1111,7 @@ mod tests { let expected: Vec<_> = list1.into_iter().chain(list2).chain(list3).collect(); let mut array_expected = ListViewBuilder::new(Int64Builder::new()); - for v in expected.iter() { + for v in &expected { array_expected.append_option(v.clone()); } let array_expected = array_expected.finish(); @@ -1127,7 +1127,7 @@ mod tests { Some(vec![Some(10), Some(20)]), ]; let mut list1_array = ListViewBuilder::new(Int64Builder::new()); - for v in list1.iter() { + for v in &list1 { list1_array.append_option(v.clone()); } let list1_array = list1_array.finish(); @@ -1138,14 +1138,14 @@ mod tests { Some(vec![Some(102), Some(103)]), ]; let mut list2_array = ListViewBuilder::new(Int64Builder::new()); - for v in list2.iter() { + for v in &list2 { list2_array.append_option(v.clone()); } let list2_array = list2_array.finish(); let list3 = [Some(vec![Some(1000), Some(1001)])]; let mut list3_array = ListViewBuilder::new(Int64Builder::new()); - for v in list3.iter() { + for v in &list3 { list3_array.append_option(v.clone()); } let list3_array = list3_array.finish(); @@ -1167,7 +1167,7 @@ mod tests { Some(vec![Some(1000), Some(1001)]), ]; let mut array_expected = ListViewBuilder::new(Int64Builder::new()); - for v in expected.iter() { + for v in &expected { array_expected.append_option(v.clone()); } let array_expected = array_expected.finish(); diff --git a/arrow-select/src/interleave.rs b/arrow-select/src/interleave.rs index 471b744e966c..f56864ac6525 100644 --- a/arrow-select/src/interleave.rs +++ b/arrow-select/src/interleave.rs @@ -310,7 +310,7 @@ fn interleave_views( let mut offsets = Vec::with_capacity(interleaved.arrays.len() + 1); offsets.push(0); let mut total_buffers = 0; - for a in interleaved.arrays.iter() { + for a in &interleaved.arrays { total_buffers += a.data_buffers().len(); offsets.push(total_buffers); } diff --git a/arrow/benches/row_format.rs b/arrow/benches/row_format.rs index caa06dc07e87..09d3800fae0b 100644 --- a/arrow/benches/row_format.rs +++ b/arrow/benches/row_format.rs @@ -103,7 +103,7 @@ fn bench_iter(c: &mut Criterion) { c.bench_function("iterate rows", |b| { b.iter(|| { - for r in rows.iter() { + for r in &rows { hint::black_box(r.as_ref()); } }) diff --git a/parquet-variant-compute/src/variant_to_arrow.rs b/parquet-variant-compute/src/variant_to_arrow.rs index a6f32288eba3..848ddaa1ba1b 100644 --- a/parquet-variant-compute/src/variant_to_arrow.rs +++ b/parquet-variant-compute/src/variant_to_arrow.rs @@ -637,7 +637,7 @@ impl<'a> StructVariantToArrowRowBuilder<'a> { capacity: usize, ) -> Result { let mut field_builders = Vec::with_capacity(fields.len()); - for field in fields.iter() { + for field in fields { field_builders.push(make_typed_variant_to_arrow_row_builder( field.data_type(), cast_options, diff --git a/parquet-variant-json/src/from_json.rs b/parquet-variant-json/src/from_json.rs index 4c22785ef106..57068f41cf47 100644 --- a/parquet-variant-json/src/from_json.rs +++ b/parquet-variant-json/src/from_json.rs @@ -119,7 +119,7 @@ pub fn append_json(json: &Value, builder: &mut impl VariantBuilderExt) -> Result } Value::Object(obj) => { let mut obj_builder = builder.try_new_object()?; - for (key, value) in obj.iter() { + for (key, value) in obj { let mut field_builder = ObjectFieldBuilder::new(key, &mut obj_builder); append_json(value, &mut field_builder)?; } diff --git a/parquet-variant/src/builder/metadata.rs b/parquet-variant/src/builder/metadata.rs index a8c4e5ba1e5a..70b5d9216737 100644 --- a/parquet-variant/src/builder/metadata.rs +++ b/parquet-variant/src/builder/metadata.rs @@ -222,7 +222,7 @@ impl WritableMetadataBuilder { // Write offsets let mut cur_offset = 0; - for key in field_names.iter() { + for key in &field_names { write_offset(metadata_buffer, cur_offset, offset_size); cur_offset += key.len(); } diff --git a/parquet/src/arrow/array_reader/byte_array.rs b/parquet/src/arrow/array_reader/byte_array.rs index a7a76f1309bc..309abc3dba92 100644 --- a/parquet/src/arrow/array_reader/byte_array.rs +++ b/parquet/src/arrow/array_reader/byte_array.rs @@ -461,7 +461,7 @@ impl ByteArrayDecoderDeltaLength { let mut total_bytes = 0; - for l in lengths.iter() { + for l in &lengths { if *l < 0 { return Err(ParquetError::General( "negative delta length byte array length".to_string(), diff --git a/parquet/src/arrow/array_reader/byte_view_array.rs b/parquet/src/arrow/array_reader/byte_view_array.rs index 51a75151ce78..6647e51db938 100644 --- a/parquet/src/arrow/array_reader/byte_view_array.rs +++ b/parquet/src/arrow/array_reader/byte_view_array.rs @@ -501,7 +501,7 @@ impl ByteViewArrayDecoderDictionary { }; if need_to_create_new_buffer { - for b in dict.buffers.iter() { + for b in &dict.buffers { output.buffers.push(b.clone()); } } @@ -587,7 +587,7 @@ impl ByteViewArrayDecoderDeltaLength { let mut total_bytes = 0; - for l in lengths.iter() { + for l in &lengths { if *l < 0 { return Err(ParquetError::General( "negative delta length byte array length".to_string(), diff --git a/parquet/src/arrow/array_reader/struct_array.rs b/parquet/src/arrow/array_reader/struct_array.rs index 20327689765d..4faba7d6aa1e 100644 --- a/parquet/src/arrow/array_reader/struct_array.rs +++ b/parquet/src/arrow/array_reader/struct_array.rs @@ -71,7 +71,7 @@ impl ArrayReader for StructArrayReader { fn read_records(&mut self, batch_size: usize) -> Result { let mut read = None; - for child in self.children.iter_mut() { + for child in &mut self.children { let child_read = child.read_records(batch_size)?; match read { Some(expected) => { @@ -157,7 +157,7 @@ impl ArrayReader for StructArrayReader { fn skip_records(&mut self, num_records: usize) -> Result { let mut skipped = None; - for child in self.children.iter_mut() { + for child in &mut self.children { let child_skipped = child.skip_records(num_records)?; match skipped { Some(expected) => { diff --git a/parquet/src/arrow/arrow_reader/mod.rs b/parquet/src/arrow/arrow_reader/mod.rs index 5d8d0396f7af..113faeb3f546 100644 --- a/parquet/src/arrow/arrow_reader/mod.rs +++ b/parquet/src/arrow/arrow_reader/mod.rs @@ -1228,7 +1228,7 @@ impl ParquetRecordBatchReaderBuilder { // Update selection based on any filters if let Some(filter) = filter.as_mut() { - for predicate in filter.predicates.iter_mut() { + for predicate in &mut filter.predicates { // break early if we have ruled out all rows if !plan_builder.selects_any() { break; diff --git a/parquet/src/arrow/push_decoder/reader_builder/mod.rs b/parquet/src/arrow/push_decoder/reader_builder/mod.rs index ffc10382443f..9444161b8ccf 100644 --- a/parquet/src/arrow/push_decoder/reader_builder/mod.rs +++ b/parquet/src/arrow/push_decoder/reader_builder/mod.rs @@ -836,7 +836,7 @@ impl RowGroupReaderBuilder { return None; } let mut cache_projection = filter.predicates.first()?.projection().clone(); - for predicate in filter.predicates.iter() { + for predicate in &filter.predicates { cache_projection.union(predicate.projection()); } cache_projection.intersect(&self.projection); diff --git a/parquet/src/bloom_filter/mod.rs b/parquet/src/bloom_filter/mod.rs index 2d1214d7f56c..15197c79c4d5 100644 --- a/parquet/src/bloom_filter/mod.rs +++ b/parquet/src/bloom_filter/mod.rs @@ -1050,7 +1050,7 @@ mod tests { } // --- Per-hash verification of the two lemmas --- - for &h in hashes.iter() { + for &h in &hashes { // mask(h as u32) gives the 8-bit pattern that this hash sets // inside whichever block it lands in. It uses only the lower // 32 bits of h, so it's the same regardless of filter size. diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs index 7600febc851f..d3f016aaf4c0 100644 --- a/parquet/src/column/writer/mod.rs +++ b/parquet/src/column/writer/mod.rs @@ -231,7 +231,7 @@ impl ColumnCloseResult { .build()?; if let Some(offset_index) = self.offset_index.as_mut() { let mut offset = dictionary_len as i64; - for location in offset_index.page_locations.iter_mut() { + for location in &mut offset_index.page_locations { location.offset = offset; offset += location.compressed_page_size as i64; } diff --git a/parquet/src/encryption/decrypt.rs b/parquet/src/encryption/decrypt.rs index 3e42664d586a..409ec3c4b860 100644 --- a/parquet/src/encryption/decrypt.rs +++ b/parquet/src/encryption/decrypt.rs @@ -425,7 +425,7 @@ impl FileDecryptionProperties { let mut column_names: Vec = Vec::new(); let mut column_keys: Vec> = Vec::new(); if let DecryptionKeys::Explicit(keys) = &self.keys { - for (key, value) in keys.column_keys.iter() { + for (key, value) in &keys.column_keys { column_names.push(key.clone()); column_keys.push(value.clone()); } diff --git a/parquet/src/encryption/encrypt.rs b/parquet/src/encryption/encrypt.rs index d69e3c02500a..eb0cd09e8368 100644 --- a/parquet/src/encryption/encrypt.rs +++ b/parquet/src/encryption/encrypt.rs @@ -124,7 +124,7 @@ impl FileEncryptionProperties { let mut column_names: Vec = Vec::with_capacity(self.column_keys.len()); let mut keys: Vec> = Vec::with_capacity(self.column_keys.len()); let mut meta: Vec> = Vec::with_capacity(self.column_keys.len()); - for (key, value) in self.column_keys.iter() { + for (key, value) in &self.column_keys { column_names.push(key.clone()); keys.push(value.key.clone()); if let Some(metadata) = value.key_metadata.as_ref() { diff --git a/parquet/src/file/metadata/mod.rs b/parquet/src/file/metadata/mod.rs index 3b4451c21bd3..96fa991c4ef2 100644 --- a/parquet/src/file/metadata/mod.rs +++ b/parquet/src/file/metadata/mod.rs @@ -911,7 +911,7 @@ impl LevelHistogram { /// Sets the values of all histogram levels to 0. pub fn reset(&mut self) { - for value in self.inner.iter_mut() { + for value in &mut self.inner { *value = 0; } } diff --git a/parquet/src/schema/printer.rs b/parquet/src/schema/printer.rs index 67d8861aaf46..ddb51b20a130 100644 --- a/parquet/src/schema/printer.rs +++ b/parquet/src/schema/printer.rs @@ -78,7 +78,7 @@ pub fn print_file_metadata(out: &mut dyn io::Write, file_metadata: &FileMetaData } if let Some(metadata) = file_metadata.key_value_metadata() { writeln!(out, "metadata:"); - for kv in metadata.iter() { + for kv in metadata { writeln!( out, " {}: {}", diff --git a/parquet/src/schema/types.rs b/parquet/src/schema/types.rs index ff32da1b3b14..13bd2ef8ff9a 100644 --- a/parquet/src/schema/types.rs +++ b/parquet/src/schema/types.rs @@ -1173,7 +1173,7 @@ pub(crate) fn num_nodes(tp: &TypePtr) -> Result { return Err(general_err!("Root schema must be Group type")); } let mut n_nodes = 1usize; // count root - for f in tp.get_fields().iter() { + for f in tp.get_fields() { count_nodes(f, &mut n_nodes); } Ok(n_nodes) @@ -1194,7 +1194,7 @@ fn num_leaves(tp: &TypePtr) -> Result { return Err(general_err!("Root schema must be Group type")); } let mut n_leaves = 0usize; - for f in tp.get_fields().iter() { + for f in tp.get_fields() { count_leaves(f, &mut n_leaves); } Ok(n_leaves) diff --git a/parquet/tests/arrow_writer/mod.rs b/parquet/tests/arrow_writer/mod.rs index b0bf3bcb5a13..2ab386f982d3 100644 --- a/parquet/tests/arrow_writer/mod.rs +++ b/parquet/tests/arrow_writer/mod.rs @@ -178,7 +178,7 @@ fn make_batch(schema: &SchemaRef, batch_index: usize) -> RecordBatch { let mut fat: Vec = vec![0u8; FAT_VALUE_LEN * ROWS_PER_BATCH]; // A cheap xorshift fill keyed by the batch index → distinct, incompressible. let mut state = (batch_index as u64).wrapping_mul(0x9E37_79B9_7F4A_7C15) | 1; - for byte in fat.iter_mut() { + for byte in &mut fat { state ^= state << 13; state ^= state >> 7; state ^= state << 17; diff --git a/parquet/tests/encryption/encryption.rs b/parquet/tests/encryption/encryption.rs index 8dc4b6168bea..123bb30ad845 100644 --- a/parquet/tests/encryption/encryption.rs +++ b/parquet/tests/encryption/encryption.rs @@ -1089,7 +1089,7 @@ fn write_and_read_stats( // Check column statistics produced at write time are available in full let row_group = metadata.row_group(0); - for column in row_group.columns().iter() { + for column in row_group.columns() { check_column_stats(column, true); } diff --git a/parquet/tests/encryption/encryption_util.rs b/parquet/tests/encryption/encryption_util.rs index daf7e07b7bc2..62762ac01c66 100644 --- a/parquet/tests/encryption/encryption_util.rs +++ b/parquet/tests/encryption/encryption_util.rs @@ -153,7 +153,7 @@ pub(crate) fn verify_encryption_test_data( ((row_index(i) * 2 + 1) * 1000000000000) as i64 ); } - for x in timestamp_col.iter() { + for x in timestamp_col { assert!(x.is_some()); } for (i, x) in f32_col.iter().enumerate() { From 54db33c7480d0ea35b51490f6ebfc75e1d78acba Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 14 Aug 2026 10:17:48 +0200 Subject: [PATCH 17/17] Fix `clippy::ptr_as_ptr` in arrow-schema ffi tests Code added by the merge from main violated the newly enabled lint. Co-Authored-By: Claude Opus 5 (1M context) --- arrow-schema/src/ffi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arrow-schema/src/ffi.rs b/arrow-schema/src/ffi.rs index 6fd229a7f306..a37f0443b595 100644 --- a/arrow-schema/src/ffi.rs +++ b/arrow-schema/src/ffi.rs @@ -1098,7 +1098,7 @@ mod tests { unsafe extern "C" fn wrapping_release(schema: *mut FFI_ArrowSchema) { let schema = unsafe { &mut *schema }; - let data = unsafe { Box::from_raw(schema.private_data() as *mut WrapperData) }; + let data = unsafe { Box::from_raw(schema.private_data().cast::()) }; WRAPPER_RAN.store(true, Ordering::SeqCst); // restore the originals, then let the original callback free everything unsafe { schema.set_release(data.original_release) }; @@ -1117,7 +1117,7 @@ mod tests { original_private_data: schema.private_data(), }); unsafe { schema.set_release(Some(wrapping_release)) }; - unsafe { schema.set_private_data(Box::into_raw(data) as *mut c_void) }; + unsafe { schema.set_private_data(Box::into_raw(data).cast::()) }; drop(schema); // runs wrapping_release, which chains to the original assert!(WRAPPER_RAN.load(Ordering::SeqCst));