You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rust 1.97 (2026-07-09) stabilized Cargo's build.warnings config key (rust-lang/cargo#16796), which controls how lint warnings from local/workspace packages only (not dependencies) are treated. It supports "deny"/"allow" (via .cargo/config.toml or CARGO_BUILD_WARNINGS=deny), and — critically — changing it does not invalidate Cargo's build cache, unlike RUSTFLAGS="-D warnings", which changes the rustc invocation fingerprint and forces a full recompile whenever toggled between builds/jobs sharing a cache.
Zeph just bumped MSRV to 1.97 today (commit 71a4dda1, #5872), which unblocks this. The project currently relies on RUSTFLAGS="-D warnings" pervasively and already has one documented workaround for its side effects:
.github/workflows/ci.yml:15 — global RUSTFLAGS: "-D warnings" env for the whole workflow.
.github/workflows/ci.yml:438-447 — the coverage job explicitly resets RUSTFLAGS: "" with an inline comment: "RUSTFLAGS is reset to empty to prevent -D warnings from promoting workspace lint warnings to errors during instrumented compilation — linting is enforced by the dedicated lint-clippy job." This is exactly the kind of per-job RUSTFLAGS juggling build.warnings's local-package scoping and cache-friendliness could simplify.
.claude/rules/branching.md ("Before Every Commit" / "Before Creating a PR") and the user's global CLAUDE.md both mandate RUSTFLAGS="-D warnings" cargo check/doc ... for local pre-commit/pre-PR gates.
Reproduction Steps
See .github/workflows/ci.yml:15, :161 (clippy's separate -D warnings CLI flag), :438-447 (coverage workaround), :647 (RUSTDOCFLAGS gate — separate mechanism, out of scope).
Observe: no verification has been done yet on whether build.warnings=deny catches the same warning classes (unused imports, dead code) this project currently relies on RUSTFLAGS="-D warnings" for.
Expected Behavior
A lint-warning gate for workspace-local code that does not force cache-busting full rebuilds when toggled between CI jobs, while remaining at least as strict as the current RUSTFLAGS="-D warnings" gate for the warning classes this project currently relies on it to catch.
Actual Behavior
Project uses a blunt, cache-invalidating, env-var-based mechanism with at least one already-documented workaround for its side effects on shared sccache caches.
build.warnings=deny only errors on lint warnings, not "hard warnings" (e.g. edition-migration warnings) — does any warning class this project currently relies on RUSTFLAGS="-D warnings" for (unused imports, dead code) fall outside lint-warning coverage?
Does build.warnings interact with cargo doc/rustdoc warnings, or is the existing RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" gate fully independent (assumed out of scope)?
Does cargo clippy -- -D warnings (CLI flag, not env-based) respect/interact with build.warnings, or must it stay unchanged regardless of this migration?
Confirm CI's pinned stable toolchain action will consistently resolve to >=1.97 going forward before relying on build.warnings in CI.
Config location choice: .cargo/config.toml vs CARGO_BUILD_WARNINGS env var — which fits the project's existing conventions better.
This is scoped as "investigate and adopt IF verification confirms no coverage regression," not a blind swap — see plan.md for the two-phase (verify-first, then conditionally adopt) approach.
Description
Rust 1.97 (2026-07-09) stabilized Cargo's
build.warningsconfig key (rust-lang/cargo#16796), which controls how lint warnings from local/workspace packages only (not dependencies) are treated. It supports"deny"/"allow"(via.cargo/config.tomlorCARGO_BUILD_WARNINGS=deny), and — critically — changing it does not invalidate Cargo's build cache, unlikeRUSTFLAGS="-D warnings", which changes the rustc invocation fingerprint and forces a full recompile whenever toggled between builds/jobs sharing a cache.Zeph just bumped MSRV to 1.97 today (commit
71a4dda1, #5872), which unblocks this. The project currently relies onRUSTFLAGS="-D warnings"pervasively and already has one documented workaround for its side effects:.github/workflows/ci.yml:15— globalRUSTFLAGS: "-D warnings"env for the whole workflow..github/workflows/ci.yml:438-447— the coverage job explicitly resetsRUSTFLAGS: ""with an inline comment: "RUSTFLAGS is reset to empty to prevent -D warnings from promoting workspace lint warnings to errors during instrumented compilation — linting is enforced by the dedicated lint-clippy job." This is exactly the kind of per-job RUSTFLAGS jugglingbuild.warnings's local-package scoping and cache-friendliness could simplify..claude/rules/branching.md("Before Every Commit" / "Before Creating a PR") and the user's globalCLAUDE.mdboth mandateRUSTFLAGS="-D warnings" cargo check/doc ...for local pre-commit/pre-PR gates.Reproduction Steps
.github/workflows/ci.yml:15,:161(clippy's separate-D warningsCLI flag),:438-447(coverage workaround),:647(RUSTDOCFLAGS gate — separate mechanism, out of scope).build.warningsrust-lang/cargo#16796 and the Rust 1.97.0 release notes confirmingbuild.warningsscope/semantics.build.warnings=denycatches the same warning classes (unused imports, dead code) this project currently relies onRUSTFLAGS="-D warnings"for.Expected Behavior
A lint-warning gate for workspace-local code that does not force cache-busting full rebuilds when toggled between CI jobs, while remaining at least as strict as the current
RUSTFLAGS="-D warnings"gate for the warning classes this project currently relies on it to catch.Actual Behavior
Project uses a blunt, cache-invalidating, env-var-based mechanism with at least one already-documented workaround for its side effects on shared sccache caches.
Environment
71a4dda1(MSRV bumped to 1.97 today via chore: bump MSRV to 1.97 #5872)Open Questions (from spec, NEEDS CLARIFICATION)
build.warnings=denyonly errors on lint warnings, not "hard warnings" (e.g. edition-migration warnings) — does any warning class this project currently relies onRUSTFLAGS="-D warnings"for (unused imports, dead code) fall outside lint-warning coverage?build.warningsinteract withcargo doc/rustdoc warnings, or is the existingRUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links"gate fully independent (assumed out of scope)?cargo clippy -- -D warnings(CLI flag, not env-based) respect/interact withbuild.warnings, or must it stay unchanged regardless of this migration?stabletoolchain action will consistently resolve to >=1.97 going forward before relying onbuild.warningsin CI..cargo/config.tomlvsCARGO_BUILD_WARNINGSenv var — which fits the project's existing conventions better.This is scoped as "investigate and adopt IF verification confirms no coverage regression," not a blind swap — see plan.md for the two-phase (verify-first, then conditionally adopt) approach.
Spec
.local/specs/047-cargo-build-warnings-migration/spec.md
.local/specs/047-cargo-build-warnings-migration/plan.md