Raise MSRV to 1.85#15174
Open
alex wants to merge 5 commits into
Open
Conversation
Updates the workspace rust-version, CI MSRV builds, installation docs (RHEL 9.7 is now required for a sufficiently new packaged Rust), and the changelog. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X4EZ7B8sU7cLxPP4qnHfAm
Alpine 3.21 ships Rust 1.83; 3.22 is the first release with a sufficiently new Rust. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X4EZ7B8sU7cLxPP4qnHfAm
rustc 1.84 changed how proc-macro expansions are attributed in coverage maps: the attribute line (e.g. #[derive(...)], #[pyo3::pyclass]) still gets a zero-count line record, but execution of the generated code is no longer attributed to it. The combined coverage gate previously stayed at 100% only because the Rust 1.83 MSRV jobs attributed hits to those lines; with the MSRV at 1.85 no toolchain in the matrix can, so treat attribute lines as non-executable when merging. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X4EZ7B8sU7cLxPP4qnHfAm
This reverts commit a9453ff.
Starting with Rust 1.84, a function consisting entirely of proc-macro expanded code (the impls generated by #[derive(...)], #[pyo3::pyclass], #[pyo3::pymethods], ...) gets a coverage mapping containing only a residual region on the attribute line, wired to a non-entry counter that never fires. Two consequences corrupt line coverage: - llvm-cov reports such a function as unexecuted even when the raw profile proves it ran, so the attribute line reads as a miss. - Generated impls that are never codegen'd at all (e.g. an unused IntoPyObject impl) leave "unused function" placeholder records whose lone residual region marks the attribute line executable, and nothing can ever cover it. Under Rust 1.83 these lines were covered because the mappings wired the attribute-line regions to the entry counter; the 1.83 MSRV jobs were the last toolchain in the matrix doing so, which is why the combined coverage gate broke when they moved to 1.85. Repair the lcov at collection time using the raw profile as ground truth: trust the profile's function count when the mapping computes zero for a function that ran, and drop attribute lines whose only functions were never codegen'd. Handwritten dead code is unaffected: it registers profile records (with count 0) and keeps its zero-count lines. This replaces the reverted approach of excluding all attribute lines in the merge step, which discarded genuine coverage information. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X4EZ7B8sU7cLxPP4qnHfAm
Member
Author
|
Blocked on rust-lang/rust#158833 |
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.
Raises the minimum supported Rust version from 1.83.0 to 1.85.0.
Cargo.toml: bump the workspacerust-versionto 1.85.0..github/workflows/ci.yml: pin the three MSRV matrix builds (plain, AWS-LC, BoringSSL) to 1.85.0 and drop the now-satisfied "1.85: 2024 edition" line from the future-MSRV comment.docs/installation.rst: document the new minimum version and update the distro notes — RHEL/CentOS now requires 9.7+ (9.6 ships Rust 1.84.1, 9.7 ships 1.88.0) and Alpine now requires 3.22+ (3.21 ships Rust 1.83, 3.22 ships 1.87). The Debian note is unchanged since trixie ships rustc 1.85.0, which meets the new MSRV.CHANGELOG.rst: note the MSRV change in the unreleased 50.0.0 section.noxfile.py: repair Rust coverage for proc-macro expanded functions (see below).Coverage repair
The first CI run failed the combined-coverage gate with 124 missed statements, all of them proc-macro attribute lines (
#[derive(...)],#[pyo3::pyclass],#[pyo3::pymethods]). Root cause, established by decoding the__llvm_covfunrecords and raw profiles of instrumented builds under 1.83.0/1.84.0/1.85.0/1.94.1:Starting with Rust 1.84, a function consisting entirely of proc-macro expanded code gets a coverage mapping containing only a residual one-column region on the attribute line (the "visible macro" token span), wired to a non-entry counter that never fires. Under 1.83 the same functions got mappings wiring those regions to the entry counter, so the attribute line showed the function's execution count. Example,
<TBSRequest as SimpleAsn1Writable>::data_length(runtime counters prove 8 executions in both builds):The 1.83.0 MSRV jobs were the last toolchain in the matrix producing entry-wired mappings, which is why the gate broke exactly when they moved to 1.85 (every ≥1.84 toolchain, including stable, emits the zero records). Disabling MIR inlining and
codegen-units=1were tested and ruled out as causes.The fix repairs the lcov at collection time using the raw profile (
llvm-profdata show --all-functions) as ground truth:IntoPyObjectimpl); the line's executability is an artifact — drop it. Handwritten dead code is unaffected since codegen'd-but-uncalled functions register profile records (count 0) and keep their zero lines.Unlike excluding attribute lines outright, this keeps genuine coverage semantics: attribute lines of executed generated impls count as executable and covered with real counts, and regressions there (generated code that stops running) remain visible.
🤖 Generated with Claude Code
https://claude.ai/code/session_01X4EZ7B8sU7cLxPP4qnHfAm