Skip to content

Adopt Rust 1.98 and guard numerical kernels from algebraic float operations #208

Description

@acgetchell

Summary

After Rust 1.98 reaches stable on 2026-08-20, raise la-stack's MSRV and pinned contributor/CI toolchain from Rust 1.97.1 to Rust 1.98.0 (or the latest 1.98.x patch available before merge), then apply the parts of the final 1.98 release that materially improve this repository.

The main la-stack-specific conclusion from the beta audit is deliberately conservative: the new f32/f64::algebraic_{add,sub,mul,div,rem} operations are inappropriate for the crate's correctness-sensitive numerical paths. They permit reassociation and other real-number optimizations despite IEEE-754 behavior, with unspecified precision and potentially varying results. This conflicts with la-stack's documented accumulation order, error bounds, non-finite classification, reproducibility, and exact-fallback filters. The upgrade should turn that conclusion into an enforceable repository policy rather than adopting these methods speculatively.

Rust 1.98's release notes are still provisional. Re-check the final Rust, Cargo, Clippy, rustfmt, and rustdoc notes when stable ships before completing this issue.

Current State

  • Cargo.toml declares rust-version = "1.97.1".
  • rust-toolchain.toml pins channel = "1.97.1".
  • clippy.toml declares msrv = "1.97.1".
  • AGENTS.md, CONTRIBUTING.md, README.md, and docs/RELEASING.md identify Rust 1.97.1 as the active baseline.
  • Core floating-point kernels intentionally use ordinary IEEE-754 operations and f64::mul_add; tests such as vector_dot_and_norm2_sq_preserve_fma_and_left_to_right_order protect the chosen rounding and accumulation behavior.
  • CI covers Linux, macOS, and Windows MSVC. The Rust 1.98 target changes in the provisional notes do not expand or alter that declared matrix.
  • No crate version bump is part of this implementation; v0.4.5 release versioning remains maintainer-driven release work.

Beta validation evidence

Rust 1.98.0-beta.7 (e1114a15d 2026-08-09) passed locally on aarch64-apple-darwin:

  • cargo +beta clippy --locked --all-targets --all-features -- -D warnings
  • cargo +beta fmt --all -- --check
  • cargo +beta test --locked --all-features
  • cargo +beta test --locked --all-features --doc

This demonstrates the local beta cell only; it does not replace final stable validation or the Linux/macOS/Windows CI matrix.

Rust 1.98 Applicability Review

Applicable work

  1. Coordinated MSRV/toolchain update

    • Align the manifest, pinned toolchain, Clippy MSRV, contributor docs, and release docs on the selected stable 1.98.x version.
    • Run the repository's full validation under the stable toolchain and address new compiler, Clippy, rustfmt, and rustdoc diagnostics without broad suppressions.
  2. Protect the numerical contract from algebraic float operations

    • Do not replace +, -, *, /, %, or mul_add in src/ with the new algebraic_* methods.
    • Add a repository-owned Semgrep rule and positive/negative fixtures that reject algebraic_add, algebraic_sub, algebraic_mul, algebraic_div, and algebraic_rem in correctness-sensitive Rust surfaces (src/, examples, and benchmark implementations).
    • Document the rationale close to the numerical/tooling policy: these operations can invalidate stated error bounds, deterministic operation order, signed-zero/non-finite behavior, and benchmark comparability.
    • Any future opt-in approximate/fast-math API must be a separate design issue with an explicit public contract, independent correctness analysis, representative benchmarks, and no effect on existing APIs.
  3. Final compatibility audit

    • Re-run compile, test, doctest, examples, benchmark compilation, Clippy, rustfmt, rustdoc, and project Semgrep checks on stable 1.98.
    • Confirm the all-feature and default-feature surfaces, downstream prelude imports, const-evaluated APIs, and D=2 through D=5 tests remain coherent.

