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 c35c11b099 chore(deps): bump rust-toolchain from 1.97.1 to 1.98.1 
(#10778)
c35c11b099 is described below

commit c35c11b099f8a328e58732dcae5a7f7897c97869
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
AuthorDate: Tue Sep 8 14:45:11 2026 +1000

    chore(deps): bump rust-toolchain from 1.97.1 to 1.98.1 (#10778)
    
    Bumps [rust-toolchain](https://github.com/rust-lang/rust) from 1.97.1 to
    1.98.0.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-lang/rust/releases";>rust-toolchain's
    releases</a>.</em></p>
    <blockquote>
    <h2>Rust 1.98.0</h2>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Language</h2>
    <ul>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/149219";>Allow
    shortening lifetime of <code>&amp;mut</code> when unsize-coercing, even
    in an invariant position.</a> For example, you can now coerce a
    <code>Cell&lt;&amp;'long mut i32&gt;</code> to a
    <code>Cell&lt;&amp;'short mut dyn Send&gt;</code>. Such shortenings were
    already previously allowed when coercing a <code>&amp;mut</code> to a
    <code>&amp;</code>, or coercing a <code>&amp;</code> to a
    <code>&amp;</code>.</li>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/155521";>Add
    deny-by-default <code>invalid_runtime_symbol_definitions</code> lint and
    warn-by-default <code>suspicious_runtime_symbol_definitions</code>
    lint</a>
    <ul>
    <li>The lints currently specifically targets <code>core</code> runtime
    symbols like <code>memcmp</code>, <code>memset</code>,
    <code>strlen</code>, ... and is planned to be expanded in the next few
    releases.</li>
    </ul>
    </li>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/156379";>Add
    warn-by-default <code>c_void_returns</code> lint to check
    <code>core::ffi::c_void</code> as a return type</a></li>
    </ul>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Platform Support</h2>
    <ul>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/144220";>Add
    <code>powerpc64-unknown-linux-gnuelfv2</code> as Tier 3</a></li>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/155722";>Add
    <code>aarch64-unknown-linux-pauthtest</code> as Tier 3 target</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7a-none-eabi</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7a-none-eabihf</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7r-none-eabi</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7r-none-eabihf</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv8r-none-eabihf</code> to Tier 2</a></li>
    </ul>
    <p>Refer to Rust's <a
    href="https://doc.rust-lang.org/rustc/platform-support.html";>platform
    support page</a> for more information on Rust's tiered platform
    support.</p>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Libraries</h2>
    <ul>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/146561";>Change
    <code>Location&lt;'_&gt;</code> lifetime to <code>'static</code> in
    <code>Panic[Hook]Info</code></a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155421";>Document
    panic in
    <code>RangeInclusive::from(legacy::RangeInclusive)</code></a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155750";>Document
    that <code>ManuallyDrop</code>'s <code>Box</code> interaction has been
    fixed</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/issues/156908";>Stabilize
    LoongArch CRC Intrinsics</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/issues/154645";>The
    <code>derive</code> macro is available at
    <code>{core,std}::derive</code>.</a> This was previously <a
    
href="https://redirect.github.com/rust-lang/rust/issues/159856";>unintentionally
    stabilized in 1.96</a>, but is now <a
    href="https://redirect.github.com/rust-lang/rust/issues/154645";>explicitly
    accepted</a> as a stabilized API.
    <ul>
    <li>Please note that the MSRV for <code>{core,std}::derive</code> will
    be 1.96, and not 1.98.</li>
    </ul>
    </li>
    </ul>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Stabilized APIs</h2>
    <ul>
    <li><a
    
href="https://doc.rust-lang.org/stable/std/primitive.str.html#method.substr_range";><code>str::substr_range</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/std/primitive.slice.html#method.subslice_range";><code>[T]::subslice_range</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/fmt/struct.NumBuffer.html";><code>core::fmt::NumBuffer</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/primitive.usize.html#method.format_into";><code>&lt;{integer}&gt;::format_into</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/std/process/struct.CommandArgs.html#impl-Send-for-CommandArgs%3C&#x27;a%3E";><code>Send/Sync
    for std::process::CommandArgs</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/primitive.f32.html#method.algebraic_add";><code>{fN}::algebraic_add</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/primitive.f32.html#method.algebraic_sub";><code>{fN}::algebraic_sub</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/primitive.f32.html#method.algebraic_mul";><code>{fN}::algebraic_mul</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/primitive.f32.html#method.algebraic_div";><code>{fN}::algebraic_div</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/primitive.f32.html#method.algebraic_rem";><code>{fN}::algebraic_rem</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/core/num/struct.NonZero.html#method.from_str_radix-4";><code>NonZero&lt;{integer}&gt;::from_str_radix</code></a></li>
    </ul>
    <!-- raw HTML omitted -->
    </blockquote>
    <p>... (truncated)</p>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    
href="https://github.com/rust-lang/rust/blob/main/RELEASES.md";>rust-toolchain's
    changelog</a>.</em></p>
    <blockquote>
    <h1>Version 1.98.0 (2026-08-20)</h1>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Language</h2>
    <ul>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/149219";>Allow
    shortening lifetime of <code>&amp;mut</code> when unsize-coercing, even
    in an invariant position.</a> For example, you can now coerce a
    <code>Cell&lt;&amp;'long mut i32&gt;</code> to a
    <code>Cell&lt;&amp;'short mut dyn Send&gt;</code>. Such shortenings were
    already previously allowed when coercing a <code>&amp;mut</code> to a
    <code>&amp;</code>, or coercing a <code>&amp;</code> to a
    <code>&amp;</code>.</li>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/155521";>Add
    deny-by-default <code>invalid_runtime_symbol_definitions</code> lint and
    warn-by-default <code>suspicious_runtime_symbol_definitions</code>
    lint</a>
    <ul>
    <li>The lints currently specifically targets <code>core</code> runtime
    symbols like <code>memcmp</code>, <code>memset</code>,
    <code>strlen</code>, ... and is planned to be expanded in the next few
    releases.</li>
    </ul>
    </li>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/156379";>Add
    warn-by-default <code>c_void_returns</code> lint to check
    <code>core::ffi::c_void</code> as a return type</a></li>
    </ul>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Platform Support</h2>
    <ul>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/144220";>Add
    <code>powerpc64-unknown-linux-gnuelfv2</code> as Tier 3</a></li>
    <li><a href="https://redirect.github.com/rust-lang/rust/pull/155722";>Add
    <code>aarch64-unknown-linux-pauthtest</code> as Tier 3 target</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7a-none-eabi</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7a-none-eabihf</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7r-none-eabi</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv7r-none-eabihf</code> to Tier 2</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155763";>Promote
    <code>thumbv8r-none-eabihf</code> to Tier 2</a></li>
    </ul>
    <p>Refer to Rust's <a
    href="https://doc.rust-lang.org/rustc/platform-support.html";>platform
    support page</a>
    for more information on Rust's tiered platform support.</p>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Libraries</h2>
    <ul>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/146561";>Change
    <code>Location&lt;'_&gt;</code> lifetime to <code>'static</code> in
    <code>Panic[Hook]Info</code></a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155421";>Document
    panic in
    <code>RangeInclusive::from(legacy::RangeInclusive)</code></a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/pull/155750";>Document
    that <code>ManuallyDrop</code>'s <code>Box</code> interaction has been
    fixed</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/issues/156908";>Stabilize
    LoongArch CRC Intrinsics</a></li>
    <li><a
    href="https://redirect.github.com/rust-lang/rust/issues/154645";>The
    <code>derive</code> macro is available at
    <code>{core,std}::derive</code>.</a> This was previously <a
    
href="https://redirect.github.com/rust-lang/rust/issues/159856";>unintentionally
    stabilized in 1.96</a>, but is now <a
    href="https://redirect.github.com/rust-lang/rust/issues/154645";>explicitly
    accepted</a> as a stabilized API.
    <ul>
    <li>Please note that the MSRV for <code>{core,std}::derive</code> will
    be 1.96, and not 1.98.</li>
    </ul>
    </li>
    </ul>
    <p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
    <h2>Stabilized APIs</h2>
    <ul>
    <li><a
    
href="https://doc.rust-lang.org/stable/std/primitive.str.html#method.substr_range";><code>str::substr_range</code></a></li>
    <li><a
    
href="https://doc.rust-lang.org/stable/std/primitive.slice.html#method.subslice_range";><code>[T]::subslice_range</code></a></li>
    </ul>
    <!-- raw HTML omitted -->
    </blockquote>
    <p>... (truncated)</p>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/88d9e12ae178fab0fb5cc050a94da85685d449ea";><code>88d9e12</code></a>
    Auto merge of <a
    href="https://redirect.github.com/rust-lang/rust/issues/161313";>#161313</a>
    - cuviper:stable-next, r=cuviper</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/8f6f43c06e1f0f0d80f2a6616a711ed99a987453";><code>8f6f43c</code></a>
    update relnotes</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/c6d0dd078ec3ac8828f3cd58125a1b1c89066e46";><code>c6d0dd0</code></a>
    Bump stable channel</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/824ef7e4e02b43a361849bf49c58df63bf378891";><code>824ef7e</code></a>
    Revert &quot;riscv: promote d, e, and f target_features to
    CfgStableToggleUnstable&quot;</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/04eb0d7194012623e82369b466d5084522957446";><code>04eb0d7</code></a>
    Auto merge of <a
    href="https://redirect.github.com/rust-lang/rust/issues/161039";>#161039</a>
    - flip1995:clippy-beta-backport, r=Mark-Simulacrum</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/6cc28588ea61d68cc901e5c8257c0926a5832b27";><code>6cc2858</code></a>
    Fix ICE when resolving local in
    <code>unnecessary_unwrap_unchecked</code> (<a
    
href="https://redirect.github.com/rust-lang/rust/issues/17353";>#17353</a>)</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/d440739bfd7b68ca41f4b028ba3502901a35b97f";><code>d440739</code></a>
    <code>unnecessary_unwrap_unchecked</code>: don't trigger inside the
    <code>_unchecked</code> fn (<a
    href="https://redirect.github.com/rust-lang/rust/issues/17";>#17</a>...</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/e1114a15d06a78347870c2291ed20480a8b1008b";><code>e1114a1</code></a>
    Auto merge of <a
    href="https://redirect.github.com/rust-lang/rust/issues/160714";>#160714</a>
    - cuviper:beta-next, r=cuviper</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/ebcacaa7ae16f0766782ec8e9db3e1eda8bd7627";><code>ebcacaa</code></a>
    [beta-1.98] Update cargo submodule</li>
    <li><a
    
href="https://github.com/rust-lang/rust/commit/33c0be17df8184eb540e2b387b1dc8a7feb04800";><code>33c0be1</code></a>
    Update attr name for <code>#[unroll]</code> in Unstable Book</li>
    <li>Additional commits viewable in <a
    href="https://github.com/rust-lang/rust/compare/1.97.1...1.98.0";>compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    ---------
    
    Signed-off-by: dependabot[bot] <[email protected]>
    Co-authored-by: dependabot[bot] 
<49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Jefffrey <[email protected]>
---
 Cargo.toml                                         |  1 -
 arrow-arith/src/aggregate.rs                       | 24 +++++++----------
 arrow-array/src/array/union_array.rs               | 11 +++-----
 arrow-avro/src/reader/header.rs                    |  2 +-
 arrow-buffer/src/buffer/boolean.rs                 | 31 +++++++++++-----------
 arrow-buffer/src/buffer/mutable.rs                 |  2 +-
 arrow-data/src/data.rs                             |  2 +-
 arrow-flight/src/sql/client.rs                     |  1 +
 arrow-json/src/reader/binary_array.rs              |  5 ++--
 arrow-row/src/lib.rs                               |  1 -
 arrow-row/src/variable.rs                          |  9 ++++---
 arrow-select/src/interleave.rs                     |  3 +--
 arrow-select/src/union_extract.rs                  | 15 ++++-------
 .../src/arrow/record_reader/definition_levels.rs   | 10 +++----
 parquet/src/bloom_filter/mod.rs                    |  4 ++-
 parquet/src/encodings/decoding/alp_decoder.rs      | 23 +++++++++++-----
 parquet/src/encodings/encoding/alp_encoder.rs      |  6 ++---
 parquet/src/encodings/rle.rs                       | 12 +++------
 parquet/src/file/metadata/mod.rs                   |  4 +--
 parquet/src/util/prefix.rs                         |  7 ++++-
 rust-toolchain.toml                                |  2 +-
 21 files changed, 86 insertions(+), 89 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index db88598802..8e7f63cda4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -229,7 +229,6 @@ default_trait_access = "allow"               # ~210 
violations in ~68 files
 doc_markdown = "allow"                       # ~2300 violations in ~290 files
 enum_glob_use = "allow"                      # ~65 violations in ~22 files
 float_cmp = "allow"                          # ~180 violations in ~2 files
-from_iter_instead_of_collect = "allow"       # ~200 violations in ~53 files
 if_not_else = "allow"                        # ~57 violations in ~39 files
 ignore_without_reason = "allow"              # ~16 violations in ~2 files
 implicit_hasher = "allow"                    # ~9 violations in ~4 files
diff --git a/arrow-arith/src/aggregate.rs b/arrow-arith/src/aggregate.rs
index 006a8deea0..d059f2b287 100644
--- a/arrow-arith/src/aggregate.rs
+++ b/arrow-arith/src/aggregate.rs
@@ -23,7 +23,6 @@ use arrow_array::*;
 use arrow_buffer::NullBuffer;
 use arrow_data::bit_iterator::try_for_each_valid_idx;
 use arrow_schema::*;
-use std::borrow::BorrowMut;
 use std::cmp::{self, Ordering};
 use std::ops::{BitAnd, BitOr, BitXor};
 use types::ByteViewType;
@@ -237,12 +236,11 @@ fn aggregate_nonnull_lanes<T: ArrowNativeTypeOp, A: 
NumericAccumulator<T>, const
     // aggregating into multiple independent accumulators allows the compiler 
to use vector registers
     // with a single accumulator the compiler would not be allowed to reorder 
floating point addition
     let mut acc = [A::default(); LANES];
-    let mut chunks = values.chunks_exact(LANES);
-    chunks.borrow_mut().for_each(|chunk| {
-        aggregate_nonnull_chunk(&mut acc, chunk[..LANES].try_into().unwrap());
+    let (chunks, remainder) = values.as_chunks::<LANES>();
+    chunks.iter().for_each(|chunk| {
+        aggregate_nonnull_chunk(&mut acc, chunk);
     });
 
-    let remainder = chunks.remainder();
     for i in 0..remainder.len() {
         acc[i].accumulate(remainder[i]);
     }
@@ -261,31 +259,29 @@ fn aggregate_nullable_lanes<T: ArrowNativeTypeOp, A: 
NumericAccumulator<T>, cons
     // aggregating into multiple independent accumulators allows the compiler 
to use vector registers
     let mut acc = [A::default(); LANES];
     // we process 64 bits of validity at a time
-    let mut values_chunks = values.chunks_exact(64);
+    let (values_chunks, remainder) = values.as_chunks::<64>();
     let validity_chunks = validity.inner().bit_chunks();
     let mut validity_chunks_iter = validity_chunks.iter();
 
-    values_chunks.borrow_mut().for_each(|chunk| {
+    values_chunks.iter().for_each(|chunk| {
         // Safety: we asserted that values and validity have the same length 
and trust the iterator impl
         let mut validity = unsafe { 
validity_chunks_iter.next().unwrap_unchecked() };
         // chunk further based on the number of vector lanes
-        chunk.chunks_exact(LANES).for_each(|chunk| {
-            aggregate_nullable_chunk(&mut acc, 
chunk[..LANES].try_into().unwrap(), validity);
+        chunk.as_chunks::<LANES>().0.iter().for_each(|chunk| {
+            aggregate_nullable_chunk(&mut acc, chunk, validity);
             validity >>= LANES;
         });
     });
 
-    let remainder = values_chunks.remainder();
     if !remainder.is_empty() {
         let mut validity = validity_chunks.remainder_bits();
 
-        let mut remainder_chunks = remainder.chunks_exact(LANES);
-        remainder_chunks.borrow_mut().for_each(|chunk| {
-            aggregate_nullable_chunk(&mut acc, 
chunk[..LANES].try_into().unwrap(), validity);
+        let (remainder_chunks, remainder) = remainder.as_chunks::<LANES>();
+        remainder_chunks.iter().for_each(|chunk| {
+            aggregate_nullable_chunk(&mut acc, chunk, validity);
             validity >>= LANES;
         });
 
-        let remainder = remainder_chunks.remainder();
         if !remainder.is_empty() {
             let mut bit = 1;
             for i in 0..remainder.len() {
diff --git a/arrow-array/src/array/union_array.rs 
b/arrow-array/src/array/union_array.rs
index 8ade858a56..1a4d2c6654 100644
--- a/arrow-array/src/array/union_array.rs
+++ b/arrow-array/src/array/union_array.rs
@@ -585,14 +585,11 @@ impl UnionArray {
             .map(|(type_id, bit_chunks)| (*type_id, bit_chunks.iter()))
             .collect::<Vec<_>>();
 
-        let chunks_exact = self.type_ids.chunks_exact(64);
-        let remainder = chunks_exact.remainder();
+        let (chunks_exact, remainder) = self.type_ids.as_chunks::<64>();
 
-        let chunks = chunks_exact.map(|type_ids_chunk| {
-            let type_ids_chunk_array = <&[i8; 
64]>::try_from(type_ids_chunk).unwrap();
-
-            mask_chunk(type_ids_chunk_array, &mut nulls_masks_iter)
-        });
+        let chunks = chunks_exact
+            .iter()
+            .map(|type_ids_chunk| mask_chunk(type_ids_chunk, &mut 
nulls_masks_iter));
 
         // SAFETY:
         // chunks is a ChunksExact iterator, which implements TrustedLen, and 
correctly reports its length
diff --git a/arrow-avro/src/reader/header.rs b/arrow-avro/src/reader/header.rs
index 6b77fe474a..5638ee76a4 100644
--- a/arrow-avro/src/reader/header.rs
+++ b/arrow-avro/src/reader/header.rs
@@ -84,7 +84,7 @@ impl Header {
     /// Returns an iterator over the meta keys in this header
     pub fn metadata(&self) -> impl Iterator<Item = (&[u8], &[u8])> {
         let mut last = 0;
-        self.meta_offsets.chunks_exact(2).map(move |w| {
+        self.meta_offsets.as_chunks::<2>().0.iter().map(move |w| {
             let start = last;
             last = w[1];
             (&self.meta_buf[start..w[0]], &self.meta_buf[w[0]..w[1]])
diff --git a/arrow-buffer/src/buffer/boolean.rs 
b/arrow-buffer/src/buffer/boolean.rs
index 677a2da55b..2f22c0ac26 100644
--- a/arrow-buffer/src/buffer/boolean.rs
+++ b/arrow-buffer/src/buffer/boolean.rs
@@ -267,9 +267,8 @@ impl BooleanBuffer {
 
         // align to byte boundaries
         // Use unaligned code path, handle remainder bytes
-        let chunks = aligned_start.chunks_exact(8);
-        let remainder = chunks.remainder();
-        let iter = chunks.map(|c| u64::from_le_bytes(c.try_into().unwrap()));
+        let (chunks, remainder) = aligned_start.as_chunks::<8>();
+        let iter = chunks.iter().map(|c| u64::from_le_bytes(*c));
         let vec_u64s: Vec<u64> = if remainder.is_empty() {
             iter.map(&mut op).collect()
         } else {
@@ -390,13 +389,11 @@ impl BooleanBuffer {
             }
 
             // Memory not u64-aligned, use chunks_exact fallback
-            let left_chunks = left_slice.chunks_exact(8);
-            let left_rem = left_chunks.remainder();
-            let right_chunks = right_slice.chunks_exact(8);
-            let right_rem = right_chunks.remainder();
+            let (left_chunks, left_rem) = left_slice.as_chunks::<8>();
+            let (right_chunks, right_rem) = right_slice.as_chunks::<8>();
 
-            let left_iter = left_chunks.map(|c| 
u64::from_le_bytes(c.try_into().unwrap()));
-            let right_iter = right_chunks.map(|c| 
u64::from_le_bytes(c.try_into().unwrap()));
+            let left_iter = left_chunks.iter().map(|c| u64::from_le_bytes(*c));
+            let right_iter = right_chunks.iter().map(|c| 
u64::from_le_bytes(*c));
 
             let result_u64s: Vec<u64> = if left_rem.is_empty() && 
right_rem.is_empty() {
                 left_iter.zip(right_iter).map(|(l, r)| op(l, r)).collect()
@@ -650,10 +647,12 @@ impl BooleanBuffer {
     pub fn has_true(&self) -> bool {
         let bit_chunks = self.unaligned_bit_chunks();
         let chunks = bit_chunks.chunks();
-        let mut exact = chunks.chunks_exact(Self::CHUNK_FOLD_BLOCK_SIZE);
+        let (exact, remainder) = chunks.as_chunks::<{ 
Self::CHUNK_FOLD_BLOCK_SIZE }>();
         let found = bit_chunks.prefix().unwrap_or(0) != 0
-            || exact.any(|block| block.iter().fold(0u64, |acc, &c| acc | c) != 
0);
-        found || exact.remainder().iter().any(|&c| c != 0) || 
bit_chunks.suffix().unwrap_or(0) != 0
+            || exact
+                .iter()
+                .any(|block| block.iter().fold(0u64, |acc, &c| acc | c) != 0);
+        found || remainder.iter().any(|&c| c != 0) || 
bit_chunks.suffix().unwrap_or(0) != 0
     }
 
     /// Returns whether there is at least one `false` value in this buffer.
@@ -679,13 +678,15 @@ impl BooleanBuffer {
             (None, None) => (0, 0),
         };
         let chunks = bit_chunks.chunks();
-        let mut exact = chunks.chunks_exact(Self::CHUNK_FOLD_BLOCK_SIZE);
+        let (exact, remainder) = chunks.as_chunks::<{ 
Self::CHUNK_FOLD_BLOCK_SIZE }>();
         let found = bit_chunks
             .prefix()
             .is_some_and(|v| (v | prefix_fill) != u64::MAX)
-            || exact.any(|block| block.iter().fold(u64::MAX, |acc, &c| acc & 
c) != u64::MAX);
+            || exact
+                .iter()
+                .any(|block| block.iter().fold(u64::MAX, |acc, &c| acc & c) != 
u64::MAX);
         found
-            || exact.remainder().iter().any(|&c| c != u64::MAX)
+            || remainder.iter().any(|&c| c != u64::MAX)
             || bit_chunks
                 .suffix()
                 .is_some_and(|v| (v | suffix_fill) != u64::MAX)
diff --git a/arrow-buffer/src/buffer/mutable.rs 
b/arrow-buffer/src/buffer/mutable.rs
index 610d9a738b..fc641009ae 100644
--- a/arrow-buffer/src/buffer/mutable.rs
+++ b/arrow-buffer/src/buffer/mutable.rs
@@ -889,7 +889,7 @@ impl MutableBuffer {
 
             let words_start = bit_idx / 8;
             let words_end = words_start + chunks * 8;
-            for dst in slice[words_start..words_end].chunks_exact_mut(8) {
+            for dst in slice[words_start..words_end].as_chunks_mut::<8>().0 {
                 let mut packed: u64 = 0;
                 for i in 0..64 {
                     packed |= (iter.next().unwrap() as u64) << i;
diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs
index 4c76842111..5f68e6548f 100644
--- a/arrow-data/src/data.rs
+++ b/arrow-data/src/data.rs
@@ -3095,7 +3095,7 @@ mod tests {
 
         assert_eq!(
             res.to_string(),
-            format!("Invalid argument error: Last offset 2 of Utf8 is larger 
than values length 0",)
+            "Invalid argument error: Last offset 2 of Utf8 is larger than 
values length 0"
         );
     }
 
diff --git a/arrow-flight/src/sql/client.rs b/arrow-flight/src/sql/client.rs
index e00f7254a3..5b283286ac 100644
--- a/arrow-flight/src/sql/client.rs
+++ b/arrow-flight/src/sql/client.rs
@@ -458,6 +458,7 @@ where
     /// Explicitly shut down and clean up the client.
     #[expect(
         clippy::unused_async,
+        clippy::unused_async_trait_impl,
         reason = "public API: dropping `async` would break callers that 
`.await` it"
     )]
     pub async fn close(&mut self) -> Result<()> {
diff --git a/arrow-json/src/reader/binary_array.rs 
b/arrow-json/src/reader/binary_array.rs
index 7f0d5219e2..1cae913ce6 100644
--- a/arrow-json/src/reader/binary_array.rs
+++ b/arrow-json/src/reader/binary_array.rs
@@ -44,11 +44,11 @@ fn invalid_hex_error_at(index: usize, byte: u8) -> 
ArrowError {
 
 fn decode_hex_to_writer<W: Write>(hex_string: &str, writer: &mut W) -> 
Result<(), ArrowError> {
     let bytes = hex_string.as_bytes();
-    let mut iter = bytes.chunks_exact(2);
+    let (iter, remainder) = bytes.as_chunks::<2>();
     let mut buffer = [0u8; 64];
     let mut buffered = 0;
 
-    for (pair_index, pair) in (&mut iter).enumerate() {
+    for (pair_index, pair) in iter.iter().enumerate() {
         let base = pair_index * 2;
         let high = decode_hex_digit(pair[0]).ok_or_else(|| 
invalid_hex_error_at(base, pair[0]))?;
         let low =
@@ -64,7 +64,6 @@ fn decode_hex_to_writer<W: Write>(hex_string: &str, writer: 
&mut W) -> Result<()
         }
     }
 
-    let remainder = iter.remainder();
     if !remainder.is_empty() {
         let index = (bytes.len() / 2) * 2;
         let low = decode_hex_digit(remainder[0])
diff --git a/arrow-row/src/lib.rs b/arrow-row/src/lib.rs
index 628891f09e..d9c0438315 100644
--- a/arrow-row/src/lib.rs
+++ b/arrow-row/src/lib.rs
@@ -2434,7 +2434,6 @@ unsafe fn decode_column(
 mod tests {
     use arrow_array::builder::*;
     use arrow_array::types::*;
-    use arrow_array::*;
     use arrow_buffer::{Buffer, OffsetBuffer};
     use arrow_buffer::{NullBuffer, i256};
     use arrow_cast::display::{ArrayFormatter, FormatOptions};
diff --git a/arrow-row/src/variable.rs b/arrow-row/src/variable.rs
index 6e19044aef..2f0e5f2c35 100644
--- a/arrow-row/src/variable.rs
+++ b/arrow-row/src/variable.rs
@@ -203,10 +203,11 @@ fn encode_blocks<const SIZE: usize>(out: &mut [u8], val: 
&[u8]) -> usize {
     let end_offset = block_count * (SIZE + 1);
     let to_write = &mut out[..end_offset];
 
-    let chunks = val.chunks_exact(SIZE);
-    let remainder = chunks.remainder();
-    for (input, output) in chunks.clone().zip(to_write.chunks_exact_mut(SIZE + 
1)) {
-        let input: &[u8; SIZE] = input.try_into().unwrap();
+    let (chunks, remainder) = val.as_chunks::<SIZE>();
+    #[expect(clippy::chunks_exact_to_as_chunks)]
+    // Requires using generic parameters in const operations: 
generic_const_exprs
+    let to_write_chunks = to_write.chunks_exact_mut(SIZE + 1);
+    for (input, output) in chunks.iter().zip(to_write_chunks) {
         let out_block: &mut [u8; SIZE] = (&mut 
output[..SIZE]).try_into().unwrap();
 
         *out_block = *input;
diff --git a/arrow-select/src/interleave.rs b/arrow-select/src/interleave.rs
index 3d8aaeccdc..2c476738c1 100644
--- a/arrow-select/src/interleave.rs
+++ b/arrow-select/src/interleave.rs
@@ -176,8 +176,7 @@ fn interleave_primitive<T: ArrowPrimitiveType>(
 
     // Process 8 elements at a time to issue multiple independent loads
     // and increase memory-level parallelism for random access patterns.
-    let chunks = indices.chunks_exact(8);
-    let remainder = chunks.remainder();
+    let (chunks, remainder) = indices.as_chunks::<8>();
     for chunk in chunks {
         let v0 = arrays[chunk[0].0].value(chunk[0].1);
         let v1 = arrays[chunk[1].0].value(chunk[1].1);
diff --git a/arrow-select/src/union_extract.rs 
b/arrow-select/src/union_extract.rs
index 2e697f32c5..bc2b8d65c0 100644
--- a/arrow-select/src/union_extract.rs
+++ b/arrow-select/src/union_extract.rs
@@ -403,22 +403,17 @@ fn is_sequential_generic<const N: usize>(offsets: &[i32]) 
-> bool {
         return false;
     }
 
-    let chunks = offsets.chunks_exact(N);
-
-    let remainder = chunks.remainder();
-
-    chunks.enumerate().all(|(i, chunk)| {
-        let chunk_array = <&[i32; N]>::try_from(chunk).unwrap();
-
+    let (chunks, remainder) = offsets.as_chunks::<N>();
+    chunks.iter().enumerate().all(|(i, chunk)| {
         //checks if values within chunk are sequential
-        chunk_array
+        chunk
             .iter()
             .copied()
             .enumerate()
             .fold(true, |acc, (i, offset)| {
-                acc & (offset == chunk_array[0] + i as i32)
+                acc & (offset == chunk[0] + i as i32)
             })
-            && offsets[0] + (i * N) as i32 == chunk_array[0] //checks if chunk 
is sequential relative to the first offset
+            && offsets[0] + (i * N) as i32 == chunk[0] //checks if chunk is 
sequential relative to the first offset
     }) && remainder
         .iter()
         .copied()
diff --git a/parquet/src/arrow/record_reader/definition_levels.rs 
b/parquet/src/arrow/record_reader/definition_levels.rs
index d9d737177e..3d1f9a5e76 100644
--- a/parquet/src/arrow/record_reader/definition_levels.rs
+++ b/parquet/src/arrow/record_reader/definition_levels.rs
@@ -145,10 +145,10 @@ pub(crate) fn build_filtered_validity_bitmap(
     value_level: i16,
     bitmap: &mut BooleanBufferBuilder,
 ) -> usize {
+    const CHUNKS: usize = u64::BITS as usize;
     // Fast path: no filtering — every def level produces a bit.
     if include_threshold.is_none() && rep_filter.is_none() {
-        let chunks = def_levels.chunks_exact(u64::BITS as usize);
-        let remainder = chunks.remainder();
+        let (chunks, remainder) = def_levels.as_chunks::<CHUNKS>();
         for chunk in chunks {
             let mut word: u64 = 0;
             for (i, &d) in chunk.iter().enumerate() {
@@ -164,10 +164,10 @@ pub(crate) fn build_filtered_validity_bitmap(
 
     // Filtered path: build include mask + value mask per chunk, compress.
     let mut item_count: usize = 0;
-    let chunks = def_levels.chunks_exact(u64::BITS as usize);
-    let remainder_offset = def_levels.len() - chunks.remainder().len();
+    let (chunks, remainder) = def_levels.as_chunks::<CHUNKS>();
+    let remainder_offset = def_levels.len() - remainder.len();
 
-    for (chunk_idx, chunk) in chunks.enumerate() {
+    for (chunk_idx, chunk) in chunks.iter().enumerate() {
         let base = chunk_idx * u64::BITS as usize;
         let mut include_mask: u64 = 0;
         let mut value_mask: u64 = 0;
diff --git a/parquet/src/bloom_filter/mod.rs b/parquet/src/bloom_filter/mod.rs
index 9b6966728a..e66d1bbcfa 100644
--- a/parquet/src/bloom_filter/mod.rs
+++ b/parquet/src/bloom_filter/mod.rs
@@ -402,7 +402,9 @@ impl Sbbf {
     /// Creates a new [Sbbf] from a raw byte slice.
     pub fn new(bitset: &[u8]) -> Self {
         let data = bitset
-            .chunks_exact(4 * 8)
+            .as_chunks::<32>()
+            .0
+            .iter()
             .map(|chunk| {
                 let mut block = Block::ZERO;
                 let (words, _remainder) = chunk.as_chunks::<4>();
diff --git a/parquet/src/encodings/decoding/alp_decoder.rs 
b/parquet/src/encodings/decoding/alp_decoder.rs
index 0fb44ffc34..3847a57542 100644
--- a/parquet/src/encodings/decoding/alp_decoder.rs
+++ b/parquet/src/encodings/decoding/alp_decoder.rs
@@ -224,7 +224,7 @@ fn parse_vector_view<Exact: AlpExact>(
     // Validate exception positions without materializing them. They are 
decoded
     // straight from the body when the vector is decoded; here we only enforce
     // that every position is in range so the whole page is validated up front.
-    for chunk in data[positions_start..values_start].chunks_exact(2) {
+    for chunk in data[positions_start..values_start].as_chunks::<2>().0 {
         let position = u16::from_le_bytes([chunk[0], chunk[1]]);
         if position >= num_elements {
             return Err(general_err!(
@@ -338,10 +338,15 @@ fn decode_range<Value: AlpFloat>(
         cur.exception_positions.len() / std::mem::size_of::<u16>(),
         cur.exception_values.len() / Value::Exact::WIDTH,
     );
+    #[expect(clippy::chunks_exact_to_as_chunks)]
+    // Requires using generic parameters in const operations: 
generic_const_exprs
+    let values_chunks = cur.exception_values.chunks_exact(Value::Exact::WIDTH);
     for (pos_chunk, value_chunk) in cur
         .exception_positions
-        .chunks_exact(std::mem::size_of::<u16>())
-        .zip(cur.exception_values.chunks_exact(Value::Exact::WIDTH))
+        .as_chunks::<{ std::mem::size_of::<u16>() }>()
+        .0
+        .iter()
+        .zip(values_chunks)
     {
         let pos = u16::from_le_bytes([pos_chunk[0], pos_chunk[1]]) as usize;
         if (lo..hi).contains(&pos) {
@@ -1129,12 +1134,16 @@ mod tests {
         assert_eq!(view.for_info.bit_width, 0);
 
         let positions: Vec<u16> = body[view.exception_positions_range()]
-            .chunks_exact(2)
-            .map(|c| u16::from_le_bytes([c[0], c[1]]))
+            .as_chunks::<2>()
+            .0
+            .iter()
+            .map(|c| u16::from_le_bytes(*c))
             .collect();
         let values: Vec<u64> = body[view.exception_values_range()]
-            .chunks_exact(8)
-            .map(|c| u64::from_le_bytes(c.try_into().unwrap()))
+            .as_chunks::<8>()
+            .0
+            .iter()
+            .map(|c| u64::from_le_bytes(*c))
             .collect();
         assert_eq!(positions, vec![0]);
         assert_eq!(values, vec![42.5_f64.to_bits()]);
diff --git a/parquet/src/encodings/encoding/alp_encoder.rs 
b/parquet/src/encodings/encoding/alp_encoder.rs
index aa8682d981..0a6be5dfb1 100644
--- a/parquet/src/encodings/encoding/alp_encoder.rs
+++ b/parquet/src/encodings/encoding/alp_encoder.rs
@@ -543,11 +543,11 @@ impl<F: AlpFloat> StreamingPage<F> {
         }
 
         // Encode whole vectors straight from the input, no copy.
-        let mut chunks = values.chunks_exact(VECTOR_SIZE);
-        for vector in chunks.by_ref() {
+        let (chunks, remainder) = values.as_chunks::<VECTOR_SIZE>();
+        for vector in chunks {
             self.push_vector(vector, preset, scratch)?;
         }
-        self.carry.extend_from_slice(chunks.remainder());
+        self.carry.extend_from_slice(remainder);
         Ok(())
     }
 
diff --git a/parquet/src/encodings/rle.rs b/parquet/src/encodings/rle.rs
index 68de2487fd..e4673a3c6c 100644
--- a/parquet/src/encodings/rle.rs
+++ b/parquet/src/encodings/rle.rs
@@ -575,9 +575,9 @@ impl RleDecoder {
                         let out = &mut buffer[values_read..values_read + 
num_values];
                         let idx = &index_buf[..num_values];
                         let dict_len = dict.len();
-                        let mut out_chunks = out.chunks_exact_mut(CHUNK);
-                        let idx_chunks = idx.chunks_exact(CHUNK);
-                        for (out_chunk, idx_chunk) in 
out_chunks.by_ref().zip(idx_chunks) {
+                        let (out_chunks, out_chunks_remainder) = 
out.as_chunks_mut::<CHUNK>();
+                        let (idx_chunks, idx_chunks_remainder) = 
idx.as_chunks::<CHUNK>();
+                        for (out_chunk, idx_chunk) in 
out_chunks.iter_mut().zip(idx_chunks) {
                             // u32 max-reduction instead of `.all(|&i| ..)`: 
`.all`
                             // short-circuits and blocks autovectorisation. 
Negative
                             // i32 cast to u32 becomes a large value so the 
bounds
@@ -591,11 +591,7 @@ impl RleDecoder {
                                 b.clone_from(unsafe { dict.get_unchecked(*i as 
usize) });
                             }
                         }
-                        for (b, i) in out_chunks
-                            .into_remainder()
-                            .iter_mut()
-                            .zip(idx.chunks_exact(CHUNK).remainder().iter())
-                        {
+                        for (b, i) in 
out_chunks_remainder.iter_mut().zip(idx_chunks_remainder) {
                             let dict_idx = *i as usize;
                             if dict_idx >= dict_len {
                                 return Err(oob(*i as u32, dict_len));
diff --git a/parquet/src/file/metadata/mod.rs b/parquet/src/file/metadata/mod.rs
index f81ae4fb35..6318497b32 100644
--- a/parquet/src/file/metadata/mod.rs
+++ b/parquet/src/file/metadata/mod.rs
@@ -1106,9 +1106,7 @@ impl LevelHistogram {
 
     /// Sets the values of all histogram levels to 0.
     pub fn reset(&mut self) {
-        for value in &mut self.inner {
-            *value = 0;
-        }
+        self.inner.fill(0);
     }
 
     /// Increments the count for a level value by `count`.
diff --git a/parquet/src/util/prefix.rs b/parquet/src/util/prefix.rs
index 696c12910e..927f073b15 100644
--- a/parquet/src/util/prefix.rs
+++ b/parquet/src/util/prefix.rs
@@ -40,7 +40,12 @@ pub(crate) fn common_prefix_length(a: &[u8], b: &[u8]) -> 
usize {
     let (a, b) = (&a[..n], &b[..n]);
 
     let mut matched = 0;
-    for (x, y) in a.chunks_exact(BLOCK).zip(b.chunks_exact(BLOCK)) {
+    for (x, y) in a
+        .as_chunks::<BLOCK>()
+        .0
+        .iter()
+        .zip(b.as_chunks::<BLOCK>().0)
+    {
         if x != y {
             break;
         }
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index d84c4a2680..daca2b13f3 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -16,5 +16,5 @@
 # under the License.
 
 [toolchain]
-channel = "1.97.1"
+channel = "1.98.1"
 components = ["rustfmt", "clippy"]

Reply via email to