Skip to content

rustfmt_aspect silently skips hand-written sources in targets with mixed source and generated files #3850

@arnels

Description

@arnels

Problem

When a Rust target's srcs contains a mix of hand-written source files and generated files (e.g. from a genrule), the rustfmt_aspect silently produces no output, all hand-written sources are skipped entirely.

Root cause:

The interaction between transform_sources (in utils.bzl) and _find_rustfmtable_srcs (in rustfmt.bzl) causes the problem:

  1. When rust_library (or similar) has both source and generated files in srcs, https://github.com/bazelbuild/rules_rust/blob/0.68.1/rust/private/utils.bzl#L857-L896 detects the mix and creates symlinks for all non-generated source files into the output directory (bazel-out/...), so that rustc can find everything in a single directory tree.
  2. These symlinks have is_source = False because they reside in the output directory, not the source tree. At this point, crate_info.srcs contains zero files with is_source = True, every file is either a generated file or a symlink to a hand-written file, both living under bazel-out/.
  3. https://github.com/bazelbuild/rules_rust/blob/0.68.1/rust/private/rustfmt.bzl#L50 filters with: srcs = [src for src in crate_info.srcs.to_list() if src.is_source]
  4. This returns an empty list, since every file in the transformed crate_info.srcs has is_source = False.
  5. The aspect then hits the if not srcs: return [] early-exit in _rustfmt_aspect_impl, producing no rustfmt_checks output group. The target is silently excluded from formatting.

Reproduction:

Any rust_library that mixes hand-written and generated sources will reproduce this:

  genrule(
      name = "generated",
      outs = ["generated.rs"],
      cmd = "echo 'pub fn generated() {}' > $@",
  )

  rust_library(
      name = "mylib",
      srcs = [
          "lib.rs",           # hand-written
          "helpers.rs",       # hand-written
          ":generated",       # generated
      ],
  )

Running bazel build //path/to:mylib --output_groups=rustfmt_checks will succeed trivially without actually checking any files with rustfmt.

Tested on 0.68.1. The relevant code in _find_rustfmtable_srcs has had the same is_source filter since the function was introduced, so all versions are likely affected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugneeds-triageThe ticket needs maintainer attention.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions