chore(bazel): upgrade rules_rust to 0.74.0 - #11537
Conversation
Upgrades `rules_rust` from 0.71.3 to 0.74.0 and stops depending on the `dfinity/rules_rust` fork. - **Drops the fork.** The pin was an `archive_override` on dfinity/rules_rust, whose sole commit adds a `strip_level_select` tag class. That tag's only caller was removed in 9e29205 when hermetic-llvm replaced zig cc, so the fork is dead code: `strip_level` now appears nowhere in the repo. The pin becomes a plain `bazel_dep` on the BCR release plus a `single_version_override` carrying our one patch — no integrity hash, no `strip_prefix`, no URL, and no fork to rebase on every future release. - **Regenerates `bazel/rules_rust_static_runtime.patch`.** The `rust_doc_test` half is upstream as of 0.74.0 (bazelbuild/rules_rust#4220), as a superset of ours — it adds an empty-lib-root guard we lacked and a unit test — so the patch no longer carries it. What remains is the dylib/cdylib static-runtime preference, which is still not upstream. #4220 also introduced a *new* site in `rustdoc.bzl` that picks the dynamic runtime for dylib/cdylib, so the policy now lives in a single `cc_runtime_libs` helper shared by all three sites that choose a runtime (`collect_inputs`, `_add_native_link_flags`, and rustdoc's doc-test link flags), keeping the action inputs and the link flags consistent by construction. - **Repins `Cargo.Bazel.json.lock`.** Required, not cosmetic: the crate_universe lockfile `checksum` is a digest over the generator's own output format, so a rules_rust bump alone invalidates it and `determine_repin` then fails every build in the repo. The 94k -> 71k line diff is purely serialization (#4133 lockfile compaction, #4090 build-script dep moved to `extra_deps`); all 1392 crate entries compare equal after normalizing for those changes, with an identical dependency graph and no crate-version churn. The Rust toolchain pin stays at 1.97.1 — `DEFAULT_RUST_VERSION` moving to 1.98.0 upstream does not affect an explicitly pinned version, and a compiler bump belongs in its own PR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The repo-wide dependency upgrade, upstream-internal patch, and large generated lockfile warrant final human verification.
Pull request overview
Upgrades rules_rust to upstream 0.74.0 while preserving required static C++ runtime linkage.
Changes:
- Replaces the fork override with a registry-based override.
- Refactors and reduces the static-runtime patch.
- Repins the generated crate-universe lockfile.
File summaries
| File | Description |
|---|---|
bazel/rust.MODULE.bazel |
Updates and patches rules_rust 0.74.0. |
bazel/rules_rust_static_runtime.patch |
Centralizes shared-library runtime selection. |
Cargo.Bazel.json.lock |
Regenerates crate-universe metadata. |
Review details
- Files reviewed: 2/3 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Let's check here; no point carrying a patch that's unnecessary |
`bazel/rustix.patch` deleted rustix's `can_compile()` probe artifact from `OUT_DIR` so that the `CargoBuildScriptRun` output — which rules_rust captures as a cacheable build output — stayed byte-reproducible. The patch header attributed the non-determinism to the probe artifact embedding "non-deterministic compiler-internal metadata". It is in fact plain path-dependence, and rules_rust 0.74.0 fixes it: upstream #4202 adds `--remap-path-prefix=${pwd}=.` to the `CARGO_ENCODED_RUSTFLAGS` that `cargo_build_script` passes to build scripts, and rustix's `can_compile()` forwards all of `CARGO_ENCODED_RUSTFLAGS` to its probe `rustc`, so the probe now compiles path-independently. The probe feeds its source to `rustc` on stdin, so the working directory (the exec root) is the only path input `rustc` has, and it folds that into the crate hash — never as a literal string, which is why it originally read as opaque compiler metadata rather than as a path leak. Measured with the pinned toolchain rustc 1.97.1, running the probe from two directories of different depth: no remap 350953f6… vs bbf7a20d… differ with remap d821dd0c… vs d821dd0c… identical Note that upstream rustix#1628 (the patch's source) is still unmerged and 1.1.4 is still the latest rustix, so this is resolved purely by the rules_rust side. Removing the `crate.annotation` leaves only `crate` and `version` behind, and `version` there is a selector for which version the annotation applies to rather than a dependency pin, so the whole annotation goes and the lockfile loses just the two patch fields. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The patch it documents no longer exists, so the row is clutter rather than a worked example. The other three entries still cover the patterns (embedded canonicalized path, generated pkgconfig, configure --prefix). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The toolchain-wide upgrade and custom runtime-linking patch affect production shared libraries and warrant final human validation.
Review details
- Files reviewed: 4/6 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Upgrades
rules_rustfrom 0.71.3 to 0.74.0, stops depending on thedfinity/rules_rustfork, and drops two local patches that 0.74.0 makes redundant.Drops the fork
The pin was an
archive_overrideondfinity/rules_rust, whose sole commit adds astrip_level_selecttag class (bazelbuild/rules_rust#4167, still open upstream). That tag's only caller was removed in 9e29205 when hermetic-llvm replaced zig cc — clang emits deterministic debug info, so thestrip_level_select(none)workaround went away with it.strip_levelnow appears nowhere in the repo outside the patch file, so the fork is dead code.No integrity hash, no
strip_prefix, no URL, and no fork to rebase on every future release — a bump is now a one-line version change. Checked before switching: BCR'srules_rust/0.74.0/source.jsoncarries no patches of its own, andrules_rustis depended on only by the root module (bazel mod explain rules_rust), so nothing else can pull MVS off 0.74.0.Regenerates
bazel/rules_rust_static_runtime.patchThe
rust_doc_testhalf of the patch is upstream as of 0.74.0 (#4220, commited7afd2fc) and is a superset of ours — it threads the runtime libs throughrustdoc_compile_action's return value rather than recomputing them, adds an empty-lib-root guard we lacked (an empty root would emit--strip_substring=/, which the writer applies as a plain string replacement), and ships a unit test. So the patch no longer carries it.What remains is the dylib/cdylib static-runtime preference, which is still not upstream and has no replacement mechanism (no new
unwindlib, toolchain or rule attribute controls C++ runtime linkage in this range). #4220 also introduced a new site inrustdoc.bzlthat picks the dynamic runtime for dylib/cdylib, which the old patch would have missed — leaving a cdylib doc test with the static runtime in its action inputs but the dynamic runtime's names in its-lflags. The policy therefore now lives in a single exportedcc_runtime_libshelper, shared by all three sites that choose a runtime (collect_inputs,_add_native_link_flags, and rustdoc's doc-test link flags), so inputs and link flags stay consistent by construction.The patch applies with zero fuzz and zero offset (
git apply --checkandpatch -F0), verified against the release tarball specifically, not just the git tag.Drops
bazel/rustix.patchThat patch deleted rustix's
can_compile()probe artifact fromOUT_DIR— which rules_rust captures as a cacheableCargoBuildScriptRunoutput — because the artifact was not byte-reproducible. 0.74.0 makes it unnecessary: #4202 adds--remap-path-prefix=${pwd}=.to theCARGO_ENCODED_RUSTFLAGSthatcargo_build_scriptpasses to build scripts, and rustix'scan_compile()forwards all of them to its proberustc.Follow-ups (not in this PR)
runtime_libs_test/shared_libraryasserts exactly that), so it would need a toolchain-level opt-in rather than a straight behaviour change..claude/CLAUDE.md's repin trigger could mention therules_rustpin, since a bump on its own requires./bin/bazel-pin.sh --force.remove_nondeterministic_out_dir_files: appendingrustix_test_can_compileto--@rules_rust//cargo/settings:out_dir_volatile_file_basenames(re-listing its seven defaults, since the flag replaces rather than extends) emptiesOUT_DIRagain with no crate patch and no repin. That, not a resurrectedbazel/rustix.patch.cargo_build_scriptcould pass the same${output_base}/${exec_root}remaps thatrustc.bzlalready passes, closing the symlink gap described above.dfinity/rules_rustfork branches can be deleted once this merges; nothing will reference the fork any more.🤖 Generated with Claude Code