Skip to content

Commit 9501793

Browse files
committed
chore(toolchain): bump ndarray to Rust 1.95.0 + manual_checked_ops fix
Aligns ndarray MSRV with the rest of the AdaWorldAPI stack (bevy already on 1.95 for edition 2024, lance-graph bumped in a parallel PR). Single rustc version across {ndarray, bevy, lance-graph, MedCare-rs} — removes the `rustup run 1.95.0 …` vs default-toolchain confusion in local dev and the bevy smoke-test CI. Changes: - `rust-toolchain.toml`: channel 1.94.1 → 1.95.0 - `Cargo.toml`: rust-version "1.94" → "1.95" - `.github/workflows/ci.yaml`: MSRV / BLAS_MSRV env 1.94.0 → 1.95.0; clippy matrix + dtolnay/rust-toolchain pin 1.94.1 → 1.95.0; updated three explanatory comments that referenced the old pin. - `src/impl_owned_array.rs::into_scalar`: fix the ONE 1.95 clippy lint that fires on this codebase — `clippy::manual_checked_ops` wants `checked_div` instead of the manual `if size == 0` + division. The fix is `(first - base).checked_div(size).unwrap_or(0)`; the existing `size == 0` guard above already handles the divisor-is-zero case, so the unwrap is unreachable in practice. Comment explains why. Test surface (post-bump, 1.95.0): cargo test --features rayon --lib: 1788 passed, 36 ignored, 0 failed cargo clippy --features rayon --lib -- -D warnings: clean Signal mining: - New file `.claude/board/UNUSED_INVENTORY_1.95.md` catalogues 36 `#[allow(dead_code|unused)]` suppression sites in the lib. Split into 9 "likely actionable" (A1-A9: stale Rust 1.64 imports, phantom SimdTier variants already flagged by round-1 audit, dead clam code) + 27 "documented scaffolding" (B1-B10: cfg-conditional imports, rayon gates, no_std polyfill helpers, doc-link helpers). Provides a ready-made follow-up backlog without bundling the cleanup into this bump PR. Companion: lance-graph parallel PR bumps to 1.95 the same way.
1 parent 8259600 commit 9501793

5 files changed

