build(nix): single-source the Rust toolchain and rustfmt edition - #211
Merged
Conversation
The pinned Rust version was hardcoded in two places — nix/toolchain.nix
(rust-bin.stable."1.95.0") and src-tauri/Cargo.toml (rust-version) — so a
bump had to touch both by hand or they'd silently drift.
Put the pin in a conventional rust-toolchain.toml and read it from nix via
rust-bin.fromRustupToolchainFile; drop the now-redundant rust-version
(nothing reads it — no MSRV job or cargo config — and the pin is the
version). It now lives in exactly one place, and a bare rustup `cargo`
outside the nix dev shell picks up the same toolchain for free.
The android cross-build keeps working: fromRustupToolchainFile returns a
re-overridable derivation, so rustAndroid = rustToolchain.override
{ targets = [...]; } still layers the android std on top.
Verified: nix dev shell resolves rustc/cargo/rustfmt/clippy 1.95.0, both
dev shells (default + android) evaluate, cargo metadata parses, treefmt
check stays green.
treefmt formatted Rust with treefmt-nix's default edition, which happened to match the workspace's 2024 — but nothing tied them together. On an edition bump `cargo fmt` (which reads Cargo.toml) would move while the treefmt gate kept formatting as 2024, and the two would fight. Read programs.rustfmt.edition from [workspace.package] edition in the root Cargo.toml, mirroring how the biome formatter already loads biome.json. Same value today (treefmt check unchanged: 234 files, 0 changed).
loss-and-quick
force-pushed
the
chore/single-source-rust-toolchain
branch
from
July 5, 2026 10:18
827227b to
d68ee13
Compare
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two pieces of Rust configuration were hardcoded (or defaulted) in the nix layer instead of deriving from a single canonical source, so a bump had to touch two places or the two would silently drift. This PR single-sources both.
1. Toolchain version →
rust-toolchain.tomlThe pinned version lived in two places:
nix/toolchain.nix(rust-bin.stable."1.95.0") andsrc-tauri/Cargo.toml(rust-version = "1.95.0").rust-toolchain.tomland read it from nix viarust-bin.fromRustupToolchainFile.rust-versionfromsrc-tauri/Cargo.toml— nothing reads it (no MSRV job, no cargo config), and the pin already fixes the exact version for every builder.1.95.0now appears in exactly one place.cargooutside the nix dev shell now picks up the same toolchain for free.The android cross-build keeps working:
fromRustupToolchainFilereturns a re-overridable derivation, sorustAndroid = rustToolchain.override { targets = [...]; }still layers the android std on top (verified upstream in rust-overlay:fromRustupToolchainends inpkg.override { … }, which stays overridable).2. rustfmt edition → read from
Cargo.tomltreefmt formatted Rust with treefmt-nix's default edition, which happened to match the workspace's
2024— but nothing tied them together. On an edition bumpcargo fmt(readsCargo.toml) would move while the treefmt gate kept formatting as2024, and the two would fight. Nowprograms.rustfmt.editionreads[workspace.package] editionfrom the rootCargo.toml, mirroring how the biome formatter already loadsbiome.json.Scope note — CI dtolnay jobs intentionally not touched
I originally planned to also drop
toolchain: stablefrom thedtolnay/rust-toolchainsteps so they'd pick uprust-toolchain.toml. That premise is wrong:dtolnay/rust-toolchain'saction.ymldefaultstoolchaintostableand does not readrust-toolchain.tomlat all (its parse step errors if the input is empty — verified in theaction.ymlat the pinned commit). Unifying the rustup-based CI jobs onto this file needs a different setup action (e.g.actions-rust-lang/setup-rust-toolchain, which does read the file) — a broader change with its own behaviour (bundled caching), so it's a separate PR.Affected layer
frontend/— React Web UIcrates/·src-tauri/— Rust core / backend / Tauri desktop (toolchain pin + edition)module/— Android installable zipscripts/— build / release helpers.github/nix/,flake.nix)Verification
Nix / toolchain / formatter wiring only — no application logic changed:
nix develop --command rustc/cargo/rustfmt/clippy --version— all resolve to 1.95.0 (nix buildsrust-default-1.95.0from the file)default+android) — confirmsrustAndroid's.override { targets }still instantiatescargo metadataparses after droppingrust-versionnix build .#checks.x86_64-linux.treefmt— green (234 files, 0 changed); rustfmt edition now evaluates to2024read fromCargo.tomlcargo clippy --workspace --all-targets -- -D warnings— cleanNotes for reviewers
Follow-up (separate PR): unify the 7
dtolnay/rust-toolchainsteps acrossci.yml,nightly.yml,release.yml,core-compat.ymlontorust-toolchain.tomlvia a file-reading setup action — this also pins them to 1.95.0 instead of floatingstable(safe, since 1.95.0 is the pin every other builder already uses). Left out here to keep this change focused and the release pipeline untouched pending that decision.