Reviewed; no current code change justified

  • core::fmt::NumBuffer and integer format_into: la-stack has no hand-written integer-formatting buffer or demonstrated formatting bottleneck.
  • NonZero<{integer}>::from_str_radix: exact arithmetic constructs NonZeroU64 from binary decomposition rather than parsing textual integers.
  • [T]::strip_circumfix and str::strip_circumfix: no paired prefix/suffix stripping exists in Rust code.
  • Explicit-endian String::from_utf16{le,be} APIs: no UTF-16 decoding path exists.
  • Atomic*::{from_mut,get_mut_slice,from_mut_slice}: no atomic/concurrent data path exists.
  • Send/Sync changes for process/environment iterator types and the 'static panic-location lifetime: no matching library or support-tool use exists.
  • Faster derived PartialOrd through derived Ord: no la-stack type derives Ord or PartialOrd.
  • assert_eq!/assert_ne! temporary-scope changes, structural-equality tightening, trait-object lifetime defaults, ambiguous-glob hard errors, attribute validation, and new runtime-symbol lints: the beta compiler, all-feature tests, doctests, and Clippy pass today; retain these in the final stable audit.
  • rustfmt discovery through cfg_select!: la-stack does not use cfg_select!.
  • New or promoted AArch64 pointer-authentication, PowerPC64 ELFv2, Thumb, RISC-V, LoongArch, Emscripten, Solaris, and Windows-GNU behavior: outside the declared target matrix; Windows CI uses MSVC.
  • Cargo 1.98's provisional stable changes are fixes for Windows credential-provider CRLF handling and diagnostic capitalization; neither intersects current workflows. Do not adopt nightly-only Cargo flags as part of this issue.

Proposed Changes

  • Wait for Rust 1.98 stable and re-read the final official release notes before implementation.
  • Update current-baseline references in:
    • Cargo.toml
    • rust-toolchain.toml
    • clippy.toml
    • AGENTS.md
    • CONTRIBUTING.md
    • README.md
    • docs/RELEASING.md
  • Do not rewrite immutable benchmark provenance, archived performance records, or synthetic fixture versions merely because they contain an older toolchain number.
  • Do not update the package version, dependency snippets, or CHANGELOG.md directly as part of the toolchain implementation.
  • Add the algebraic-float Semgrep policy and tested fixtures using the existing project-rule conventions.
  • Fix only demonstrated Rust 1.98 diagnostic or formatting changes; avoid unrelated mechanical churn.
  • Record a short adopt/no-change table in the implementation PR, updated from the final stable release notes.

Acceptance Criteria

  • Implementation begins only after Rust 1.98 is stable and its final release notes have been reviewed.
  • Cargo.toml, rust-toolchain.toml, and clippy.toml agree on Rust 1.98.0 or the same newer 1.98.x patch.
  • Active contributor/release documentation consistently names the selected baseline.
  • Archived benchmark provenance and intentionally synthetic test fixtures remain historically accurate.
  • No crate package-version bump or direct CHANGELOG.md edit is included.
  • A tested repository-owned rule prevents f64::algebraic_*/f32::algebraic_* use in correctness-sensitive source, example, and benchmark surfaces.
  • The numerical rationale for rejecting algebraic float operations is documented, including precision, reassociation, non-finite/signed-zero, reproducibility, and benchmark-comparability concerns.
  • Existing mul_add, accumulation-order, error-bound, exact-fallback, non-finite, and strict exact-conversion semantics remain unchanged.
  • Any new Rust/Clippy/rustdoc diagnostics are fixed or narrowly justified; no broad warning suppression is added.
  • Default and exact feature APIs, examples, doctests, tests, proptests, and benchmark targets compile under stable Rust 1.98.
  • just semgrep-test, just semgrep, and final just ci pass under the selected stable toolchain.
  • Linux, macOS, and Windows MSVC CI pass after the pin changes.
  • No unsafe Rust is introduced.
  • The implementation PR records the final 1.98 adopt/no-change audit and changelog-ready summary of the MSRV bump and numerical-policy guard.

Benefits

  • Keeps the declared MSRV, local toolchain, Clippy configuration, documentation, and CI aligned.
  • Prevents an attractive performance API from silently weakening la-stack's scientific correctness contract.
  • Makes future fast-math proposals explicit, reviewable, benchmarked, and opt-in rather than accidental.
  • Captures final compiler/tooling compatibility evidence across the crate's real feature and platform matrix.

Implementation Notes

  • Rust 1.98 is scheduled to become stable on 2026-08-20; beta details can still change.
  • Prefer the smallest stable 1.98 patch that includes any release-day correctness fixes, and keep all baseline declarations exact and aligned.
  • The local beta pass is useful early evidence, not final validation.
  • A toolchain bump is a public MSRV change and should be called out as breaking under the project's pre-1.0 policy.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions