Skip to content

migrate lint-warning CI gate from RUSTFLAGS=-D warnings to cargo's build.warnings #5873

Description

@bug-ops

Description

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

  1. 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).
  2. Compare against cargo PR feat(compile): Stabilize build.warnings rust-lang/cargo#16796 and the Rust 1.97.0 release notes confirming build.warnings scope/semantics.
  3. 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.

Environment

Open Questions (from spec, NEEDS CLARIFICATION)

  1. 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?
  2. 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)?
  3. Does cargo clippy -- -D warnings (CLI flag, not env-based) respect/interact with build.warnings, or must it stay unchanged regardless of this migration?
  4. Confirm CI's pinned stable toolchain action will consistently resolve to >=1.97 going forward before relying on build.warnings in CI.
  5. 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.

Spec

.local/specs/047-cargo-build-warnings-migration/spec.md
.local/specs/047-cargo-build-warnings-migration/plan.md

Metadata

Metadata

Assignees

Labels

P3Research — medium-high complexityenhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions