Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .claude/board/UNUSED_INVENTORY_1.95.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Unused / Allow-suppressed Inventory — 1.95 sweep

> **Captured:** 2026-05-13 while bumping ndarray master to Rust 1.95.0.
> **Source:** `grep -rn "#\[allow(dead_code\|#\[allow(unused" src/` (lib only).
> **Purpose:** signal mining — each entry below is a piece of code that
> compiles but is allowed to be unused. Some are legitimate scaffolding
> (rayon-gated, no_std polyfill, hot-swap reserves), some are actionable
> (Rust-1.64 compatibility imports that 1.95 likely doesn't need, phantom
> tier variants flagged by the round-1 audit fleet).

## Categorization

### A — Likely actionable (real "API drift" candidates)

| # | Site | Suppression | Why interesting |
|---|---|---|---|
| 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. |
| A2 | `src/iterators/mod.rs:24` | `unused_imports // Needed for Rust 1.64` | Same as A1. |
| 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. |
| 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. |
| A5 | `src/hpc/clam_compress.rs:141` | `dead_code` | Same family as A4. |
| A6 | `src/hpc/jitson/scan_config.rs:144` | `dead_code` | jitson scan-config. Probably scaffolding for an unfinished feature; needs PR-author review. |
| A7 | `src/impl_ref_types.rs:364` | `dead_code` | ndarray ref type helper. |
| A8 | `src/backend/native.rs:376`, `:423` | `dead_code` (×2) | Backend kernel helpers possibly only used by feature-gated paths. |
| 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. |

### B — Documented scaffolding (intentional, leave)

| # | Site | Suppression | Justification |
|---|---|---|---|
| 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. |
| B2 | `src/split_at.rs:11` | `dead_code // used only when Rayon support is enabled` | Self-documented. |
| B3 | `src/hpc/jitson_cranelift/engine.rs:130` | `dead_code // retained for future hot-swap / eviction by FuncId` | Self-documented. |
| 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. |
| B5 | `src/parallel/mod.rs:120,122` | `unused_imports // used by rustdoc links` | Self-documented. |
| B6 | `src/simd_neon.rs:1721` | `unused_macros` | NEON macros only used on aarch64. |
| B7 | `src/zip/mod.rs:424,715` | `dead_code` / `unused` | Zip iterator scaffolding. |
| B8 | `src/backend/native.rs:20` | `dead_code` | Backend kernel scaffold. |
| B9 | `src/doc/ndarray_for_numpy_users/mod.rs:750` | `unused_imports` | Doc example. |
| B10 | `src/itertools.rs:90` | (inside a doc-comment example) | Not real code. |

## Suggested follow-ups (post-1.95 bump)

- **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.
- **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.
- **A4, A5 (clam dead_code):** needs domain owner review. Worth flagging in a CLAM-related PR; not urgent.
- **A6 (jitson scan_config):** check INTEGRATION_PLANS — if jitson is still active, wire; if archived, delete.
- **A7, A8, A9:** small-scope per-site review; aggregate into a "dead-code cleanup" PR.

## What this PR (1.95 bump) does NOT touch

This file is **signal mining only**. The 1.95 bump PR itself:
- Bumps `rust-toolchain.toml` → 1.95.0
- Bumps `Cargo.toml` `rust-version` → "1.95"
- Bumps `MSRV` / `BLAS_MSRV` env in ci.yaml → 1.95.0
- Fixes the ONE 1.95 clippy lint that fires (`clippy::manual_checked_ops`
in `impl_owned_array.rs::into_scalar`)

The 36 suppression sites are pre-existing and persist after the bump.
Cleaning them up is the follow-up work surfaced by this inventory.
54 changes: 26 additions & 28 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ env:
# `LazyLock<Tier>` detection means one binary, all ISAs. Jobs that
# specifically need a higher target-cpu can opt in via per-job env.
RUSTFLAGS: "-D warnings"
MSRV: 1.94.0
BLAS_MSRV: 1.94.0
MSRV: 1.95.0
BLAS_MSRV: 1.95.0

jobs:
pass-msrv:
Expand All @@ -41,15 +41,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
# Pinned to 1.94.1 to match `rust-toolchain.toml`. Auto-tracking
# `stable` would silently bump to 1.95 and start rejecting code
# on lints like `clippy::unnecessary_sort_by` that 1.94 accepted.
# Pinned to 1.95.0 to match `rust-toolchain.toml`. The workspace
# bumped from 1.94.1 → 1.95.0 in commit
# https://github.com/AdaWorldAPI/ndarray (this PR) to align with
# bevy (edition 2024 → 1.95 MSRV) and lance-graph. 1.95 added the
# `clippy::manual_checked_ops` lint which fires on
# `impl_owned_array.rs::into_scalar` — fixed in this same PR.
rust:
- "1.94.1"
- "1.95.0"
name: clippy/${{ matrix.rust }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.94.1
- uses: dtolnay/rust-toolchain@1.95.0
with:
components: clippy
- uses: Swatinem/rust-cache@v2
Expand All @@ -58,28 +61,23 @@ jobs:

format:
runs-on: ubuntu-latest
name: format/nightly
# Marked non-blocking until a separate fmt-sweep PR aligns the
# codebase with `rustfmt.toml`. Local audit (2026-04-30) under
# `cargo +nightly fmt --all -- --check` reports 5,679 drift sites —
# too large to bundle into a CI-fix PR. The format job remains in
# the pipeline as a continuous signal so the sweep author can verify
# zero drift after running `cargo +nightly fmt --all`, but it does
# not gate merge until that sweep lands.
continue-on-error: true
name: format/stable
# Blocking — no continue-on-error. `rustfmt.toml` was stripped of all
# nightly-only directives in PR #133 (`7ca1cf3d chore(fmt): strip
# unstable rustfmt options, keep stable-only config` + `ed59b3b1
# style: normalize codebase to stable rustfmt 1.94.1`) and the
# codebase normalized — so stable rustfmt enforces the project's
# style losslessly. The previous `continue-on-error: true` +
# `dtolnay/rust-toolchain@nightly` setup was a stale band-aid from
# when `brace_style = AlwaysNextLine`, `imports_granularity =
# Preserve`, `unstable_features = true` still lived in rustfmt.toml.
# That state no longer exists; the band-aid is removed in this PR.
steps:
- uses: actions/checkout@v4
# `rustfmt.toml` declares 13 nightly-only options
# (`brace_style = AlwaysNextLine`, `imports_granularity = Preserve`,
# `unstable_features = true`, etc.). Stable rustfmt warns and
# ignores them, then produces drift on every nightly-formatted
# file because its defaults differ from the unstable settings.
# The format job MUST use nightly rustfmt for the project's chosen
# style to be enforceable.
#
# The compile + clippy jobs stay on 1.94.1 (pinned in
# `rust-toolchain.toml`) — only this fmt job needs nightly.
- uses: dtolnay/rust-toolchain@nightly
# Stable rustfmt 1.95.0 — pinned in `rust-toolchain.toml`. No
# nightly dependency since rustfmt.toml is stable-clean post-PR
# #133.
- uses: dtolnay/rust-toolchain@1.95.0
with:
components: rustfmt
- run: cargo fmt --all --check
Expand All @@ -101,7 +99,7 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
targets: ${{ matrix.target }}
# rust-toolchain.toml pins 1.94.1 — install the cross-compile target
# rust-toolchain.toml pins 1.95.0 — install the cross-compile target
# for that toolchain too, since dtolnay/rust-toolchain only installs
# for the matrix value which may differ from the pinned version.
- run: rustup target add ${{ matrix.target }}
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
name = "ndarray"
version = "0.17.2"
edition = "2021"
rust-version = "1.94"
rust-version = "1.95"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update Docker images to the new MSRV

With rust-version raised to 1.95, the repository Docker builds are now broken: both Dockerfile and Dockerfile.avx512 still install and assert Rust 1.94.0 before running cargo build/cargo test, and Cargo will reject this package because its manifest requires rustc 1.95 or newer. This affects anyone using the documented docker build -t ndarray-test . or AVX-512 image path; please bump those Dockerfiles alongside the manifest MSRV.

Useful? React with 👍 / 👎.

authors = [
"Ulrik Sverdrup \"bluss\"",
"Jim Turner"
Expand Down
14 changes: 8 additions & 6 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[toolchain]
channel = "1.94.1"
# Pinned to 1.94.1 (latest 1.94 patch, 2026-03-25). 1.95 turned several
# previously-safe patterns into denied lints (e.g. unnecessary_sort_by)
# without sufficient value to justify the churn — bump explicitly when
# a future version is reviewed, never auto-track stable. Mirrors the
# pin in lance-graph, smb-office-rs, and MedCare-rs.
channel = "1.95.0"
# Pinned to 1.95.0 (2026-04-14). Aligns ndarray with the rest of the
# AdaWorldAPI stack: bevy (already on 1.95 for edition 2024) and
# lance-graph (bumped in parallel). 1.95 introduced one new clippy lint
# that fires on this codebase (`clippy::manual_checked_ops` on
# `impl_owned_array.rs::into_scalar`); that's fixed in this same commit.
# Never auto-track `stable` — bump explicitly when a future version is
# reviewed and the workspace clippy passes clean.
components = ["clippy", "rustfmt"]
2 changes: 1 addition & 1 deletion src/hpc/clam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ impl ClamTree {

use super::bf16_truth::{AwarenessState, PackedQualia};
use super::causality::{causality_decompose, CausalityDecomposition, NarsTruthValue};
use super::node::{Node, SPO, S__, _P_, __O};
use super::node::{Node, _P_, __O, SPO, S__};
use super::plane::Distance as PlaneDistance;

/// A verified hit enriched with causal metadata from SPO decomposition.
Expand Down
2 changes: 1 addition & 1 deletion src/hpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ mod e2e_tests {
use super::causality::{causality_decompose, CausalityDirection};
use super::clam::{knn_brute, ClamTree};
use super::fingerprint::Fingerprint;
use super::node::{Node, SPO, S__, _P_, __O};
use super::node::{Node, _P_, __O, SPO, S__};
use super::seal::Seal;

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/hpc/udf_kernels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::bf16_truth::{bf16_hamming_scalar, BF16Weights};
use super::bitwise::hamming_distance_raw;
use super::cascade::Cascade;
use super::causality::{causality_decompose, CausalityDirection};
use super::node::{Node, SPO, S__, _P_, __O};
use super::node::{Node, _P_, __O, SPO, S__};
use super::plane::Truth;

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