From 2383d6e842dedcb78863ee9fe4f5266c71111683 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Fri, 22 May 2026 21:09:47 +0100 Subject: [PATCH 1/2] test: cram test for confusing %{target} error in inferred rules Captures the current confusing 'You cannot use %{target} with inferred rules' message that fires when a rule references %{target} but omits the (target ...) field. The test asserts the situation should produce a clear error pointing at the missing field. See #12439. Signed-off-by: Ali Caglayan --- .../target-pform-without-target-field.t | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t diff --git a/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t b/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t new file mode 100644 index 00000000000..62b4a1d5e36 --- /dev/null +++ b/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t @@ -0,0 +1,17 @@ +When a rule uses %{target} but omits the (target ...) field, dune should +produce a clear error message pointing the user at the missing field. See +https://github.com/ocaml/dune/issues/12439. + + $ make_dune_project 3.24 + $ cat > dune < (rule + > (action + > (write-file %{target} hello))) + > EOF + + $ dune build + File "dune", line 3, characters 14-23: + 3 | (write-file %{target} hello))) + ^^^^^^^^^ + Error: You cannot use %{target} with inferred rules. + [1] From e5e2f06c6174284317cdea7f56f0d9f4d39bbf76 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Fri, 22 May 2026 21:12:43 +0100 Subject: [PATCH 2/2] fix: clearer error when %{target} is used without a (target ...) field Point the user at the missing field instead of mentioning 'inferred rules'. Fixes #12439. Signed-off-by: Ali Caglayan --- doc/changes/fixed/14668.md | 4 ++++ src/dune_rules/expander.ml | 3 ++- .../target-pform-without-target-field.t | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 doc/changes/fixed/14668.md diff --git a/doc/changes/fixed/14668.md b/doc/changes/fixed/14668.md new file mode 100644 index 00000000000..fdd35939054 --- /dev/null +++ b/doc/changes/fixed/14668.md @@ -0,0 +1,4 @@ +- Reword the error raised when `%{target}` is used in a rule that omits the + `(target ...)` (or `(targets ...)`) field, so it points at the missing + field instead of mentioning "inferred rules". (#14668, fixes #12439, + @Alizter) diff --git a/src/dune_rules/expander.ml b/src/dune_rules/expander.ml index 6aaacba2849..ae84bd20231 100644 --- a/src/dune_rules/expander.ml +++ b/src/dune_rules/expander.ml @@ -273,7 +273,8 @@ let[@inline never] invalid_use_of_target_variable User_error.raise ~loc:source.loc [ Pp.textf - "You cannot use %s with inferred rules." + "You cannot use %s unless the rule has a (target ...) or (targets ...) \ + field." (Dune_lang.Template.Pform.describe source) ] | Static { targets = _; multiplicity } -> diff --git a/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t b/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t index 62b4a1d5e36..13d10b392a6 100644 --- a/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t +++ b/test/blackbox-tests/test-cases/rule-target-inferrence/target-pform-without-target-field.t @@ -13,5 +13,6 @@ https://github.com/ocaml/dune/issues/12439. File "dune", line 3, characters 14-23: 3 | (write-file %{target} hello))) ^^^^^^^^^ - Error: You cannot use %{target} with inferred rules. + Error: You cannot use %{target} unless the rule has a (target ...) or + (targets ...) field. [1]