Skip to content

crate_universe silently drops all features and optional deps if there are no triples with host tools in supported_platform_triples #3907

@bdolgov

Description

@bdolgov

Summary

When supported_platform_triples contains only non-host targets (e.g. thumbv6m-none-eabi), crate_universe silently produces BUILD files with no crate_features and no optional dependencies, because cargo tree is never executed.

Root Cause

In cargo_tree_resolver.rs, TreeResolver::generate() computes host_triples by filtering supported_platform_triples against RUSTC_TRIPLES_WITH_HOST_TOOLS (link). Then execute_cargo_tree() iterates host_triples × target_triples (link) to spawn cargo tree processes.

When all targets passed to supported_platform_triples do not have host tools, host_triples is empty, the cartesian product is empty, zero cargo tree commands run, and the feature metadata map stays empty. All crates get generated with no features and no optional deps.

I understand that not having the host platform in supported_platform_triples is likely a mistake (proc macros won't work, etc.). But silently producing incorrect output in this case is a bug that took a significant amount of time to debug.

Reproduction

Details

MODULE.bazel:

module(
    name = "rust-rules-bug",
    version = "0.0.1",
)

bazel_dep(name = "rules_rust", version = "0.69.0")

git_override(
    module_name = "rules_rust",
    commit = "f5b713578a97eca01c449dc211a801c48f2c5ee3",
    remote = "https://github.com/bazelbuild/rules_rust.git",
)

rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")

rust.toolchain(
    edition = "2024",
    extra_target_triples = ["thumbv6m-none-eabi"],
    versions = ["1.94.0"],
)

crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
crate.from_cargo(
    cargo_lockfile = "//:Cargo.lock",
    manifests = ["//:Cargo.toml"],
    supported_platform_triples = ["thumbv6m-none-eabi"],
)
use_repo(crate, "crates")

Cargo.toml:

[package]
name = "rust-rules-bug"
version = "0.1.0"
edition = "2024"

[dependencies]
portable-atomic = { version = "1.13.1", features = ["critical-section"] }

BUILD.bazel:

load("@crates//:defs.bzl", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")

rust_library(
    name = "rust-rules-bug",
    srcs = ["src/lib.rs"],
    deps = all_crate_deps(normal = True),
)

src/lib.rs:

#![no_std]

use portable_atomic::AtomicU32;

static COUNTER: AtomicU32 = AtomicU32::new(0);

pub fn increment() -> u32 {
    COUNTER.fetch_add(1, portable_atomic::Ordering::Relaxed)
}

Expected

$ bazelisk query --output=build '@@rules_rust~~crate~crates__portable-atomic-1.13.1//:portable_atomic' | grep crate_features
  crate_features = ["critical-section", "default", "fallback"],

Actual

$ bazelisk query --output=build '@@rules_rust~~crate~crates__portable-atomic-1.13.1//:portable_atomic' | grep crate_features
(no output — crate_features is missing entirely)

Workaround

Add a host triple to supported_platform_triples:

supported_platform_triples = ["thumbv6m-none-eabi", "x86_64-unknown-linux-gnu"],

Possible Solutions

I don't have enough context to know which fix is correct here. There seem to be two places this could be addressed, each with a couple of options:

In cargo_tree_resolver.rs:

  1. Fail explicitly if jobs is empty — declare supported_platform_triples without a host triple as unsupported and surface a clear error instead of silently producing incorrect output.
  2. Handle the empty-hosts case by running cargo tree once per target triple without the HOST_TRIPLE environment override when there are no host triples in supported_platform_triples.

In crates_repository.bzl:

  1. Fail early if supported_platform_triples contains no host triples.
  2. Silently include host triples from SUPPORTED_PLATFORM_TRIPLES when none are present.

Happy to send a PR if you point me toward the preferred approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions