Skip to content

coverage: return InstrumentedFilesInfo from haskell_library/binary/test#2434

Open
briantopping wants to merge 1 commit into
tweag:masterfrom
briantopping:coverage-instrumentedfilesinfo
Open

coverage: return InstrumentedFilesInfo from haskell_library/binary/test#2434
briantopping wants to merge 1 commit into
tweag:masterfrom
briantopping:coverage-instrumentedfilesinfo

Conversation

@briantopping

Copy link
Copy Markdown

Problem

rules_haskell ships HPC coverage, but its rule implementations never return Bazel's InstrumentedFilesInfo. Without it, bazel coverage can't deterministically instrument the transitive Haskell libraries in a test's closure: a library is realized in both instrumented and non-instrumented configurations within one coverage //... run, and a test linking the non-instrumented variant produces no <lib>_.hpc — so its covered modules silently score 0%.

Fix

Return coverage_common.instrumented_files_info at the provider sites:

  • _haskell_binary_common_impl (haskell_binary + haskell_test): source_attributes = ["srcs"], dependency_attributes = ["deps", "narrowed_deps"].
  • haskell_library_impl: dependency_attributes additionally includes "exports".

haskell_library_impl is reused by haskell_proto_aspect via a patched-ctx struct (the existing real_ctx indirection), which isn't a genuine rule ctx and which coverage_common.instrumented_files_info rejects — so the provider is attached only for a real rule ctx (no real_ctx attribute), preserving the aspect's provider contract.

Why upstream

Generic coverage-correctness fix, nothing project-specific — any user running bazel coverage over a multi-library Haskell target gets non-deterministic transitive-library coverage today.

Verification

buildifier clean; cherry-picks cleanly onto current master. Carried in a downstream fork where it makes HPC→lcov scoring deterministic. Not yet exercised with a fresh bazel coverage on master here — happy to confirm if a maintainer prefers.

rules_haskell ships HPC coverage support, but its rule implementations
never return Bazel's InstrumentedFilesInfo. As a result `bazel coverage`
cannot deterministically instrument the transitive Haskell libraries in a
test's closure: a library can be realized in both instrumented and
non-instrumented configurations within a single `coverage //...` run, and
a test that links the non-instrumented variant produces no `<lib>_.hpc`,
so its covered modules silently score 0%.

Return `coverage_common.instrumented_files_info` at the provider sites:

  * _haskell_binary_common_impl (haskell_binary + haskell_test):
    source_attributes = ["srcs"], dependency_attributes =
    ["deps", "narrowed_deps"] (these rules have no `exports`).
  * haskell_library_impl: dependency_attributes additionally includes
    "exports".

haskell_library_impl is also reused by haskell_proto_aspect through a
patched-ctx struct (the existing `real_ctx` indirection), which is not a
genuine rule ctx and which `coverage_common.instrumented_files_info`
rejects. Attach the provider only when invoked with a real rule ctx (no
`real_ctx` attribute), preserving the aspect's provider contract.
@briantopping briantopping requested a review from avdv as a code owner June 26, 2026 16:51
@avdv

avdv commented Jun 29, 2026

Copy link
Copy Markdown
Member

Thank you!

Does this have any effect on the tests in rules_haskell_tests, e.g. the two-libs one ?

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