Skip to content

Commit 1debce3

Browse files
authored
Adding extracted_files field to rocq.extraction stanza (#13997)
This PR adds an `extracted_files` field to the `rocq.extraction` stanza. In particular, this field is used to specify files that should be produced by extraction *other than* those purely meant for OCaml extraction (the current `extracted_modules` field behavior). The primary motivation for this is the following behavior: given a Rocq extraction prelude `X.v` that extracts to Haskell and produces a file `X.hs`, a single `dune build` will produce this file, but subsequent `dune build` will wipe the `X.hs` from `_build/...`. This behavior is mitigated by this PR and specifically witnessed by the `Test rebuild does not clean extracted files:` test in `test/blackbox-tests/test-cases/rocq/extraction/extracted-files.t` --------- It is my belief that the `extracted_files` stanza could subsume `extracted_modules`: `(extracted_modules F1 ... FN) --> (extracted_files F1.ml F1.mli ... FN.ml FN.mli)`, however for compatibility I did not do this, although maybe it is worth discussing.
2 parents 8ac8db0 + 6f66894 commit 1debce3

7 files changed

Lines changed: 330 additions & 18 deletions

File tree

doc/changes/added/13997.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- `rocq.extraction`: Add `extracted_files` field in `(rocq 0.13)`, replacing
2+
`extracted_modules`, supporting extraction to languages other than OCaml
3+
(#13997, @Durbatuluk1701).

doc/rocq.rst

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ The supported Rocq language versions (not the version of Rocq) are:
374374
+ ``(mode native)`` is not allowed anymore. It is the default if Rocq was configured with native compute enabled.
375375
+ ``COQPATH`` is not recognized anymore, use ``ROCQPATH``.
376376
- ``0.12``: Support for output tests.
377+
- ``0.13``: ``rocq.extraction`` now uses ``extracted_files`` instead of
378+
``extracted_modules``, supporting extraction to languages other than OCaml.
377379

378380
.. _rocq-lang-1.0:
379381

@@ -391,21 +393,33 @@ unchanged or minimally modified.
391393
rocq.extraction
392394
---------------
393395

394-
Rocq may be instructed to *extract* OCaml sources as part of the compilation
396+
Rocq may be instructed to *extract* sources as part of the compilation
395397
process by using the ``rocq.extraction`` stanza:
396398

397399
.. code:: dune
398400
399401
(rocq.extraction
400402
(prelude <name>)
401-
(extracted_modules <names>)
403+
(extracted_files <filenames>)
402404
<optional-fields>)
403405
404406
- ``(prelude <name>)`` refers to the Rocq source that contains the extraction
405407
commands.
406408

407-
- ``(extracted_modules <names>)`` is an exhaustive list of OCaml modules
408-
extracted.
409+
- ``(extracted_files <filenames>)`` is the list of files Dune expects the
410+
extraction to produce. Each entry is a filename with its extension, for
411+
example OCaml (``.ml``, ``.mli``), Haskell (``.hs``), or Scheme (``.scm``).
412+
413+
.. versionadded:: 3.23
414+
415+
416+
.. note::
417+
418+
``(extracted_modules <names>)`` is the predecessor to ``extracted_files``,
419+
available in ``(rocq 0.12)`` and below. It accepts bare module names and
420+
expects Dune to produce both a ``.ml`` and ``.mli`` file for each. Users
421+
upgrading from ``0.12`` should replace ``(extracted_modules M1 ... Mn)``
422+
with ``(extracted_files M1.ml M1.mli ... Mn.ml Mn.mli)``.
409423

410424
- ``<optional-fields>`` are ``flags``, ``stdlib``, ``theories``, and
411425
``plugins``. All of these fields have the same meaning as in the

src/dune_rules/dir_contents.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ end = struct
177177
Path.Build.set_extension mlg_file ~ext:Filename.Extension.ml
178178
|> Path.Build.basename)
179179
| Rocq_stanza.Extraction.T s ->
180-
Memo.return (Rocq_stanza.Extraction.ml_target_fnames s)
180+
Memo.return (Rocq_stanza.Extraction.target_fnames s)
181181
| Rule_conf.T rule ->
182182
Simple_rules.user_rule sctx rule ~dir ~expander
183183
>>| (function

src/dune_rules/rocq/rocq_rules.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ let setup_extraction_rules ~sctx ~dir ~dir_contents (s : Rocq_stanza.Extraction.
12971297
let* rocq_sources = Dir_contents.rocq dir_contents in
12981298
let rocq_module = Rocq_sources.extract rocq_sources s in
12991299
let file_targets =
1300-
Rocq_stanza.Extraction.ml_target_fnames s |> List.map ~f:(Path.Build.relative dir)
1300+
Rocq_stanza.Extraction.target_fnames s |> List.map ~f:(Path.Build.relative dir)
13011301
in
13021302
let loc = s.buildable.loc in
13031303
let use_stdlib = s.buildable.use_stdlib in

src/dune_rules/rocq/rocq_stanza.ml

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let rocq_syntax =
1818
Dune_lang.Syntax.create
1919
~name:(Syntax.Name.parse "rocq")
2020
~desc:"Rocq Prover build language"
21-
[ (0, 11), `Since (3, 21); (0, 12), `Since (3, 22) ]
21+
[ (0, 11), `Since (3, 21); (0, 12), `Since (3, 22); (0, 13), `Since (3, 23) ]
2222
;;
2323

2424
let get_rocq_syntax () = Dune_lang.Syntax.get_exn rocq_syntax
@@ -70,23 +70,48 @@ end
7070

7171
module Extraction = struct
7272
type t =
73-
{ (* not a list of modules because we want to preserve whatever case Rocq
74-
uses *)
75-
extracted_modules : string list
73+
{ target_fnames : string list
7674
; prelude : Loc.t * Rocq_module.Name.t
7775
; buildable : Buildable.t
7876
}
7977

80-
let ml_target_fnames t =
81-
List.concat_map t.extracted_modules ~f:(fun m -> [ m ^ ".ml"; m ^ ".mli" ])
82-
;;
78+
let target_fnames t = t.target_fnames
8379

8480
let decode =
8581
fields
86-
(let+ extracted_modules = field "extracted_modules" (repeat string)
82+
(let* ver = get_rocq_syntax () in
83+
let+ extracted_modules_opt =
84+
field_o
85+
"extracted_modules"
86+
(Dune_lang.Syntax.deleted_in
87+
rocq_syntax
88+
(0, 13)
89+
~extra_info:
90+
"Use (extracted_files ...) instead, listing each .ml and .mli file \
91+
explicitly."
92+
>>> repeat string)
93+
and+ extracted_files_opt =
94+
field_o
95+
"extracted_files"
96+
(Dune_lang.Syntax.since rocq_syntax (0, 13) >>> repeat string)
8797
and+ prelude = field "prelude" (located (string >>| Rocq_module.Name.make))
88-
and+ buildable = Buildable.decode in
89-
{ prelude; extracted_modules; buildable })
98+
and+ buildable = Buildable.decode
99+
and+ loc = loc in
100+
let target_fnames =
101+
if ver < (0, 13)
102+
then (
103+
match extracted_modules_opt with
104+
| None ->
105+
User_error.raise ~loc [ Pp.text "Field \"extracted_modules\" is required" ]
106+
| Some modules ->
107+
List.concat_map modules ~f:(fun m -> [ m ^ ".ml"; m ^ ".mli" ]))
108+
else (
109+
match extracted_files_opt with
110+
| None ->
111+
User_error.raise ~loc [ Pp.text "Field \"extracted_files\" is required" ]
112+
| Some files -> files)
113+
in
114+
{ target_fnames; prelude; buildable })
90115
;;
91116

92117
include Stanza.Make (struct

src/dune_rules/rocq/rocq_stanza.mli

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ end
2727

2828
module Extraction : sig
2929
type t =
30-
{ extracted_modules : string list
30+
{ target_fnames : string list
3131
; prelude : Loc.t * Rocq_module.Name.t
3232
; buildable : Buildable.t
3333
}
3434

35-
val ml_target_fnames : t -> string list
35+
val target_fnames : t -> string list
3636

3737
include Stanza.S with type t := t
3838
end

0 commit comments

Comments
 (0)