Skip to content

[WIP] Respect --instrumentation_filter for Rust coverage#3998

Closed
tamasvajk wants to merge 10 commits intobazelbuild:mainfrom
tamasvajk:coverage-instrumentation-filter
Closed

[WIP] Respect --instrumentation_filter for Rust coverage#3998
tamasvajk wants to merge 10 commits intobazelbuild:mainfrom
tamasvajk:coverage-instrumentation-filter

Conversation

@tamasvajk
Copy link
Copy Markdown
Contributor

@tamasvajk tamasvajk commented Apr 28, 2026

Summary

Respect --instrumentation_filter when instrumenting Rust targets for coverage, consistent with Bazel's recommended approach for rules.

Problem

Previously, all Rust targets were instrumented with -Cinstrument-coverage when running bazel coverage, regardless of --instrumentation_filter. This causes:

  • Third-party and vendored crate dependencies to be unnecessarily recompiled with coverage instrumentation, slowing down builds
  • Coverage reports to include noise from code the user doesn't care about

Changes

  1. rustc.bzl: Add ctx.coverage_instrumented() check, the standard Bazel API for respecting --instrumentation_filter. Only targets matching the filter get -Cinstrument-coverage.

  2. .bazelci/presubmit.yml: Add --instrumentation_filter=^// to CI coverage tasks so that all workspace targets are instrumented (excluding external dependencies).

Usage

By default, Bazel's --instrumentation_filter is -/javatests[/:],-/test/java[/:], which instruments most targets including external dependencies. To restrict coverage to only workspace targets (recommended for Rust projects with vendored deps):

# .bazelrc
coverage --instrumentation_filter=^//

To further exclude vendored code:

coverage --instrumentation_filter=^//,-^//third_party

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

@tamasvajk tamasvajk marked this pull request as draft April 28, 2026 16:34
@tamasvajk tamasvajk marked this pull request as ready for review April 28, 2026 16:59
@tamasvajk tamasvajk force-pushed the coverage-instrumentation-filter branch 3 times, most recently from 8065153 to 077019a Compare April 28, 2026 19:08
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! Just had one question.

Comment thread .bazelci/presubmit.yml
- echo "coverage --experimental_split_coverage_postprocessing" >> user.bazelrc
- echo "build --//rust/settings:experimental_use_coverage_metadata_files" >> user.bazelrc
coverage_flags: &coverage_flags
- "--instrumentation_filter=^//"
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.

Isn't this the default? If so is it necessary?

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.

https://bazel.build/reference/command-line-reference#flag--instrumentation_filter shows the default is -/javatests[/:],-/test/java[/:]

Tamas Vajk added 6 commits May 4, 2026 08:57
Previously, all Rust targets were instrumented with
-Cinstrument-coverage when running `bazel coverage`, regardless of
--instrumentation_filter. This differs from how coverage works for
Java and C++ targets, where only targets matching the filter are
instrumented.

Add ctx.coverage_instrumented() check so that Rust coverage respects
the same filter, reducing unnecessary recompilation and keeping
coverage reports focused on the code under test.
Without an explicit --instrumentation_filter, Bazel's default filter
may not match workspace targets, causing ctx.coverage_instrumented()
to return False and producing empty Rust coverage reports.

Add coverage --instrumentation_filter=^// to both .bazelrc and all
CI coverage tasks. Projects with vendored dependencies should narrow
this, e.g.: coverage --instrumentation_filter=^//,-^//third_party
ctx.coverage_instrumented() returns False for test targets by design
(Bazel considers test sources not worth instrumenting). But Rust test
binaries statically link their dependencies, and the coverage runtime
only initializes if the binary itself is compiled with
-Cinstrument-coverage. Without this, test binaries produce no profraw
files and coverage collection fails with "no input files specified".

Always add -Cinstrument-coverage for test crates (crate_info.is_test)
when coverage is enabled, while still respecting the instrumentation
filter for library targets.
When a test target is not instrumented (e.g. due to
--instrumentation_filter), no .profraw files are produced. Previously
llvm-profdata merge would fail with "no input files specified".

Write an empty coverage file and exit successfully instead, so that
uninstrumented test targets don't break coverage collection.
The .bazelrc is inherited by sub-workspace CI tasks (cc_common_link,
bzlmod_repo_mapping, sys, pyo3) causing build/test failures. The flag
is already passed via coverage_flags in presubmit.yml for coverage tasks.
@tamasvajk tamasvajk force-pushed the coverage-instrumentation-filter branch from 077019a to 1229613 Compare May 4, 2026 08:58
The --instrumentation_filter=^// flag doesn't work correctly with
Bazel 7.4.1 for Rust coverage collection. Remove it from the
ubuntu1804 tasks so they use the default filter, which works.
@tamasvajk tamasvajk force-pushed the coverage-instrumentation-filter branch from 5211230 to bf827f9 Compare May 4, 2026 09:53
Tamas Vajk added 3 commits May 4, 2026 10:08
The empty profraw handling causes coverage to silently produce
empty data on Bazel 7.4.1 instead of going through the normal
coverage pipeline. This isn't needed since bazel coverage already
handles uninstrumented test targets gracefully.
The coverage collection wrapper does not reliably find profraw
files on Bazel 7.x, causing empty coverage reports. Remove
coverage_targets and post_shell_commands from ubuntu1804 tasks.
@tamasvajk tamasvajk changed the title Respect --instrumentation_filter for Rust coverage [WIP] Respect --instrumentation_filter for Rust coverage May 4, 2026
@tamasvajk
Copy link
Copy Markdown
Contributor Author

Closing this in favor of #4013.

@tamasvajk tamasvajk closed this May 5, 2026
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