Background
Tracking the chain so it's clear what this is downstream of:
Important to note up front: the bug here is independent of which alias rule you use. Upstream's verbatim alias_rules.bzl and the hand-rolled workaround copy are byte-identical, and either one trips this. Today the issue is mostly latent because #2832 blocks the upstream path, but once #2832 is fixed and users adopt default_alias_rule = "opt", they'd hit this immediately.
The bug
rust/private/rustc.bzl::collect_deps (0.70.0):
aliases = {k.label: v for k, v in aliases.items()}
for dep in crate_deps:
crate_info = dep.crate_info
...
if crate_info.owner in aliases:
...
The dict is keyed by the aliased target's own .label, but the lookup is against crate_info.owner of the dep. These differ whenever the aliased target is a rule that forwards COMMON_PROVIDERS from an underlying rust_library — which is exactly what the canonical transition_alias_opt rule does:
def _transition_alias_impl(ctx):
return [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]
So crate_info.owner ends up as the wrapped rust_library's label (e.g. @crate_index__hyper-0.14.29//:hyper), but the dict key is the wrapper's label (e.g. //third_party/rust/crates:hyper1427). They don't match → the alias is silently dropped → the crate gets imported under its original name → compile error like unresolved import alias_name.
Reproducer
In a workspace where #2832 is worked around with a custom alias_rules.bzl (or, hypothetically, once #2832 is fixed, with default_alias_rule = "opt" directly):
# Cargo.toml → renders as `transition_alias_opt(name="hyper", actual="@crate_index__hyper-0.14.29//:hyper")` in crate_index
# user-facing rust_library:
rust_library(
name = "foo",
aliases = {"@crate_index//:hyper": "hyper1427"},
deps = ["@crate_index//:hyper"],
...
)
foo's source imports the crate as hyper1427 (e.g. use hyper1427::Body;). Compile fails with unresolved import hyper1427 because the alias dict key doesn't match dep.crate_info.owner.
Proposed fix
Use the underlying library's owner when the alias key is itself a crate_info-providing target:
aliases = {
k[rust_common.crate_info].owner if rust_common.crate_info in k else k.label: v
for k, v in aliases.items()
}
This is what we carry as a local patch (0010-allow-using-aliased-crate-in-aliases-attr.patch) against 0.70.0. Happy to send a PR if the maintainers agree.
Versions
- rules_rust: 0.70.0
- bazel: 7.7.1
Background
Tracking the chain so it's clear what this is downstream of:
cargo-bazelnow supportsalias_ruleto customize the aliases generated #2312 (closed): introducedrender_config(default_alias_rule = "opt")as a shortcut to wrap all crate_universe crates in acompilation_mode=opttransition.crates_vendor, the generated BUILDs reference@@crate_index//:alias_rules.bzlbut the file isn't shipped in the vendored output, sodefault_alias_rule = "opt"fails to load.alias_rules.bzlin their workspace and pointingdefault_alias_ruleat it. The natural way to write that file is to copy upstream's owncrate_universe/src/rendering/verbatim/alias_rules.bzlverbatim (it's the canonical implementation).rust/private/rustc.bzl::collect_deps.Important to note up front: the bug here is independent of which alias rule you use. Upstream's verbatim
alias_rules.bzland the hand-rolled workaround copy are byte-identical, and either one trips this. Today the issue is mostly latent because #2832 blocks the upstream path, but once #2832 is fixed and users adoptdefault_alias_rule = "opt", they'd hit this immediately.The bug
rust/private/rustc.bzl::collect_deps(0.70.0):The dict is keyed by the aliased target's own
.label, but the lookup is againstcrate_info.ownerof the dep. These differ whenever the aliased target is a rule that forwardsCOMMON_PROVIDERSfrom an underlyingrust_library— which is exactly what the canonicaltransition_alias_optrule does:So
crate_info.ownerends up as the wrapped rust_library's label (e.g.@crate_index__hyper-0.14.29//:hyper), but the dict key is the wrapper's label (e.g.//third_party/rust/crates:hyper1427). They don't match → the alias is silently dropped → the crate gets imported under its original name → compile error likeunresolved import alias_name.Reproducer
In a workspace where #2832 is worked around with a custom
alias_rules.bzl(or, hypothetically, once #2832 is fixed, withdefault_alias_rule = "opt"directly):foo's source imports the crate ashyper1427(e.g.use hyper1427::Body;). Compile fails withunresolved import hyper1427because the alias dict key doesn't matchdep.crate_info.owner.Proposed fix
Use the underlying library's owner when the alias key is itself a
crate_info-providing target:This is what we carry as a local patch (
0010-allow-using-aliased-crate-in-aliases-attr.patch) against 0.70.0. Happy to send a PR if the maintainers agree.Versions