Lines changed: 87 additions & 17 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Unused / Allow-suppressed Inventory — 1.95 sweep
2+
3+
> **Captured:** 2026-05-13 while bumping ndarray master to Rust 1.95.0.
4+
> **Source:** `grep -rn "#\[allow(dead_code\|#\[allow(unused" src/` (lib only).
5+
> **Purpose:** signal mining — each entry below is a piece of code that
6+
> compiles but is allowed to be unused. Some are legitimate scaffolding
7+
> (rayon-gated, no_std polyfill, hot-swap reserves), some are actionable
8+
> (Rust-1.64 compatibility imports that 1.95 likely doesn't need, phantom
9+
> tier variants flagged by the round-1 audit fleet).
10+
11+
## Categorization
12+
13+
### A — Likely actionable (real "API drift" candidates)
14+
15+
| # | Site | Suppression | Why interesting |
16+
|---|---|---|---|
17+
| A1 | `src/impl_owned_array.rs:7` | `unused_imports // Needed for Rust 1.64` | We just bumped to 1.95. The 1.64-era workaround is almost certainly stale. **Action:** remove the suppression, see if the import is still needed; if not, drop it. |
18+
| A2 | `src/iterators/mod.rs:24` | `unused_imports // Needed for Rust 1.64` | Same as A1. |
19+
| A3 | `src/hpc/simd_dispatch.rs:47` | `dead_code` on `SimdTier::WasmSimd128` (and likely `Sse2`) | **Flagged by round-1 audit agent #6**: `SimdTier::Sse2` is never selected in `detect()`; no SSE2 wrapper functions exist. Phantom variants. **Action:** delete or wire. |
20+
| A4 | `src/hpc/clam.rs:928` | `dead_code` | CLAM cluster code. **Action:** verify if the suppressed fn is reachable through any public CLAM call path; if not, delete. |
21+
| A5 | `src/hpc/clam_compress.rs:141` | `dead_code` | Same family as A4. |
22+
| A6 | `src/hpc/jitson/scan_config.rs:144` | `dead_code` | jitson scan-config. Probably scaffolding for an unfinished feature; needs PR-author review. |
23+
| A7 | `src/impl_ref_types.rs:364` | `dead_code` | ndarray ref type helper. |
24+
| A8 | `src/backend/native.rs:376`, `:423` | `dead_code` (×2) | Backend kernel helpers possibly only used by feature-gated paths. |
25+
| A9 | `src/hpc/packed.rs:29`, `:42` | `unused_variables` (×2) | Variables defined but unused. Either rename to `_x` for explicit "ignored", or wire them in. |
26+
27+
### B — Documented scaffolding (intentional, leave)
28+
29+
| # | Site | Suppression | Justification |
30+
|---|---|---|---|
31+
| B1 | `src/simd.rs:15,31,48,96,110,126,1612,1658,1672` (×9) | `dead_code` | Tier enum variants for cross-arch builds (only some platforms use all variants) + no_std `LazyLock` polyfill helpers. |
32+
| B2 | `src/split_at.rs:11` | `dead_code // used only when Rayon support is enabled` | Self-documented. |
33+
| B3 | `src/hpc/jitson_cranelift/engine.rs:130` | `dead_code // retained for future hot-swap / eviction by FuncId` | Self-documented. |
34+
| B4 | `src/data_repr.rs:11`, `src/data_traits.rs:11`, `src/impl_constructors.rs:37`, `src/impl_methods.rs:13`, `src/free_functions.rs:13`, `src/impl_views/conversions.rs:10` | `unused_imports` | Conditional-cfg imports needed under some feature combinations. |
35+
| B5 | `src/parallel/mod.rs:120,122` | `unused_imports // used by rustdoc links` | Self-documented. |
36+
| B6 | `src/simd_neon.rs:1721` | `unused_macros` | NEON macros only used on aarch64. |
37+
| B7 | `src/zip/mod.rs:424,715` | `dead_code` / `unused` | Zip iterator scaffolding. |
38+
| B8 | `src/backend/native.rs:20` | `dead_code` | Backend kernel scaffold. |
39+
| B9 | `src/doc/ndarray_for_numpy_users/mod.rs:750` | `unused_imports` | Doc example. |
40+
| B10 | `src/itertools.rs:90` | (inside a doc-comment example) | Not real code. |
41+
42+
## Suggested follow-ups (post-1.95 bump)
43+
44+
- **A1, A2 (Rust 1.64 compat sweep):** remove the suppression, attempt build, drop the import if no longer needed. Likely a 2-line change × 2 files.
45+
- **A3 (phantom SimdTier variants):** the round-1 audit fleet already flagged this. Pair with the round-3 cosmetic-SIMD consumer fleet — they'll touch `simd_dispatch.rs` anyway.
46+
- **A4, A5 (clam dead_code):** needs domain owner review. Worth flagging in a CLAM-related PR; not urgent.
47+
- **A6 (jitson scan_config):** check INTEGRATION_PLANS — if jitson is still active, wire; if archived, delete.
48+
- **A7, A8, A9:** small-scope per-site review; aggregate into a "dead-code cleanup" PR.
49+
50+
## What this PR (1.95 bump) does NOT touch
51+
52+
This file is **signal mining only**. The 1.95 bump PR itself:
53+
- Bumps `rust-toolchain.toml` → 1.95.0
54+
- Bumps `Cargo.toml` `rust-version` → "1.95"
55+
- Bumps `MSRV` / `BLAS_MSRV` env in ci.yaml → 1.95.0
56+
- Fixes the ONE 1.95 clippy lint that fires (`clippy::manual_checked_ops`
57+
in `impl_owned_array.rs::into_scalar`)
58+
59+
The 36 suppression sites are pre-existing and persist after the bump.
60+
Cleaning them up is the follow-up work surfaced by this inventory.

.github/workflows/ci.yaml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ env:
2121
# `LazyLock<Tier>` detection means one binary, all ISAs. Jobs that
2222
# specifically need a higher target-cpu can opt in via per-job env.
2323
RUSTFLAGS: "-D warnings"
24-
MSRV: 1.94.0
25-
BLAS_MSRV: 1.94.0
24+
MSRV: 1.95.0
25+
BLAS_MSRV: 1.95.0
2626

2727
jobs:
2828
pass-msrv:
@@ -41,15 +41,18 @@ jobs:
4141
runs-on: ubuntu-latest
4242
strategy:
4343
matrix:
44-
# Pinned to 1.94.1 to match `rust-toolchain.toml`. Auto-tracking
45-
# `stable` would silently bump to 1.95 and start rejecting code
46-
# on lints like `clippy::unnecessary_sort_by` that 1.94 accepted.
44+
# Pinned to 1.95.0 to match `rust-toolchain.toml`. The workspace
45+
# bumped from 1.94.1 → 1.95.0 in commit
46+
# https://github.com/AdaWorldAPI/ndarray (this PR) to align with
47+
# bevy (edition 2024 → 1.95 MSRV) and lance-graph. 1.95 added the
48+
# `clippy::manual_checked_ops` lint which fires on
49+
# `impl_owned_array.rs::into_scalar` — fixed in this same PR.
4750
rust:
48-
- "1.94.1"
51+
- "1.95.0"
4952
name: clippy/${{ matrix.rust }}
5053
steps:
5154
- uses: actions/checkout@v4
52-
- uses: dtolnay/rust-toolchain@1.94.1
55+
- uses: dtolnay/rust-toolchain@1.95.0
5356
with:
5457
components: clippy
5558
- uses: Swatinem/rust-cache@v2
@@ -77,7 +80,7 @@ jobs:
7780
# The format job MUST use nightly rustfmt for the project's chosen
7881
# style to be enforceable.
7982
#
80-
# The compile + clippy jobs stay on 1.94.1 (pinned in
83+
# The compile + clippy jobs stay on 1.95.0 (pinned in
8184
# `rust-toolchain.toml`) — only this fmt job needs nightly.
8285
- uses: dtolnay/rust-toolchain@nightly
8386
with:
@@ -101,7 +104,7 @@ jobs:
101104
with:
102105
toolchain: ${{ matrix.rust }}
103106
targets: ${{ matrix.target }}
104-
# rust-toolchain.toml pins 1.94.1 — install the cross-compile target
107+
# rust-toolchain.toml pins 1.95.0 — install the cross-compile target
105108
# for that toolchain too, since dtolnay/rust-toolchain only installs
106109
# for the matrix value which may differ from the pinned version.
107110
- run: rustup target add ${{ matrix.target }}

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
name = "ndarray"
44
version = "0.17.2"
55
edition = "2021"
6-
rust-version = "1.94"
6+
rust-version = "1.95"
77
authors = [
88
"Ulrik Sverdrup \"bluss\"",
99
"Jim Turner"

rust-toolchain.toml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
[toolchain]
2-
channel = "1.94.1"
3-
# Pinned to 1.94.1 (latest 1.94 patch, 2026-03-25). 1.95 turned several
4-
# previously-safe patterns into denied lints (e.g. unnecessary_sort_by)
5-
# without sufficient value to justify the churn — bump explicitly when
6-
# a future version is reviewed, never auto-track stable. Mirrors the
7-
# pin in lance-graph, smb-office-rs, and MedCare-rs.
2+
channel = "1.95.0"
3+
# Pinned to 1.95.0 (2026-04-14). Aligns ndarray with the rest of the
4+
# AdaWorldAPI stack: bevy (already on 1.95 for edition 2024) and
5+
# lance-graph (bumped in parallel). 1.95 introduced one new clippy lint
6+
# that fires on this codebase (`clippy::manual_checked_ops` on
7+
# `impl_owned_array.rs::into_scalar`); that's fixed in this same commit.
8+
# Never auto-track `stable` — bump explicitly when a future version is
9+
# reviewed and the workspace clippy passes clean.
810
components = ["clippy", "rustfmt"]

src/impl_owned_array.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@ impl<A> Array<A, Ix0> {
4545
// by `array![1, 2, 3, 4].slice_move(s![2])`.)
4646
let first = self.parts.ptr.as_ptr() as usize;
4747
let base = self.data.as_ptr() as usize;
48-
let index = (first - base) / size;
48+
// Use `checked_div` to satisfy `clippy::manual_checked_ops`
49+
// (new lint in Rust 1.95). The `size == 0` branch above already
50+
// covers the divisor-is-zero case, so the `unwrap_or` is
51+
// unreachable in practice — `0` is the safest fallback if some
52+
// future refactor lets a `size == 0` ZST sneak past the guard.
53+
let index = (first - base).checked_div(size).unwrap_or(0);
4954
debug_assert_eq!((first - base) % size, 0);
5055
// Remove the element at the index and return it.
5156
self.data.into_vec().remove(index)

0 commit comments

Comments
 (0)