Skip to content

chore(bazel): upgrade rules_rust to 0.74.0 - #11537

Merged
basvandijk merged 7 commits into
masterfrom
bas/rules-rust-0.74.0
Sep 11, 2026
Merged

chore(bazel): upgrade rules_rust to 0.74.0#11537
basvandijk merged 7 commits into
masterfrom
bas/rules-rust-0.74.0

Conversation

@basvandijk

@basvandijk basvandijk commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Upgrades rules_rust from 0.71.3 to 0.74.0, stops depending on the dfinity/rules_rust fork, and drops two local patches that 0.74.0 makes redundant.

Drops the fork

The pin was an archive_override on dfinity/rules_rust, whose sole commit adds a strip_level_select tag 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 the strip_level_select(none) workaround went away with it. strip_level now appears nowhere in the repo outside the patch file, so the fork is dead code.

-bazel_dep(name = "rules_rust", version = "0.71.3")
-archive_override(
+bazel_dep(name = "rules_rust", version = "0.74.0")
+single_version_override(
     module_name = "rules_rust",
-    integrity = "sha256-5GXwZtp5VlNxMI+dolYYxhyhG5f5ReZ5qz30gAbPsrg=",
     patch_strip = 1,
     patches = ["//bazel:rules_rust_static_runtime.patch"],
-    strip_prefix = "rules_rust-f8f382c7e351a797242ce4a92262342f8994e265",
-    type = "tar.gz",
-    urls = ["https://codeload.github.com/dfinity/rules_rust/tar.gz/f8f382c7e351a797242ce4a92262342f8994e265"],
 )

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's rules_rust/0.74.0/source.json carries no patches of its own, and rules_rust is 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.patch

The rust_doc_test half of the patch is upstream as of 0.74.0 (#4220, commit ed7afd2fc) and is a superset of ours — it threads the runtime libs through rustdoc_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 in rustdoc.bzl that 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 -l flags. The policy therefore now lives in a single exported 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), so inputs and link flags stay consistent by construction.

The patch applies with zero fuzz and zero offset (git apply --check and patch -F0), verified against the release tarball specifically, not just the git tag.

Drops bazel/rustix.patch

That patch deleted rustix's can_compile() probe artifact from OUT_DIR — which rules_rust captures as a cacheable CargoBuildScriptRun output — because the artifact was not byte-reproducible. 0.74.0 makes it unnecessary: #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 them to its probe rustc.

Follow-ups (not in this PR)

  • The remaining dylib/cdylib half of the static-runtime patch has no upstream issue. Opening one would let it retire the way the doc-test half just did — though upstream deliberately links the dynamic runtime for shared libraries (its own runtime_libs_test/shared_library asserts 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 the rules_rust pin, since a bump on its own requires ./bin/bazel-pin.sh --force.
  • If the rustix probe ever regresses (a toolchain bump, or anything adding a remap-scope rustflag), the fix is rules_rust 0.74.0's new remove_nondeterministic_out_dir_files: appending rustix_test_can_compile to --@rules_rust//cargo/settings:out_dir_volatile_file_basenames (re-listing its seven defaults, since the flag replaces rather than extends) empties OUT_DIR again with no crate patch and no repin. That, not a resurrected bazel/rustix.patch.
  • Worth an upstream issue: cargo_build_script could pass the same ${output_base}/${exec_root} remaps that rustc.bzl already passes, closing the symlink gap described above.
  • The dfinity/rules_rust fork branches can be deleted once this merges; nothing will reference the fork any more.

🤖 Generated with Claude Code

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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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.

@basvandijk
basvandijk marked this pull request as ready for review September 10, 2026 15:18
@basvandijk
basvandijk requested a review from a team as a code owner September 10, 2026 15:18
Comment thread bazel/rules_rust_static_runtime.patch Outdated
Comment thread bazel/rules_rust_static_runtime.patch Outdated
Comment thread Cargo.Bazel.toml.lock
@nmattia

nmattia commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

bazel/rustix.patch may now be redundant: upstream bazelbuild/rules_rust#4202 fixes issue #4201, the same rustix build-script probe defect that patch works around. Worth checking separately rather than in a version bump.

Let's check here; no point carrying a patch that's unnecessary

basvandijk and others added 3 commits September 11, 2026 08:27
`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>
@basvandijk
basvandijk requested review from nmattia and a balanced review from Copilot September 11, 2026 09:08
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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

@basvandijk
basvandijk added this pull request to the merge queue Sep 11, 2026
Merged via the queue into master with commit c7ea996 Sep 11, 2026
44 checks passed
@basvandijk
basvandijk deleted the bas/rules-rust-0.74.0 branch September 11, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants