Skip to content

test: single-module consumer unreferenced-dep regression guard#14308

Merged
robinbb merged 2 commits into
ocaml:mainfrom
robinbb:robinbb-test-single-module-unreferenced-lib
Apr 29, 2026
Merged

test: single-module consumer unreferenced-dep regression guard#14308
robinbb merged 2 commits into
ocaml:mainfrom
robinbb:robinbb-test-single-module-unreferenced-lib

Conversation

@robinbb
Copy link
Copy Markdown
Collaborator

@robinbb robinbb commented Apr 23, 2026

Summary

Adds a blackbox cram test recording the rebuild-target count for a
single-module consumer library whose only module references no module
of its declared dependency.

On current main the count is 1: consumer_lib is a single-module
stanza, so dune skips ocamldep for it and falls back to a glob over
dep_lib's object directory, which is invalidated by the cmi change.
This corner is distinct from the one documented by
test-cases/per-module-lib-deps/single-module-lib.t (single-module
consumer that references some modules of a multi-module dep): a
future fix that drops a lib dep when ocamldep yields zero references
to it could tighten this corner to 0 without needing to solve the
broader single-module-consumer skip-ocamldep limitation.

Related: #4572, #14116

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new blackbox cram regression test in the per-module-lib-deps suite to ensure that when a single-module consumer library does not reference any module from a declared dependency library, editing the dependency’s implementation (without a signature change) does not trigger recompilation of the consumer.

Changes:

  • Add a new cram test case single-module-unreferenced-lib.t that builds two unwrapped libraries where the consumer does not reference the dependency.
  • Verify via dune trace + jq that no targets related to the consumer module are rebuilt after the dependency implementation changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@robinbb robinbb marked this pull request as ready for review April 23, 2026 23:05
@robinbb robinbb assigned robinbb and unassigned robinbb Apr 24, 2026
@robinbb
Copy link
Copy Markdown
Collaborator Author

robinbb commented Apr 24, 2026

Looking for a volunteer to review.

robinbb added 2 commits April 27, 2026 07:22
Add a blackbox test in which a single-module consumer library has a
dependency library whose module it does not reference. When the
dependency's module is edited (no signature change), the consumer
module must not be recompiled. On current main, the cmi is
hash-stable under this edit, so the observed rebuild target count is
zero; the test guards against regressions of that behaviour.

The test also anchors the per-module-lib-deps surface for future
tightening work — when tighter per-module filtering lands
(ocaml#4572), this scenario remains at
zero rebuilds but for a different reason (consumer has no declared
dep on the module).

See: ocaml#14116 (comment)

Signed-off-by: Robin Bate Boerop <me@robinbb.com>
The previous form used an implementation-only edit to [modA.ml] with
no [.mli], leaving the cmi hash-stable and producing a trivially-true
rebuild-count assertion of 0 that did not exercise any aspect of
per-module library filtering.

Rewrite with [modA.mli] so the edit forces a cmi hash change. The
consumer [modB] still rebuilds on current main (count = 1) because
[libB] is a single-module stanza: dune skips ocamldep for it and the
consumer falls back to a glob over [libA]'s object directory.

This form tests a distinct corner from [single-module-lib.t] (which
covers single-module consumers that reference some but not all
modules of a multi-module dep): the zero-reference case could be
tightened to zero rebuilds by a future fix that drops the lib dep
when ocamldep yields no references, without needing to solve the
broader single-module-consumer skip-ocamldep limitation.

Signed-off-by: Robin Bate Boerop <me@robinbb.com>
@robinbb robinbb force-pushed the robinbb-test-single-module-unreferenced-lib branch from 33c4fd9 to fa0984e Compare April 27, 2026 15:40
robinbb added a commit to robinbb/dune that referenced this pull request Apr 27, 2026
Each of the dep PRs supplying a test in
[per-module-lib-deps/] was renamed per Leonidas's review on
ocaml#14309: generic [libA]/[modA1]-style names replaced by
role-bearing names like [dep_lib]/[spurious_rebuild]. This commit
applies the same renames to this PR's local copies of those tests
so they stay convergent with the dep PRs' canonical versions.

Touches:
- single-module-unreferenced-lib.t (ocaml#14308)
- sibling-unreferenced-lib.t (ocaml#14309)
- unwrapped-tight-deps.t (ocaml#14310)
- lib-vs-lib-name-collision.t (ocaml#14324)
- opaque-mli-change.t, opaque-cmx-deps-local.t (ocaml#14331)
- transitive-unreferenced-lib.t (ocaml#14332)
- wrapped-reexport-via-open-flag.t (ocaml#14346)
- auto-wrapped-child-reexport.t (ocaml#14347)

Pure rename + path/dir adjustments. Count assertions preserved
(this PR's promotions to the post-fix counts are unchanged).
Test suite passes.

Signed-off-by: Robin Bate Boerop <me@robinbb.com>
@robinbb robinbb requested a review from Copilot April 29, 2026 00:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@robinbb robinbb merged commit 7092025 into ocaml:main Apr 29, 2026
62 of 63 checks passed
@robinbb robinbb deleted the robinbb-test-single-module-unreferenced-lib branch April 29, 2026 14:52
robinbb added a commit to robinbb/dune that referenced this pull request Apr 29, 2026
Three cluster tests landed on main as observational baselines
(via PRs ocaml#14308, ocaml#14331, ocaml#14350) recording the trunk-today
rebuild list. With this PR's per-module filter applied, the
[.cmi]/[.cmti] byte rule no longer globs over a dep lib's
objdir for unreferenced sibling modules, so:

- [single-module-unreferenced-lib.t]: [spurious_rebuild]'s
  rebuild count drops from 1 to 0.
- [opaque-mli-change.t]: only the [.cmx]/[.o] native rule
  re-runs (release and dev profile both); the byte rule's deps
  no longer include the changed dep lib's [.cmi].
- [implicit-transitive-deps-false.t]: same — the [.cmx]/[.o]
  native rule re-runs, the byte rule does not.

Promote the asserted [target_files] arrays accordingly. No
behavioural surprise here — all three drops match the design
of the per-module filter; the upstream baselines exist
specifically to be flipped by this PR.

Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb added a commit to robinbb/dune that referenced this pull request Apr 29, 2026
Cluster tests landed on main as observational baselines (via PRs
ocaml#14308, ocaml#14331, ocaml#14350, and the transitive-unreferenced-module
follow-up) recording the trunk rebuild list. With this PR's
per-module filter applied, the [.cmi]/[.cmti] byte rule no longer
globs over a dep lib's objdir for unreferenced sibling modules,
so:

- [single-module-unreferenced-lib.t]: [spurious_rebuild]'s
  rebuild count drops from 1 to 0.
- [opaque-mli-change.t]: only the [.cmx]/[.o] native rule
  re-runs (release and dev profile both); the byte rule's deps
  no longer include the changed dep lib's [.cmi].
- [implicit-transitive-deps-false.t]: same — the [.cmx]/[.o]
  native rule re-runs, the byte rule does not.
- [transitive-unreferenced-module.t]: the consumer doesn't even
  directly reference the transitive lib, so the filter drops it
  entirely; both rules are skipped, [target_files] becomes [[]].

Promote the asserted [target_files] arrays accordingly. No
behavioural surprise here — all four drops match the design of
the per-module filter; the upstream baselines exist specifically
to be flipped by this PR.

Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb added a commit to robinbb/dune that referenced this pull request Apr 29, 2026
Cluster tests landed on main as observational baselines (via PRs
ocaml#14308, ocaml#14331, ocaml#14350, and the transitive-unreferenced-module
follow-up) recording the trunk rebuild list. With this PR's
per-module filter applied, the [.cmi]/[.cmti] byte rule no longer
globs over a dep lib's objdir for unreferenced sibling modules,
so:

- [single-module-unreferenced-lib.t]: [spurious_rebuild]'s
  rebuild count drops from 1 to 0.
- [opaque-mli-change.t]: only the [.cmx]/[.o] native rule
  re-runs (release and dev profile both); the byte rule's deps
  no longer include the changed dep lib's [.cmi].
- [implicit-transitive-deps-false.t]: same — the [.cmx]/[.o]
  native rule re-runs, the byte rule does not.
- [transitive-unreferenced-module.t]: the consumer doesn't even
  directly reference the transitive lib, so the filter drops it
  entirely; both rules are skipped, [target_files] becomes [[]].

Promote the asserted [target_files] arrays accordingly. No
behavioural surprise here — all four drops match the design of
the per-module filter; the upstream baselines exist specifically
to be flipped by this PR.

Signed-off-by: Robin Bate Boerop <me@robinbb.com>
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