diff --git a/.github/workflows/crates.yml b/.github/workflows/crates.yml index 9fc3d00d2e..0471bf5958 100644 --- a/.github/workflows/crates.yml +++ b/.github/workflows/crates.yml @@ -160,11 +160,13 @@ jobs: with: save-if: ${{ github.ref == 'refs/heads/main' }} + # Advisory only (no -D warnings) — the enforced gate lives in lint.yml. - run: rustup component add clippy && cargo clippy --all-targets - name: clippy (bench-suite feature) run: cargo clippy -p tract-cli --features bench-suite - name: test (bench-suite feature) run: cargo test -p tract-cli --features bench-suite --bin tract bench_ + # Enforced fmt check also runs in lint.yml; kept here too for this job's own gating. - name: fmt run: rustup component add rustfmt --toolchain stable && cargo +stable fmt --check - name: Warnings diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000000..631dc0c7bd --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,55 @@ +name: lint + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: lint-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_INCREMENTAL: false + CARGO_NET_RETRY: 10 + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + # `rustup show` installs and activates whatever `rust-toolchain.toml` + # pins, so the version lives in exactly ONE place. This is also the + # repo's own idiom — the other workflows drive rustup directly rather + # than through a third-party toolchain action. + - name: Setup rust toolchain (pinned by rust-toolchain.toml) + run: | + rustup show + rustup component add rustfmt + + - run: cargo fmt --all --check + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup rust toolchain (pinned by rust-toolchain.toml) + run: | + rustup show + rustup component add clippy + + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + save-if: ${{ github.ref == 'refs/heads/main' }} + + - run: cargo clippy --all-targets -- -D warnings diff --git a/Cargo.toml b/Cargo.toml index 8264ba49b3..f01277014e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,7 +124,7 @@ default-members = [ [workspace.package] # MSRV source of truth: CI derives the tested toolchain from this. Keep the # README rustc badge in sync when bumping. -rust-version = "1.97" +rust-version = "1.98" [workspace.dependencies] anstyle = "1.0.2" diff --git a/README.md b/README.md index 655556c04c..4fa5ac421e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![tract-logo](assets/tract-logo/PNG/tract-horizontal-blue.png) ![Rust](https://img.shields.io/badge/rust-%23000000.svg?style=for-the-badge&logo=rust&logoColor=white) -![rustc >= 1.97.0](https://img.shields.io/badge/rustc-%3E%3D1.97.0-brightgreen) +![rustc >= 1.98.0](https://img.shields.io/badge/rustc-%3E%3D1.98.0-brightgreen) ![MIT/Apache 2](https://img.shields.io/crates/l/tract) [![Native Linux test status](https://github.com/sonos/tract/workflows/Native%20Linux/badge.svg)](https://github.com/sonos/tract/actions) [![Embedded targets status](https://github.com/sonos/tract/workflows/Embedded%20targets/badge.svg)](https://github.com/sonos/tract/actions) diff --git a/cli/src/hwbench.rs b/cli/src/hwbench.rs index f899c25143..f0d77db87d 100644 --- a/cli/src/hwbench.rs +++ b/cli/src/hwbench.rs @@ -385,6 +385,10 @@ fn llc_bytes() -> usize { max.unwrap_or(32 * 1024 * 1024) } +// The arguments ARE the benchmarked shape — datum type plus the GEMM's own +// dimensions. Folding them into a parameter struct would name the same eight +// values one indirection away without making any call site clearer. +#[allow(clippy::too_many_arguments)] fn bench_shape( dt: DatumType, m: usize, diff --git a/linalg/src/arm32/mod.rs b/linalg/src/arm32/mod.rs index 9309b5778f..6a4591721c 100644 --- a/linalg/src/arm32/mod.rs +++ b/linalg/src/arm32/mod.rs @@ -47,15 +47,15 @@ fn neon_mmv_f32(suitable: &[Suitable], query: &Query) -> Option<&'static str> { Some(m) if m < 32 => { cortex_a7_mmv_linear::linear_model().preferred(suitable, Some(m), query.k, Some(1)) } - _ => Some(&armv7neon::armv7neon_mmm_f32_32x1_cortexa7.name.as_str()), + _ => Some(armv7neon::armv7neon_mmm_f32_32x1_cortexa7.name.as_str()), }, 0xc09 => match query.m { Some(m) if m < 32 => { cortex_a9_mmv_linear::linear_model().preferred(suitable, Some(m), query.k, Some(1)) } - _ => Some(&armv7neon::armv7neon_mmm_f32_32x1_cortexa9.name.as_str()), + _ => Some(armv7neon::armv7neon_mmm_f32_32x1_cortexa9.name.as_str()), }, - _ => Some(&armv7neon::armv7neon_mmm_f32_32x1_generic.name.as_str()), + _ => Some(armv7neon::armv7neon_mmm_f32_32x1_generic.name.as_str()), } } @@ -80,8 +80,8 @@ fn preferred( match (dt, query.n) { (DatumType::F32, Some(1)) => neon_mmv_f32(suitable, query), (DatumType::F32, _) => neon_mmm_f32(suitable, query), - (DatumType::I32, Some(1)) => Some(&armv7neon::armv7neon_mmm_i32_32x1.name.as_str()), - (DatumType::I32, _) => Some(&armv7neon::armv7neon_mmm_i32_8x4.name.as_str()), + (DatumType::I32, Some(1)) => Some(armv7neon::armv7neon_mmm_i32_32x1.name.as_str()), + (DatumType::I32, _) => Some(armv7neon::armv7neon_mmm_i32_8x4.name.as_str()), _ => None, } } diff --git a/linalg/src/generic/reduce.rs b/linalg/src/generic/reduce.rs index 8843526096..8a2ce184de 100644 --- a/linalg/src/generic/reduce.rs +++ b/linalg/src/generic/reduce.rs @@ -227,8 +227,8 @@ pub mod softmax_l2 { #[inline] fn exp_sum_impl(x: &mut [f32], max: f32) -> f32 { let mut acc = [0f32; 4]; - let mut it = x.chunks_exact_mut(4); - for c in &mut it { + let (chunks, remainder) = x.as_chunks_mut::<4>(); + for c in chunks.iter_mut() { for (j, v) in c.iter_mut().enumerate() { let y = accurate_exp_f32(*v - max); *v = y; @@ -236,7 +236,7 @@ pub mod softmax_l2 { } } let mut sum = (acc[0] + acc[1]) + (acc[2] + acc[3]); - for v in it.into_remainder().iter_mut() { + for v in remainder.iter_mut() { let y = accurate_exp_f32(*v - max); *v = y; sum += y; diff --git a/linalg/src/x86_64/mmm.rs b/linalg/src/x86_64/mmm.rs index 5a9b1a1e41..094cb90039 100644 --- a/linalg/src/x86_64/mmm.rs +++ b/linalg/src/x86_64/mmm.rs @@ -490,7 +490,7 @@ fn avx2_preferred( ) -> Option<&'static str> { match (dt, query.n) { (DatumType::I32, Some(1)) => None, - (DatumType::I32, _) => Some(&mmm::avx2_mmm_i32_8x8.name.as_str()), + (DatumType::I32, _) => Some(mmm::avx2_mmm_i32_8x8.name.as_str()), _ => None, } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 73cb934de4..6990df5a6b 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,7 @@ +# Bump log (append-only): +# - 2026-09-05: pinned to a fixed channel (was floating "stable"), joining +# the workspace-wide Rust toolchain sweep. A future bump edits only the +# `channel` line below — the version lives in exactly one place. [toolchain] -channel = "stable" +channel = "1.98.1" components = ["rustfmt", "clippy"] diff --git a/transformers/src/ops/gdn_recurrent.rs b/transformers/src/ops/gdn_recurrent.rs index 647ab7b8d3..4a84a27475 100644 --- a/transformers/src/ops/gdn_recurrent.rs +++ b/transformers/src/ops/gdn_recurrent.rs @@ -211,6 +211,10 @@ mod tests { use super::*; use crate::ops::test_utils::arb; + // A test helper whose arguments are the layer's own inputs: three shape + // values and the six tensors the operator consumes. Grouping them would + // obscure exactly what each case is feeding in. + #[allow(clippy::too_many_arguments)] fn run( s_len: usize, heads: usize,