Bump Rust to 1.98.1 and the CI nightly to 2026-09-02 - #38620
Conversation
QA LLM Review1. HIGH -- 1.98.0 is the one stable release carrying an open, unfixed UB miscompilation
Rust 1.98.0 miscompiles some Detailsrustc 1.98.0 can decide that an impl's predicates are impossible when they involve associated-type projections plus an opaque type, emit I reproduced it on the platform we build for, The trigger needs dyn dispatch into an impl whose where-clauses involve associated-type projections or associated-type bounds, with an Suggested fix: hold |
|
Good catch, and it holds up on every point I could check independently:
The point about a green CI run proving nothing is the one that decides it. This PR is now a draft, held until 1.98.1 lands. I will then repin both On splitting: the nightly half is genuinely unaffected, since master has carried the fix since 2026-07-15 and the new pin is 2026-09-02. I am keeping it here rather than landing it separately, so the toolchain moves as one reviewable change. Happy to split it out instead if you would rather unblock the doc and nightly jobs now. Two things already surfaced by the nightly half, for the record. Advancing past 2026-08-02 required removing the stale blocker note in 🤖 Posted by Claude Code |
CI derives its stable toolchain from the `rust-version` field in the root `Cargo.toml`, so that field is what decides which warnings CI can see. Holding it at 1.97.1 meant the lints Rust 1.98 introduced only showed up when someone built locally. Raising it to 1.98.1 closes that gap. Cargo.lock needs no change, which matters because the doc test job resolves with `--locked`. The pin skips 1.98.0, which miscompiles some `dyn Trait` calls into a null vtable slot. rustc 1.98.0 can decide that an impl's predicates are impossible when they involve associated-type projections plus an opaque type, emit `VtblEntry::Vacant` for that impl's method, and leave a zero in the method slot of a compiler-generated vtable, after which safe code dispatches through a null pointer. The bug is rust-lang/rust#161441, and the fix reached stable in the 1.98.1 point release. Running the self-contained reproducer from that issue on `x86_64-unknown-linux-gnu` under edition 2024 confirms the difference: 1.98.0 aborts with SIGILL at `-O` and SIGSEGV without it, while 1.98.1 runs to completion in both profiles. A green CI run on 1.98.0 would not have ruled the tree out, because rustc emits the bad vtable with no diagnostic. Rust 1.98.1 uses LLVM 22.1.8, matching the `clang-22`, `lld-22`, and `llvm-22` packages the CI builder image already installs, so the Dockerfile needs no accompanying change. The comment on that apt stanza asks for the two to move together, and they still agree. Bumping `rust-version` does change the builder image tag, because the tag hashes the build arguments and `RUST_VERSION` is one of them. `ci/mkpipeline.sh` detects the missing tag and inserts bootstrap steps that build and push the stable, min, and console flavors for both architectures, so the first build on this branch will be slow but needs no manual intervention. The nightly pin moves to 2026-09-02. The note that pinned it to 2026-08-02 pointed at rust-lang/rust#160439, a rustdoc hang that broke the Doctests job, and that issue was closed as completed on 2026-08-06. The note is removed rather than reworded, because the constraint it described no longer exists. Advancing the nightly does make rustdoc's `redundant_explicit_links` lint fire, and `bin/doc` runs with `RUSTDOCFLAGS=-D warnings`, so those become errors. Eight doc comments in `mz-avro` and `mz-pgtest` spell an intra-doc link as a label plus an explicit legacy HTML path that resolves to the same destination. Dropping the explicit target is the rewrite rustdoc itself suggests, and every referenced item is in scope at the link site. The `flush` links in the Avro writer keep their explicit targets, because a fragment path is not redundant with its label and rustdoc does not flag them. `bin/lint-versions` records the Rust version that has been checked for compilation time regressions, and it is updated here so `bin/lint` passes. That validation has not been performed. Team Testing should confirm 1.98.1 before this merges. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
f113d67 to
7be4db7
Compare
|
Addressed. The pin now reads 1.98.1 in both 1.98.1 published on 2026-09-03, carrying the rust-lang/rust#161555 backport of the rust-lang/rust#158993 fix. I verified the difference with the self-contained reproducer from rust-lang/rust#161441 on The branch is rebased onto The commit message and the PR description now state why the pin skips 1.98.0 rather than leaving it implicit. The remaining item before merge is unchanged: 🤖 Posted by Claude Code |
CI derives its stable toolchain from the
rust-versionfield in the rootCargo.toml, so that field is what decides which warnings CI can see. Holding it at 1.97.1 meant the lints Rust 1.98 introduced only showed up when someone built locally, which is how the warnings fixed in #38619 went unnoticed. Raising it closes that gap. Cargo.lock needs no change, which matters because the doc test job resolves with--locked.Rust 1.98.1 uses LLVM 22.1.8, matching the
clang-22,lld-22, andllvm-22packages the CI builder image already installs, so the Dockerfile needs no accompanying change. The comment on that apt stanza asks for the two to move together, and they still agree. Bumpingrust-versiondoes change the builder image tag, because the tag hashes the build arguments andRUST_VERSIONis one of them.ci/mkpipeline.shdetects the missing tag and inserts bootstrap steps that build and push the stable, min, and console flavors for both architectures, so the first build on this branch will be slow but needs no manual intervention.The nightly pin moves to 2026-09-02. The note that pinned it to 2026-08-02 pointed at rust-lang/rust#160439, a rustdoc hang that broke the Doctests job, and that issue was closed as completed on 2026-08-06. The note is removed rather than reworded, because the constraint it described no longer exists.
Advancing the nightly does make rustdoc's
redundant_explicit_linkslint fire, andbin/docruns withRUSTDOCFLAGS=-D warnings, so those become errors. Eight doc comments inmz-avroandmz-pgtestspell an intra-doc link as a label plus an explicit legacy HTML path that resolves to the same destination. Dropping the explicit target is the rewrite rustdoc itself suggests, and every referenced item is in scope at the link site. Theflushlinks in the Avro writer keep their explicit targets, because a fragment path is not redundant with its label and rustdoc does not flag them.Why 1.98.1 and not 1.98.0
Rust 1.98.0 carries a
P-criticalmiscompilation, rust-lang/rust#161441: rustc can wrongly decide an impl's predicates are impossible when they involve associated-type projections plus an opaque type, emit a vacant vtable entry, and leave a zero in the method slot. Safe code then dispatches through a null pointer. It is a regression from 1.97.1, and it is silent at compile time, so a green CI run on 1.98.0 would not have been evidence that the tree is unaffected. That matters here becauserust-versionselects the toolchain in thestableci-builder flavor that builds the shipped images.rust-lang/rust#158993 fixed it on master on 2026-07-15, which is after the 1.98 beta cutoff and therefore too late for 1.98.0. rust-lang/rust#161555 backported it on top of the 1.98.0 commit
88d9e12ae178and merged to thestablebranch on 2026-09-01. The 1.98.1 release published on 2026-09-03, so the pin goes straight there and 1.98.0 is never used. Running the self-contained reproducer from the upstream issue onx86_64-unknown-linux-gnuunder edition 2024 confirms the difference: 1.98.0 aborts with SIGILL at-Oand SIGSEGV without it, while 1.98.1 runs to completion in both profiles.Outstanding before merge
bin/lint-versionsrecords the Rust version checked for compilation time regressions. That validation has not been performed. Team Testing should confirm 1.98.1 before this merges.The
cargo test --docjob could not be exercised locally because that machine has noprotoc, so it is covered only by CI. Building the nightly builder image also runscargo miri setupand installscargo-fuzz, neither of which can be checked outside an image build; both fail loudly in the bootstrap step rather than silently. Finally, a toolchain bump surfaces latent problems anywhere in the tree, not only in the diff, so a failure on this branch may point at code it does not touch.Release notes
No user-visible changes.
🤖 Posted by Claude Code