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

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


The following commit(s) were added to refs/heads/main by this push:
     new 000a7fd32e Enable five more clippy lints (#10935)
000a7fd32e is described below

commit 000a7fd32ecf928f9505afa3d77786179f8fd8dd
Author: Emil Ernerfeldt <[email protected]>
AuthorDate: Tue Sep 1 17:09:02 2026 +0200

    Enable five more clippy lints (#10935)
    
    # Which issue does this PR close?
    No issue in particular
    
    - Follow-up to #10673
    - Follow-up to #10721
    - Follow-up to #10742
    
    # Rationale for this change
    
    #10742 left the `pedantic` lints we violate as `allow`, with a violation
    count each. These five are the ones worth paying for: two guard raw
    pointers, one guards bindings that claim to be unused, and two improve
    readability and test output.
    
    ## What changes are included in this PR?
    
    One commit per new lint (easiest to review commit by commit!):
    
    *
    
[`redundant_else`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else)
    *
    
[`manual_assert_eq`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert_eq)
    *
    
[`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)
    - the FFI stream code now builds its pointers with `&raw mut` instead of
    going through a `&mut`
    *
    
[`used_underscore_binding`](https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_binding)
    - two conditionally-used parameters keep their names and get a
    feature-gated `expect`
    *
    
[`cast_ptr_alignment`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_ptr_alignment)
    - the five byte-pointer casts now say why they are sound
    
    Let me know if you disagree with any of them.
    
    ## Are these changes tested?
    
    Covered by existing tests plus the clippy CI job.
    
    ## Are there any user-facing changes?
    
    No.
    
    ---------
    
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
 Cargo.toml                                         |  5 --
 arrow-array/src/array/null_array.rs                |  2 +-
 arrow-array/src/ffi.rs                             | 13 ++++--
 arrow-array/src/ffi_stream.rs                      | 13 +++---
 arrow-avro/src/reader/mod.rs                       |  8 ++--
 arrow-buffer/src/bigint/mod.rs                     |  4 +-
 arrow-buffer/src/buffer/mutable.rs                 |  4 +-
 arrow-buffer/src/util/bit_mask.rs                  |  4 ++
 arrow-buffer/src/util/bit_util.rs                  |  4 ++
 arrow-data/src/equal/boolean.rs                    | 10 ++--
 .../src/bin/arrow-json-integration-test.rs         |  4 +-
 arrow-ipc/src/writer.rs                            |  8 ++--
 arrow-select/src/interleave.rs                     |  2 +-
 arrow-select/src/merge.rs                          |  5 +-
 arrow-select/src/take.rs                           |  8 ++--
 arrow-select/src/union_extract.rs                  |  3 +-
 arrow/src/util/test_util.rs                        | 10 ++--
 parquet-geospatial/src/interval.rs                 |  8 ++--
 parquet-variant-compute/src/arrow_to_variant.rs    | 14 +++---
 parquet-variant/tests/variant_interop.rs           |  5 +-
 .../src/arrow/arrow_reader/selection/selector.rs   |  3 +-
 parquet/src/arrow/arrow_writer/levels.rs           |  2 +-
 parquet/src/arrow/buffer/dictionary_buffer.rs      | 14 +++++-
 parquet/src/arrow/in_memory_row_group.rs           |  4 +-
 parquet/src/column/writer/mod.rs                   | 30 ++++++------
 parquet/src/compression.rs                         |  7 +++
 parquet/src/data_type.rs                           |  8 ++--
 parquet/src/file/metadata/reader.rs                | 22 ++++-----
 parquet/src/file/statistics.rs                     | 54 ++++++++++++++--------
 parquet/src/geospatial/accumulator.rs              |  7 +++
 parquet/src/schema/parser.rs                       |  5 +-
 parquet/src/util/bit_util.rs                       |  2 +-
 parquet/tests/encryption/encryption_async.rs       | 54 +++++++++++-----------
 33 files changed, 195 insertions(+), 151 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index df851b3ccb..db88598802 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -220,12 +220,10 @@ wildcard_dependencies = "warn"
 # Lints in `pedantic` that we currently allow.
 # Some of these we should consider enabling in the future.
 # Counts come from `cargo clippy --all-features --all-targets`.
-borrow_as_ptr = "allow"                      # ~9 violations in ~1 file
 cast_lossless = "allow"                      # ~640 violations in ~100 files
 cast_possible_truncation = "allow"           # ~890 violations in ~190 files
 cast_possible_wrap = "allow"                 # ~570 violations in ~120 files
 cast_precision_loss = "allow"                # ~130 violations in ~33 files
-cast_ptr_alignment = "allow"                 # ~3 violations in ~3 files
 cast_sign_loss = "allow"                     # ~590 violations in ~150 files
 default_trait_access = "allow"               # ~210 violations in ~68 files
 doc_markdown = "allow"                       # ~2300 violations in ~290 files
@@ -238,7 +236,6 @@ implicit_hasher = "allow"                    # ~9 
violations in ~4 files
 inline_always = "allow"                      # ~30 violations in ~17 files
 items_after_statements = "allow"             # ~130 violations in ~41 files
 manual_assert = "allow"                      # ~20 violations in ~12 files
-manual_assert_eq = "allow"                   # ~29 violations in ~10 files
 many_single_char_names = "allow"             # ~8 violations in ~5 files
 map_unwrap_or = "allow"                      # ~76 violations in ~40 files
 match_bool = "allow"                         # ~100 violations in ~49 files
@@ -253,7 +250,6 @@ needless_pass_by_value = "allow"             # ~260 
violations in ~110 files
 non_std_lazy_statics = "allow"               # ~56 violations in ~10 files
 range_plus_one = "allow"                     # ~17 violations in ~13 files
 redundant_closure_for_method_calls = "allow" # ~310 violations in ~130 files
-redundant_else = "allow"                     # ~23 violations in ~16 files
 return_self_not_must_use = "allow"           # ~470 violations in ~91 files
 semicolon_if_nothing_returned = "allow"      # ~1300 violations in ~250 files
 similar_names = "allow"                      # ~150 violations in ~43 files
@@ -267,7 +263,6 @@ unnecessary_debug_formatting = "allow"       # ~23 
violations in ~7 files
 unnecessary_wraps = "allow"                  # ~64 violations in ~39 files
 unreadable_literal = "allow"                 # ~4100 violations in ~120 files
 unused_self = "allow"                        # ~31 violations in ~20 files
-used_underscore_binding = "allow"            # ~15 violations in ~3 files
 used_underscore_items = "allow"              # ~120 violations in ~17 files
 verbose_bit_mask = "allow"                   # 1 violation in 1 file
 wildcard_imports = "allow"                   # ~230 violations in ~130 files
diff --git a/arrow-array/src/array/null_array.rs 
b/arrow-array/src/array/null_array.rs
index feced56a14..00aa20a1ba 100644
--- a/arrow-array/src/array/null_array.rs
+++ b/arrow-array/src/array/null_array.rs
@@ -237,6 +237,6 @@ mod tests {
         let data = mutable.freeze();
 
         let struct_array = Arc::new(StructArray::from(data.clone()));
-        assert!(make_array(data) == struct_array);
+        assert_eq!(&make_array(data), &(struct_array as ArrayRef));
     }
 }
diff --git a/arrow-array/src/ffi.rs b/arrow-array/src/ffi.rs
index 14235631a8..07707a641a 100644
--- a/arrow-array/src/ffi.rs
+++ b/arrow-array/src/ffi.rs
@@ -347,7 +347,7 @@ impl ImportedArrowArray<'_> {
             | DataType::LargeListView(field)
             | DataType::Map(field, _) => Ok([self.consume_child(0, 
field.data_type())?].to_vec()),
             DataType::Struct(fields) => {
-                assert!(fields.len() == self.array.num_children());
+                assert_eq!(fields.len(), self.array.num_children());
                 fields
                     .iter()
                     .enumerate()
@@ -355,7 +355,7 @@ impl ImportedArrowArray<'_> {
                     .collect::<Result<Vec<_>>>()
             }
             DataType::Union(union_fields, _) => {
-                assert!(union_fields.len() == self.array.num_children());
+                assert_eq!(union_fields.len(), self.array.num_children());
                 union_fields
                     .iter()
                     .enumerate()
@@ -397,7 +397,14 @@ impl ImportedArrowArray<'_> {
             } else {
                 let lengths = self.array.buffer(self.array.num_buffers() - 1);
                 // SAFETY: is lengths is non-null, then it must be valid for 
up to num_variadic_buffers.
-                unsafe { std::slice::from_raw_parts(lengths.cast::<i64>(), 
num_variadic_buffers) }
+                // The C data interface requires buffers to be aligned for 
their type.
+                #[expect(
+                    clippy::cast_ptr_alignment,
+                    reason = "the C data interface requires aligned buffers"
+                )]
+                unsafe {
+                    std::slice::from_raw_parts(lengths.cast::<i64>(), 
num_variadic_buffers)
+                }
             }
         } else {
             &[]
diff --git a/arrow-array/src/ffi_stream.rs b/arrow-array/src/ffi_stream.rs
index 58e23888f1..4bb570d56a 100644
--- a/arrow-array/src/ffi_stream.rs
+++ b/arrow-array/src/ffi_stream.rs
@@ -368,7 +368,7 @@ unsafe fn producer_error(stream_ptr: *mut 
FFI_ArrowArrayStream) -> Option<String
 fn get_stream_schema(stream_ptr: *mut FFI_ArrowArrayStream) -> 
Result<SchemaRef> {
     let mut schema = FFI_ArrowSchema::empty();
 
-    let ret_code = unsafe { (*stream_ptr).get_schema.unwrap()(stream_ptr, &mut 
schema) };
+    let ret_code = unsafe { (*stream_ptr).get_schema.unwrap()(stream_ptr, &raw 
mut schema) };
 
     if ret_code == 0 {
         let schema = Schema::try_from(&schema)?;
@@ -395,7 +395,7 @@ impl ArrowArrayStreamReader {
             ));
         }
 
-        let schema = get_stream_schema(&mut stream)?;
+        let schema = get_stream_schema(&raw mut stream)?;
 
         Ok(Self { stream, schema })
     }
@@ -421,7 +421,8 @@ impl Iterator for ArrowArrayStreamReader {
     fn next(&mut self) -> Option<Self::Item> {
         let mut array = FFI_ArrowArray::empty();
 
-        let ret_code = unsafe { self.stream.get_next.unwrap()(&mut 
self.stream, &mut array) };
+        let ret_code =
+            unsafe { self.stream.get_next.unwrap()(&raw mut self.stream, &raw 
mut array) };
 
         if ret_code == 0 {
             // The end of stream has been reached
@@ -445,7 +446,7 @@ impl Iterator for ArrowArrayStreamReader {
                 format!("Cannot get next batch from input stream. Error code: 
{ret_code}");
             // SAFETY: `self.stream` is valid and unreleased by construction, 
and the
             // `get_next` call above returned a non-zero code.
-            let message = match unsafe { producer_error(&mut self.stream) } {
+            let message = match unsafe { producer_error(&raw mut self.stream) 
} {
                 Some(producer_message) => format!("{message}. Producer error: 
{producer_message}"),
                 None => message,
             };
@@ -508,7 +509,7 @@ mod tests {
 
         // Get schema from `FFI_ArrowArrayStream`
         let mut ffi_schema = FFI_ArrowSchema::empty();
-        let ret_code = unsafe { get_schema(&mut ffi_stream, &mut ffi_schema) };
+        let ret_code = unsafe { get_schema(&raw mut ffi_stream, &raw mut 
ffi_schema) };
         assert_eq!(ret_code, 0);
 
         let exported_schema = Schema::try_from(&ffi_schema).unwrap();
@@ -518,7 +519,7 @@ mod tests {
         let mut produced_batches = vec![];
         loop {
             let mut ffi_array = FFI_ArrowArray::empty();
-            let ret_code = unsafe { get_next(&mut ffi_stream, &mut ffi_array) 
};
+            let ret_code = unsafe { get_next(&raw mut ffi_stream, &raw mut 
ffi_array) };
             assert_eq!(ret_code, 0);
 
             // The end of stream has been reached
diff --git a/arrow-avro/src/reader/mod.rs b/arrow-avro/src/reader/mod.rs
index 3b97b9bd48..f05df596a8 100644
--- a/arrow-avro/src/reader/mod.rs
+++ b/arrow-avro/src/reader/mod.rs
@@ -1706,10 +1706,9 @@ mod test {
             if (n & !0x7F) == 0 {
                 out.push(n as u8);
                 break;
-            } else {
-                out.push(((n & 0x7F) | 0x80) as u8);
-                n >>= 7;
             }
+            out.push(((n & 0x7F) | 0x80) as u8);
+            n >>= 7;
         }
         out
     }
@@ -3117,9 +3116,8 @@ mod test {
                             test.name
                         );
                         continue;
-                    } else {
-                        panic!("Test '{}' failed during build: {e}", 
test.name);
                     }
+                    panic!("Test '{}' failed during build: {e}", test.name);
                 }
             };
             let stream = Box::pin(stream::once(async { Bytes::from(body) }));
diff --git a/arrow-buffer/src/bigint/mod.rs b/arrow-buffer/src/bigint/mod.rs
index 7597e19896..2a359df2c1 100644
--- a/arrow-buffer/src/bigint/mod.rs
+++ b/arrow-buffer/src/bigint/mod.rs
@@ -732,14 +732,14 @@ impl i256 {
             // self is between 10^64 and 10^77 (~i256::MAX).
             // `value` is 14 digits max (10^77 / 10^64 = 10^13),
             // so it fits to `low` u128
-            debug_assert!(value.high == 0);
+            debug_assert_eq!(value.high, 0);
             Some(64 + value.low.checked_ilog10()?)
         } else if self >= POW10_32 {
             let value = self.checked_div(POW10_32)?;
             // self is between 10^32 and 10^64.
             // `value` is 33 digits max (10^64/10^32=10^32)
             // so it fits to `low` 128-bit value
-            debug_assert!(value.high == 0);
+            debug_assert_eq!(value.high, 0);
             Some(32 + value.low.checked_ilog10()?)
         } else {
             // self fits within u128 (high == 0 and self > 0).
diff --git a/arrow-buffer/src/buffer/mutable.rs 
b/arrow-buffer/src/buffer/mutable.rs
index 150fe44043..c53cf3fcab 100644
--- a/arrow-buffer/src/buffer/mutable.rs
+++ b/arrow-buffer/src/buffer/mutable.rs
@@ -1465,13 +1465,13 @@ mod tests {
 
         buf.extend_from_slice(&[0xaa]);
         buf2.extend_from_slice(&[0xaa, 0xbb]);
-        assert!(buf != buf2);
+        assert_ne!(buf, buf2);
 
         buf.extend_from_slice(&[0xbb]);
         assert_eq!(buf, buf2);
 
         buf2.reserve(65);
-        assert!(buf != buf2);
+        assert_ne!(buf, buf2);
     }
 
     #[test]
diff --git a/arrow-buffer/src/util/bit_mask.rs 
b/arrow-buffer/src/util/bit_mask.rs
index b1f25eb014..d65988dca1 100644
--- a/arrow-buffer/src/util/bit_mask.rs
+++ b/arrow-buffer/src/util/bit_mask.rs
@@ -156,6 +156,10 @@ 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) {
+    #[expect(
+        clippy::cast_ptr_alignment,
+        reason = "the pointer is only written through `write_unaligned`"
+    )]
     let ptr = unsafe { data.as_mut_ptr().add(offset) }.cast::<u64>();
     unsafe { ptr.write_unaligned(chunk) };
 }
diff --git a/arrow-buffer/src/util/bit_util.rs 
b/arrow-buffer/src/util/bit_util.rs
index f06e03ef13..6faec24111 100644
--- a/arrow-buffer/src/util/bit_util.rs
+++ b/arrow-buffer/src/util/bit_util.rs
@@ -574,6 +574,10 @@ 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);
 
+        #[expect(
+            clippy::cast_ptr_alignment,
+            reason = "`U64UnalignedSlice` only reads and writes through the 
unaligned methods"
+        )]
         let ptr = bytes_for_u64.as_mut_ptr().cast::<u64>();
 
         let this = Self {
diff --git a/arrow-data/src/equal/boolean.rs b/arrow-data/src/equal/boolean.rs
index cbd18ad789..b413ddc3cb 100644
--- a/arrow-data/src/equal/boolean.rs
+++ b/arrow-data/src/equal/boolean.rs
@@ -59,12 +59,12 @@ pub(super) fn boolean_equal(
             let rem = len % 8;
             if rem == 0 {
                 return true;
-            } else {
-                let aligned_bits = len - rem;
-                lhs_start += aligned_bits;
-                rhs_start += aligned_bits;
-                len = rem
             }
+
+            let aligned_bits = len - rem;
+            lhs_start += aligned_bits;
+            rhs_start += aligned_bits;
+            len = rem;
         }
 
         equal_bits(
diff --git a/arrow-integration-testing/src/bin/arrow-json-integration-test.rs 
b/arrow-integration-testing/src/bin/arrow-json-integration-test.rs
index a71ba166ca..3ee551fe4c 100644
--- a/arrow-integration-testing/src/bin/arrow-json-integration-test.rs
+++ b/arrow-integration-testing/src/bin/arrow-json-integration-test.rs
@@ -161,8 +161,8 @@ fn validate(arrow_name: &str, json_name: &str, verbose: 
bool) -> Result<()> {
         if let Some(Ok(arrow_batch)) = arrow_reader.next() {
             // compare batches
             let num_columns = arrow_batch.num_columns();
-            assert!(num_columns == json_batch.num_columns());
-            assert!(arrow_batch.num_rows() == json_batch.num_rows());
+            assert_eq!(num_columns, json_batch.num_columns());
+            assert_eq!(arrow_batch.num_rows(), json_batch.num_rows());
 
             for i in 0..num_columns {
                 assert_eq!(
diff --git a/arrow-ipc/src/writer.rs b/arrow-ipc/src/writer.rs
index 11a3030e03..99d40632f2 100644
--- a/arrow-ipc/src/writer.rs
+++ b/arrow-ipc/src/writer.rs
@@ -1549,11 +1549,11 @@ fn compare_dictionaries(old: &ArrayData, new: 
&ArrayData) -> DictionaryCompariso
     let existing_len = old.len();
     let new_len = new.len();
     if existing_len == new_len {
-        if *old == *new {
-            return DictionaryComparison::Equal;
+        return if *old == *new {
+            DictionaryComparison::Equal
         } else {
-            return DictionaryComparison::NotEqual;
-        }
+            DictionaryComparison::NotEqual
+        };
     }
 
     // Can't be a delta if the new is shorter than the existing
diff --git a/arrow-select/src/interleave.rs b/arrow-select/src/interleave.rs
index 494fdb2931..3d8aaeccdc 100644
--- a/arrow-select/src/interleave.rs
+++ b/arrow-select/src/interleave.rs
@@ -211,7 +211,7 @@ fn interleave_primitive<T: ArrowPrimitiveType>(
     }
 
     // SAFETY: all `len` elements have been initialized
-    debug_assert!(base == len);
+    debug_assert_eq!(base, len);
     unsafe { output.set_len(len) };
 
     let array = PrimitiveArray::<T>::try_new(output.into(), 
interleaved.nulls)?;
diff --git a/arrow-select/src/merge.rs b/arrow-select/src/merge.rs
index 2198194380..be69054cbd 100644
--- a/arrow-select/src/merge.rs
+++ b/arrow-select/src/merge.rs
@@ -174,10 +174,9 @@ pub fn merge_n(values: &[&dyn Array], indices: &[impl 
MergeIndex]) -> Result<Arr
 
         if end_row_ix == indices.len() {
             break;
-        } else {
-            // Set the start_row_ix for the next slice.
-            start_row_ix = end_row_ix;
         }
+        // Set the start_row_ix for the next slice.
+        start_row_ix = end_row_ix;
     }
 
     Ok(make_array(mutable.freeze()))
diff --git a/arrow-select/src/take.rs b/arrow-select/src/take.rs
index d429bbd268..55b3d521ab 100644
--- a/arrow-select/src/take.rs
+++ b/arrow-select/src/take.rs
@@ -172,12 +172,12 @@ where
     T::Native: Display,
 {
     let Some(len) = T::Native::from_usize(len) else {
-        if T::DATA_TYPE.is_integer() {
+        return if T::DATA_TYPE.is_integer() {
             // the biggest representable value for T::Native is lower than 
len, e.g: u8::MAX < 512, no need to check bounds
-            return Ok(());
+            Ok(())
         } else {
-            return Err(ArrowError::ComputeError("Cast to usize 
failed".to_string()));
-        }
+            Err(ArrowError::ComputeError("Cast to usize failed".to_string()))
+        };
     };
 
     if indices.null_count() > 0 {
diff --git a/arrow-select/src/union_extract.rs 
b/arrow-select/src/union_extract.rs
index b5a547ffd4..00fe6db734 100644
--- a/arrow-select/src/union_extract.rs
+++ b/arrow-select/src/union_extract.rs
@@ -354,9 +354,8 @@ fn eq_scalar_inner(chunk_size: usize, type_ids: &[i8], 
target: i8) -> BoolValue
 
         if false_bits == type_ids.len() {
             return BoolValue::Scalar(false);
-        } else {
-            (false_bits, false)
         }
+        (false_bits, false)
     } else {
         (true_bits, true)
     };
diff --git a/arrow/src/util/test_util.rs b/arrow/src/util/test_util.rs
index 2a8bf05852..90b3b4e272 100644
--- a/arrow/src/util/test_util.rs
+++ b/arrow/src/util/test_util.rs
@@ -120,16 +120,16 @@ fn get_data_dir(udf_env: &str, submodule_data: &str) -> 
Result<PathBuf, Box<dyn
         let trimmed = dir.trim().to_string();
         if !trimmed.is_empty() {
             let pb = PathBuf::from(trimmed);
-            if pb.is_dir() {
-                return Ok(pb);
+            return if pb.is_dir() {
+                Ok(pb)
             } else {
-                return Err(format!(
+                Err(format!(
                     "the data dir `{}` defined by env {} not found",
                     pb.display(),
                     udf_env
                 )
-                .into());
-            }
+                .into())
+            };
         }
     }
 
diff --git a/parquet-geospatial/src/interval.rs 
b/parquet-geospatial/src/interval.rs
index 3b3b9d868b..97a84ec00c 100644
--- a/parquet-geospatial/src/interval.rs
+++ b/parquet-geospatial/src/interval.rs
@@ -423,11 +423,11 @@ impl IntervalTrait for WraparoundInterval {
                 let new_right = right.merge_interval(&other_right);
 
                 // If the left and right intervals intersect each other, we 
need the full interval
-                if new_left.intersects_interval(&new_right) {
-                    return WraparoundInterval::full();
+                return if new_left.intersects_interval(&new_right) {
+                    WraparoundInterval::full()
                 } else {
-                    return WraparoundInterval::new(new_right.lo(), 
new_left.hi());
-                }
+                    WraparoundInterval::new(new_right.lo(), new_left.hi())
+                };
             }
             // Neither are wraparound: just merge the inner intervals
             (false, false) => {
diff --git a/parquet-variant-compute/src/arrow_to_variant.rs 
b/parquet-variant-compute/src/arrow_to_variant.rs
index 380946cc91..7bf80ad0b3 100644
--- a/parquet-variant-compute/src/arrow_to_variant.rs
+++ b/parquet-variant-compute/src/arrow_to_variant.rs
@@ -365,16 +365,16 @@ macro_rules! define_row_builder {
                         $(
                             // NOTE: The `?` macro expansion fails without the 
type annotation.
                             let Some(value): Option<$option_ty> = value else {
-                                if !self.options.safe {
-                                    return 
Err(ArrowError::ComputeError(format!(
-                                        "Failed to convert value at index 
{index}: conversion failed",
-                                    )));
-                                } else {
+                                return if self.options.safe {
                                     // Overflow is encoded as Variant::Null,
                                     // distinct from None indicating a missing 
value
                                     builder.append_value(Variant::Null);
-                                    return Ok(());
-                                }
+                                    Ok(())
+                                } else {
+                                    Err(ArrowError::ComputeError(format!(
+                                        "Failed to convert value at index 
{index}: conversion failed",
+                                    )))
+                                };
                             };
                         )?
                     )?
diff --git a/parquet-variant/tests/variant_interop.rs 
b/parquet-variant/tests/variant_interop.rs
index 229ea44937..9c8b21aa5f 100644
--- a/parquet-variant/tests/variant_interop.rs
+++ b/parquet-variant/tests/variant_interop.rs
@@ -54,11 +54,8 @@ fn cases_dir() -> PathBuf {
             let pb = PathBuf::from(trimmed).join("..").join("variant");
             if pb.is_dir() {
                 return pb;
-            } else {
-                panic!(
-                    "Can't find variant data at `{pb:?}`. Used value of env 
`{env_name}`../variant ",
-                )
             }
+            panic!("Can't find variant data at `{pb:?}`. Used value of env 
`{env_name}`../variant ")
         }
     }
 
diff --git a/parquet/src/arrow/arrow_reader/selection/selector.rs 
b/parquet/src/arrow/arrow_reader/selection/selector.rs
index 680cc72879..291b0aaa84 100644
--- a/parquet/src/arrow/arrow_reader/selection/selector.rs
+++ b/parquet/src/arrow/arrow_reader/selection/selector.rs
@@ -136,9 +136,8 @@ pub(super) fn limit_selectors(
                 selection.row_count = limit;
                 selectors.truncate(idx + 1);
                 break;
-            } else {
-                limit -= selection.row_count;
             }
+            limit -= selection.row_count;
         }
     }
     selectors
diff --git a/parquet/src/arrow/arrow_writer/levels.rs 
b/parquet/src/arrow/arrow_writer/levels.rs
index 40417ef73c..d62378bbde 100644
--- a/parquet/src/arrow/arrow_writer/levels.rs
+++ b/parquet/src/arrow/arrow_writer/levels.rs
@@ -418,7 +418,7 @@ impl LevelInfoBuilder {
             // mapping between child elements and rep_level entries, the 
position
             // of each slot's first element is directly computable from 
offsets.
             child.visit_leaves(|leaf| {
-                debug_assert!(leaf.max_rep_level == ctx.rep_level);
+                debug_assert_eq!(leaf.max_rep_level, ctx.rep_level);
                 let rep_levels = leaf.rep_levels.materialize_mut().unwrap();
                 let batch_len = values_end - values_start;
                 let batch_base = rep_levels.len() - batch_len;
diff --git a/parquet/src/arrow/buffer/dictionary_buffer.rs 
b/parquet/src/arrow/buffer/dictionary_buffer.rs
index c2f92bf4c5..441da3a501 100644
--- a/parquet/src/arrow/buffer/dictionary_buffer.rs
+++ b/parquet/src/arrow/buffer/dictionary_buffer.rs
@@ -400,6 +400,10 @@ fn hash_byte_slices<I: ArrowNativeType>(offsets: &[I], 
values: &[u8], scratch: &
     let state = RandomState::new();
 
     // SAFETY: MutableBuffer is 64-byte aligned; scratch is sized to exactly 
count * size_of::<u64>()
+    #[expect(
+        clippy::cast_ptr_alignment,
+        reason = "MutableBuffer is 64-byte aligned"
+    )]
     let hash_slots = unsafe { 
from_raw_parts_mut(scratch.as_mut_ptr().cast::<u64>(), count) };
 
     for idx in 0..count {
@@ -415,8 +419,14 @@ fn hash_byte_slices<I: ArrowNativeType>(offsets: &[I], 
values: &[u8], scratch: &
 #[inline]
 fn hashes_as_u64(scratch: &[u8]) -> &[u64] {
     let n = scratch.len() / size_of::<u64>();
-    // SAFETY: scratch was written as u64s by hash_byte_slices
-    unsafe { from_raw_parts(scratch.as_ptr().cast::<u64>(), n) }
+    // SAFETY: scratch was written as u64s by hash_byte_slices, and 
MutableBuffer is 64-byte aligned
+    #[expect(
+        clippy::cast_ptr_alignment,
+        reason = "MutableBuffer is 64-byte aligned"
+    )]
+    unsafe {
+        from_raw_parts(scratch.as_ptr().cast::<u64>(), n)
+    }
 }
 
 #[cfg(test)]
diff --git a/parquet/src/arrow/in_memory_row_group.rs 
b/parquet/src/arrow/in_memory_row_group.rs
index db523e5be1..9abf596022 100644
--- a/parquet/src/arrow/in_memory_row_group.rs
+++ b/parquet/src/arrow/in_memory_row_group.rs
@@ -84,10 +84,10 @@ impl InMemoryRowGroup<'_> {
                     // If the first page does not start at the beginning of 
the column,
                     // then we need to also fetch a dictionary page.
                     let mut ranges: Vec<Range<u64>> = vec![];
-                    let (start, _len) = chunk_meta.byte_range();
+                    let (start, len) = chunk_meta.byte_range();
                     let Some(offset_idx) = offset_index[idx].as_ref() else {
                         // No offset index for this column, fetch the entire 
column
-                        ranges.push(start..start + _len);
+                        ranges.push(start..start + len);
                         return ranges;
                     };
 
diff --git a/parquet/src/column/writer/mod.rs b/parquet/src/column/writer/mod.rs
index a91d2af53d..1f4466c082 100644
--- a/parquet/src/column/writer/mod.rs
+++ b/parquet/src/column/writer/mod.rs
@@ -4430,12 +4430,12 @@ mod tests {
         assert_eq!(1, r.rows_written);
 
         let stats = r.metadata.statistics().expect("statistics");
-        if let Statistics::ByteArray(_stats) = stats {
-            let min_value = _stats.min_opt().unwrap();
-            let max_value = _stats.max_opt().unwrap();
+        if let Statistics::ByteArray(stats) = stats {
+            let min_value = stats.min_opt().unwrap();
+            let max_value = stats.max_opt().unwrap();
 
-            assert!(!_stats.min_is_exact());
-            assert!(!_stats.max_is_exact());
+            assert!(!stats.min_is_exact());
+            assert!(!stats.max_is_exact());
 
             let expected_len = 64;
             assert_eq!(min_value.len(), expected_len);
@@ -4480,12 +4480,12 @@ mod tests {
         let stats = r.metadata.statistics().expect("statistics");
         assert_eq!(stats.null_count_opt(), Some(0));
         assert_eq!(stats.distinct_count_opt(), None);
-        if let Statistics::ByteArray(_stats) = stats {
-            let min_value = _stats.min_opt().unwrap();
-            let max_value = _stats.max_opt().unwrap();
+        if let Statistics::ByteArray(stats) = stats {
+            let min_value = stats.min_opt().unwrap();
+            let max_value = stats.max_opt().unwrap();
 
-            assert!(!_stats.min_is_exact());
-            assert!(!_stats.max_is_exact());
+            assert!(!stats.min_is_exact());
+            assert!(!stats.max_is_exact());
 
             assert_eq!(min_value.len(), TEST_TRUNCATE_LENGTH);
             assert_eq!(max_value.len(), TEST_TRUNCATE_LENGTH);
@@ -4532,12 +4532,12 @@ mod tests {
         let stats = r.metadata.statistics().expect("statistics");
         assert_eq!(stats.null_count_opt(), Some(0));
         assert_eq!(stats.distinct_count_opt(), None);
-        if let Statistics::FixedLenByteArray(_stats) = stats {
-            let min_value = _stats.min_opt().unwrap();
-            let max_value = _stats.max_opt().unwrap();
+        if let Statistics::FixedLenByteArray(stats) = stats {
+            let min_value = stats.min_opt().unwrap();
+            let max_value = stats.max_opt().unwrap();
 
-            assert!(!_stats.min_is_exact());
-            assert!(!_stats.max_is_exact());
+            assert!(!stats.min_is_exact());
+            assert!(!stats.max_is_exact());
 
             assert_eq!(min_value.len(), TEST_TRUNCATE_LENGTH);
             assert_eq!(max_value.len(), TEST_TRUNCATE_LENGTH);
diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs
index 74d740348a..2eb71f621c 100644
--- a/parquet/src/compression.rs
+++ b/parquet/src/compression.rs
@@ -146,6 +146,13 @@ pub(crate) trait CompressionLevel<T: std::fmt::Display + 
std::cmp::PartialOrd> {
 /// Given the compression type `codec`, returns a codec used to compress and 
decompress
 /// bytes for the compression type.
 /// This returns `None` if the codec type is `UNCOMPRESSED`.
+#[cfg_attr(
+    any(feature = "lz4", test),
+    expect(
+        clippy::used_underscore_binding,
+        reason = "`_options` is only read when the `lz4` feature is on"
+    )
+)]
 pub fn create_codec(codec: CodecType, _options: &CodecOptions) -> 
Result<Option<Box<dyn Codec>>> {
     #[cfg_attr(
         any(
diff --git a/parquet/src/data_type.rs b/parquet/src/data_type.rs
index 29f5f07fc6..432cf28d81 100644
--- a/parquet/src/data_type.rs
+++ b/parquet/src/data_type.rs
@@ -1407,11 +1407,11 @@ mod tests {
             Decimal::from_i32(3, 5, 2)
         );
 
-        assert!(Decimal::from_i32(222, 5, 2) != Decimal::from_i32(111, 5, 2));
-        assert!(Decimal::from_i32(222, 5, 2) != Decimal::from_i32(222, 6, 2));
-        assert!(Decimal::from_i32(222, 5, 2) != Decimal::from_i32(222, 5, 3));
+        assert_ne!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(111, 5, 2));
+        assert_ne!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(222, 6, 2));
+        assert_ne!(Decimal::from_i32(222, 5, 2), Decimal::from_i32(222, 5, 3));
 
-        assert!(Decimal::from_i64(222, 5, 2) != Decimal::from_i32(222, 5, 2));
+        assert_ne!(Decimal::from_i64(222, 5, 2), Decimal::from_i32(222, 5, 2));
     }
 
     #[test]
diff --git a/parquet/src/file/metadata/reader.rs 
b/parquet/src/file/metadata/reader.rs
index 018cf440cd..9589e308d7 100644
--- a/parquet/src/file/metadata/reader.rs
+++ b/parquet/src/file/metadata/reader.rs
@@ -290,16 +290,16 @@ impl ParquetMetaDataReader {
             Err(ParquetError::NeedMoreData(needed)) => {
                 // If reader is the same length as `file_size` then presumably 
there is no more to
                 // read, so return an EOF error.
-                if file_size == reader.len() || needed as u64 > file_size {
-                    return Err(eof_err!(
+                return if file_size == reader.len() || needed as u64 > 
file_size {
+                    Err(eof_err!(
                         "Parquet file too small. Size is {} but need {}",
                         file_size,
                         needed
-                    ));
+                    ))
                 } else {
                     // Ask for a larger buffer
-                    return Err(ParquetError::NeedMoreData(needed));
-                }
+                    Err(ParquetError::NeedMoreData(needed))
+                };
             }
             Err(e) => return Err(e),
         };
@@ -355,16 +355,16 @@ impl ParquetMetaDataReader {
         let file_range = file_size.saturating_sub(reader.len())..file_size;
         if !(file_range.contains(&range.start) && 
file_range.contains(&range.end)) {
             // Requested range starts beyond EOF
-            if range.end > file_size {
-                return Err(eof_err!(
+            return if range.end > file_size {
+                Err(eof_err!(
                     "Parquet file too small. Range {range:?} is beyond file 
bounds {file_size}",
-                ));
+                ))
             } else {
                 // Ask for a larger buffer
-                return Err(ParquetError::NeedMoreData(
+                Err(ParquetError::NeedMoreData(
                     (file_size - range.start).try_into()?,
-                ));
-            }
+                ))
+            };
         }
 
         // Perform extra sanity check to make sure `range` and the footer 
metadata don't
diff --git a/parquet/src/file/statistics.rs b/parquet/src/file/statistics.rs
index 5c9304652c..0c6503a5a9 100644
--- a/parquet/src/file/statistics.rs
+++ b/parquet/src/file/statistics.rs
@@ -867,30 +867,46 @@ mod tests {
     fn test_statistics_partial_eq() {
         let expected = Statistics::int32(Some(12), Some(45), None, Some(11), 
true);
 
-        assert!(Statistics::int32(Some(12), Some(45), None, Some(11), true) == 
expected);
-        assert!(Statistics::int32(Some(11), Some(45), None, Some(11), true) != 
expected);
-        assert!(Statistics::int32(Some(12), Some(44), None, Some(11), true) != 
expected);
-        assert!(Statistics::int32(Some(12), Some(45), None, Some(23), true) != 
expected);
-        assert!(Statistics::int32(Some(12), Some(45), None, Some(11), false) 
!= expected);
-
-        assert!(
-            Statistics::int32(Some(12), Some(45), None, Some(11), false)
-                != Statistics::int64(Some(12), Some(45), None, Some(11), false)
+        assert_eq!(
+            Statistics::int32(Some(12), Some(45), None, Some(11), true),
+            expected
+        );
+        assert_ne!(
+            Statistics::int32(Some(11), Some(45), None, Some(11), true),
+            expected
+        );
+        assert_ne!(
+            Statistics::int32(Some(12), Some(44), None, Some(11), true),
+            expected
+        );
+        assert_ne!(
+            Statistics::int32(Some(12), Some(45), None, Some(23), true),
+            expected
+        );
+        assert_ne!(
+            Statistics::int32(Some(12), Some(45), None, Some(11), false),
+            expected
+        );
+
+        assert_ne!(
+            Statistics::int32(Some(12), Some(45), None, Some(11), false),
+            Statistics::int64(Some(12), Some(45), None, Some(11), false)
         );
 
-        assert!(
-            Statistics::boolean(Some(false), Some(true), None, None, true)
-                != Statistics::double(Some(1.2), Some(4.5), None, None, true)
+        assert_ne!(
+            Statistics::boolean(Some(false), Some(true), None, None, true),
+            Statistics::double(Some(1.2), Some(4.5), None, None, true)
         );
 
-        assert!(
+        assert_ne!(
             Statistics::byte_array(
                 Some(ByteArray::from(vec![1, 2, 3])),
                 Some(ByteArray::from(vec![1, 2, 3])),
                 None,
                 None,
                 true
-            ) != Statistics::fixed_len_byte_array(
+            ),
+            Statistics::fixed_len_byte_array(
                 Some(ByteArray::from(vec![1, 2, 3]).into()),
                 Some(ByteArray::from(vec![1, 2, 3]).into()),
                 None,
@@ -899,14 +915,15 @@ mod tests {
             )
         );
 
-        assert!(
+        assert_ne!(
             Statistics::byte_array(
                 Some(ByteArray::from(vec![1, 2, 3])),
                 Some(ByteArray::from(vec![1, 2, 3])),
                 None,
                 None,
                 true,
-            ) != Statistics::ByteArray(
+            ),
+            Statistics::ByteArray(
                 ValueStatistics::new(
                     Some(ByteArray::from(vec![1, 2, 3])),
                     Some(ByteArray::from(vec![1, 2, 3])),
@@ -918,14 +935,15 @@ mod tests {
             )
         );
 
-        assert!(
+        assert_ne!(
             Statistics::fixed_len_byte_array(
                 Some(FixedLenByteArray::from(vec![1, 2, 3])),
                 Some(FixedLenByteArray::from(vec![1, 2, 3])),
                 None,
                 None,
                 true,
-            ) != Statistics::FixedLenByteArray(
+            ),
+            Statistics::FixedLenByteArray(
                 ValueStatistics::new(
                     Some(FixedLenByteArray::from(vec![1, 2, 3])),
                     Some(FixedLenByteArray::from(vec![1, 2, 3])),
diff --git a/parquet/src/geospatial/accumulator.rs 
b/parquet/src/geospatial/accumulator.rs
index 477721897d..adc96e9ced 100644
--- a/parquet/src/geospatial/accumulator.rs
+++ b/parquet/src/geospatial/accumulator.rs
@@ -116,6 +116,13 @@ pub trait GeoStatsAccumulator: Send {
 pub struct DefaultGeoStatsAccumulatorFactory {}
 
 impl GeoStatsAccumulatorFactory for DefaultGeoStatsAccumulatorFactory {
+    #[cfg_attr(
+        feature = "geospatial",
+        expect(
+            clippy::used_underscore_binding,
+            reason = "`_descr` is only read when the `geospatial` feature is 
on"
+        )
+    )]
     fn new_accumulator(&self, _descr: &ColumnDescPtr) -> Box<dyn 
GeoStatsAccumulator> {
         #[cfg(feature = "geospatial")]
         if let Some(crate::basic::LogicalType::Geometry { .. }) = 
_descr.logical_type_ref() {
diff --git a/parquet/src/schema/parser.rs b/parquet/src/schema/parser.rs
index 204246b5db..9ac7a62273 100644
--- a/parquet/src/schema/parser.rs
+++ b/parquet/src/schema/parser.rs
@@ -209,10 +209,9 @@ impl Parser<'_> {
         while let Some(value) = self.tokenizer.next() {
             if value == "}" {
                 break;
-            } else {
-                self.tokenizer.backtrack();
-                vec.push(Arc::new(self.add_type()?));
             }
+            self.tokenizer.backtrack();
+            vec.push(Arc::new(self.add_type()?));
         }
         Ok(vec)
     }
diff --git a/parquet/src/util/bit_util.rs b/parquet/src/util/bit_util.rs
index 20ce146463..ab1524f639 100644
--- a/parquet/src/util/bit_util.rs
+++ b/parquet/src/util/bit_util.rs
@@ -175,7 +175,7 @@ impl FromBitpacked for bool {
 
     #[inline]
     fn unpack_batch(input: &[u8], output: &mut [Self], num_bits: usize) {
-        assert!(num_bits == 1);
+        assert_eq!(num_bits, 1);
         // Safety:
         //   we asserted that we will only decode with a bitwidth of 1,
         //   so the u8 can only be 0 or 1, which are the valid representations 
of a bool.
diff --git a/parquet/tests/encryption/encryption_async.rs 
b/parquet/tests/encryption/encryption_async.rs
index 35b9878a68..189eaccb8b 100644
--- a/parquet/tests/encryption/encryption_async.rs
+++ b/parquet/tests/encryption/encryption_async.rs
@@ -800,7 +800,7 @@ fn spawn_parquet_parallel_serialization_task(
         let mut current_rg_rows = 0;
 
         while let Some(mut rb) = data.recv().await {
-            // This loop allows the "else" block to repeatedly split the 
RecordBatch to handle the case
+            // This loop repeatedly splits the RecordBatch to handle the case
             // when max_row_group_rows < execution.batch_size as an 
alternative to a recursive async
             // function.
             loop {
@@ -808,33 +808,33 @@ fn spawn_parquet_parallel_serialization_task(
                     send_arrays_to_column_writers(&col_array_channels, &rb, 
&schema).await?;
                     current_rg_rows += rb.num_rows();
                     break;
-                } else {
-                    let rows_left = max_row_group_rows - current_rg_rows;
-                    let rb_split = rb.slice(0, rows_left);
-                    send_arrays_to_column_writers(&col_array_channels, 
&rb_split, &schema).await?;
-
-                    // Signal the parallel column writers that the RowGroup is 
done, join and finalize RowGroup
-                    // on a separate task, so that we can immediately start on 
the next RG before waiting
-                    // for the current one to finish.
-                    drop(col_array_channels);
-
-                    let finalize_rg_task =
-                        spawn_rg_join_and_finalize_task(col_writer_tasks, 
max_row_group_rows);
-
-                    // Do not surface error from closed channel (means 
something
-                    // else hit an error, and the plan is shutting down).
-                    if serialize_tx.send(finalize_rg_task).await.is_err() {
-                        return Ok(());
-                    }
-
-                    current_rg_rows = 0;
-                    rb = rb.slice(rows_left, rb.num_rows() - rows_left);
-
-                    row_group_index += 1;
-                    let column_writers = 
writer_factory.create_column_writers(row_group_index)?;
-                    (col_writer_tasks, col_array_channels) =
-                        spawn_column_parallel_row_group_writer(column_writers, 
100)?;
                 }
+
+                let rows_left = max_row_group_rows - current_rg_rows;
+                let rb_split = rb.slice(0, rows_left);
+                send_arrays_to_column_writers(&col_array_channels, &rb_split, 
&schema).await?;
+
+                // Signal the parallel column writers that the RowGroup is 
done, join and finalize RowGroup
+                // on a separate task, so that we can immediately start on the 
next RG before waiting
+                // for the current one to finish.
+                drop(col_array_channels);
+
+                let finalize_rg_task =
+                    spawn_rg_join_and_finalize_task(col_writer_tasks, 
max_row_group_rows);
+
+                // Do not surface error from closed channel (means something
+                // else hit an error, and the plan is shutting down).
+                if serialize_tx.send(finalize_rg_task).await.is_err() {
+                    return Ok(());
+                }
+
+                current_rg_rows = 0;
+                rb = rb.slice(rows_left, rb.num_rows() - rows_left);
+
+                row_group_index += 1;
+                let column_writers = 
writer_factory.create_column_writers(row_group_index)?;
+                (col_writer_tasks, col_array_channels) =
+                    spawn_column_parallel_row_group_writer(column_writers, 
100)?;
             }
         }
 

Reply via email to