Skip to content

Fix platform label context in rule transitions#3997

Open
tamasvajk wants to merge 2 commits intobazelbuild:mainfrom
tamasvajk:transition-label-context
Open

Fix platform label context in rule transitions#3997
tamasvajk wants to merge 2 commits intobazelbuild:mainfrom
tamasvajk:transition-label-context

Conversation

@tamasvajk
Copy link
Copy Markdown
Contributor

Summary

Fix platform label resolution in rule transitions for rust_binary, rust_shared_library, rust_static_library, and rust_test.

Problem

When a platform label comes from the main repository (no repo name), str(label) produces //platforms:foo instead of @//platforms:foo. Bazel's //command_line_option:platforms setting requires the canonical form with @, so the transition silently selects the wrong platform or fails.

This affects anyone using the platform attribute on Rust rules with a label defined in the main repository.

Fix

Extract a _resolve_platform helper that adds the @ prefix when attr.platform.repo_name is empty, and apply it consistently to all four rule transitions. The original patch only fixed rust_binary; this PR fixes all four for completeness.


Note: This PR was largely AI-generated using Claude Code, with human review and guidance throughout.

When a platform label has no repo name (i.e. from the main repo),
str(label) produces "//platforms:foo" instead of "@//platforms:foo".
Bazel's platform setting requires the canonical form with @, causing
the transition to fail silently or select the wrong platform.

Extract a _resolve_platform helper and apply it consistently to all
four rule transitions (static_library, shared_library, binary, test).
Copy link
Copy Markdown
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

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

Thanks! I had one question on this.

Comment thread rust/private/rust.bzl Outdated
Comment on lines +1012 to +1014
When a label has no repo name (e.g. from the main repo), str(label) omits
the leading @, producing "//platforms:foo" instead of "@//platforms:foo".
Bazel's platform setting requires the canonical form with @.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there any upstream issue for this? That seems somewhat surprising.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not aware of a specific upstream Bazel issue for this. The problem is that str(attr.platform) inside a transition implementation omits the @ prefix for labels from the main repository. Since the transition runs in the context of @rules_rust, Bazel then interprets //platforms:foo as @rules_rust//platforms:foo instead of @//platforms:foo.

This was discovered when using the platform attribute on rust_binary with a label from the main repo — the platform was silently resolved against rules_rust instead of the root workspace.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I tried to set up a minimal repro, but I could only repro this with our patched Bazel. So the problem is actually not in rules_rust, but in our Bazel patch. I'm closing this PR.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you file an upstream issue for this? Because platform is a attr.label I would have expected it to be in the correct form for all contexts and that a simple str would result in the correct behavior. I'm happy to accept the fix but would love to hear from the Bazel team first 🙏

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also @krasimirgg do you maybe have any context here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ah, disregard

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reopening — I was able to reproduce this with stock Bazel (not our patched version). The trigger is --noincompatible_unambiguous_label_stringification, which some projects set for compatibility reasons.

Minimal repro:

# WORKSPACE
workspace(name = "repro")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(name = "rules_rust", sha256 = "d861...", urls = ["...0.64.0..."])
load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains")
rules_rust_dependencies()
rust_register_toolchains()

# BUILD.bazel
load("@rules_rust//rust:defs.bzl", "rust_binary")
rust_binary(name = "hello", srcs = ["main.rs"], edition = "2021", platform = "//platforms:my_linux_x86_64")

# platforms/BUILD.bazel
platform(name = "my_linux_x86_64", constraint_values = ["@platforms//os:linux", "@platforms//cpu:x86_64"], visibility = ["//visibility:public"])
$ bazel build //:hello --noincompatible_unambiguous_label_stringification
ERROR: no such package '@@rules_rust//platforms': BUILD file not found in directory 'platforms' of external repository @@rules_rust.

Root cause: With --noincompatible_unambiguous_label_stringification (which was the default before Bazel 6.0, see bazelbuild/bazel#15916), str(attr.platform) inside the transition produces //platforms:my_linux_x86_64 without the @ prefix. Bazel then resolves this relative to @@rules_rust instead of the main repo.

The flag was introduced to fix exactly this class of ambiguity, but projects that disable it (via --noincompatible_unambiguous_label_stringification) hit this bug.

@tamasvajk tamasvajk closed this Apr 28, 2026
@tamasvajk tamasvajk reopened this Apr 28, 2026
The previous check `not attr.platform.repo_name` was incorrect because
repo_name is empty for main-repo labels regardless of the stringification
flag. With --incompatible_unambiguous_label_stringification (the default),
str(label) already includes the @ prefix, so prepending another @ produced
"@@//foo:bar" which is an invalid repository name.

Check the string itself instead: only add @ when str() doesn't already
start with one.
@tamasvajk
Copy link
Copy Markdown
Contributor Author

@UebelAndre What's the best way to rerun the CI jobs? There are some transient failures in the logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants