diff --git a/bin/printenv.ml b/bin/printenv.ml index fb32e79cc64..ea8ff12be24 100644 --- a/bin/printenv.ml +++ b/bin/printenv.ml @@ -7,12 +7,13 @@ let dump sctx ~dir = let module Link_flags = Dune_rules.Link_flags in let module Ocaml_flags = Dune_rules.Ocaml_flags in let module Js_of_ocaml = Dune_rules.Js_of_ocaml in + let module Menhir_env = Dune_rules.Menhir_env in let node = Super_context.env_node sctx ~dir in let open Memo.O in let ocaml_flags = node >>= Env_node.ocaml_flags in let foreign_flags = node >>| Env_node.foreign_flags in let link_flags = node >>= Env_node.link_flags in - let menhir_flags = node >>| Env_node.menhir_flags in + let menhir = node >>= Env_node.menhir in let coq_flags = node >>= Env_node.coq_flags in let js_of_ocaml = node >>= Env_node.js_of_ocaml in let open Action_builder.O in @@ -30,8 +31,8 @@ let dump sctx ~dir = let* link_flags = Action_builder.of_memo link_flags in Link_flags.dump link_flags and+ menhir_dump = - let+ flags = Action_builder.of_memo_join menhir_flags in - [ "menhir_flags", flags ] |> List.map ~f:Dune_lang.Encoder.(pair string (list string)) + let* env = Action_builder.of_memo menhir in + Menhir_env.dump env and+ coq_dump = Action_builder.of_memo_join coq_flags >>| Dune_rules.Coq.Coq_flags.dump and+ jsoo_dump = let* jsoo = Action_builder.of_memo js_of_ocaml in diff --git a/doc/changes/9512.md b/doc/changes/9512.md new file mode 100644 index 00000000000..5e6adc1eb84 --- /dev/null +++ b/doc/changes/9512.md @@ -0,0 +1,6 @@ +- Menhir: generate `.conflicts` file by default. Add new field to the `(menhir)` + stanza to control the generation of this file: `(explain )`. + Introduce `(menhir (flags ...) (explain ...))` field in the `(env)` stanza, + delete `(menhir_flags)` field. All changes are guarded under a new version of + the Menhir extension, 3.0. + (#9512, @nojb) diff --git a/doc/stanzas/env.rst b/doc/stanzas/env.rst index 370ce3adbbb..774f36d17b2 100644 --- a/doc/stanzas/env.rst +++ b/doc/stanzas/env.rst @@ -32,7 +32,13 @@ Fields supported in ```` are: variables to the environment where the build commands are executed and are used by ``dune exec``. -- ``(menhir_flags ))`` specifies flags for Menhir stanzas. +- ``(menhir_flags ))`` specifies flags for Menhir stanzas. This flag was + replaced by the ``(menhir)`` field (see below) starting in version 3.0 of the + Menhir extension. + +- ``(menhir (flags ))`` specifies the Menhir + settings. See `menhir`_ for more details. This field was introduced in version + 3.0 of the Menhir extension. - ``(js_of_ocaml (flags )(build_runtime )(link_flags ))`` specifies ``js_of_ocaml`` flags. See `jsoo-field`_ for more details. diff --git a/doc/stanzas/menhir.rst b/doc/stanzas/menhir.rst index 9f44f55e2ab..1c7e63e96c1 100644 --- a/doc/stanzas/menhir.rst +++ b/doc/stanzas/menhir.rst @@ -40,4 +40,14 @@ Menhir supports writing the grammar and automation to the ``.cmly`` file. Therefore, if this is flag is passed to Menhir, Dune will know to introduce a ``.cmly`` target for the module. +- ``(explain )`` is used to control the generation of the + ``.conflicts`` file explaining conflicts found while generating the + parser. The condition is specified using the + :doc:`reference/boolean-language`. This field was introduced in version 3.0 of + the Menhir extension. + +Note that starting in version 3.0 of the Menhir extension, the ``.conflicts`` +file is generated by default. If this is not desired, it needs to be disabled +explicitly by using the ``(explain)`` field. + .. _menhir-git: https://gitlab.inria.fr/fpottier/menhir diff --git a/src/dune_lang/blang.ml b/src/dune_lang/blang.ml index a3cad320a2d..3eb02e0d88b 100644 --- a/src/dune_lang/blang.ml +++ b/src/dune_lang/blang.ml @@ -15,6 +15,17 @@ module Ast = struct let true_ = Const true let false_ = Const false + let rec equal f t1 t2 = + match t1, t2 with + | Const b1, Const b2 -> Bool.equal b1 b2 + | Not t1, Not t2 -> equal f t1 t2 + | Expr x1, Expr x2 -> f x1 x2 + | And tl1, And tl2 | Or tl1, Or tl2 -> List.equal (equal f) tl1 tl2 + | Compare (op1, x1, y1), Compare (op2, x2, y2) -> + Relop.equal op1 op2 && f x1 x2 && f y1 y2 + | (Const _ | Not _ | Expr _ | And _ | Or _ | Compare _), _ -> false + ;; + let rec to_dyn string_to_dyn = let open Dyn in function @@ -72,3 +83,4 @@ let false_ = Ast.false_ let to_dyn = Ast.to_dyn String_with_vars.to_dyn let decode = Ast.decode String_with_vars.decode let encode = Ast.encode String_with_vars.encode +let equal = Ast.equal String_with_vars.equal diff --git a/src/dune_lang/blang.mli b/src/dune_lang/blang.mli index e59d0c80c98..c4b560d8739 100644 --- a/src/dune_lang/blang.mli +++ b/src/dune_lang/blang.mli @@ -18,6 +18,7 @@ val false_ : t val to_dyn : t -> Dyn.t val decode : t Decoder.t val encode : t Encoder.t +val equal : t -> t -> bool module Ast : sig type 'string t = 'string ast diff --git a/src/dune_rules/dune_env.ml b/src/dune_rules/dune_env.ml index 0a219f9133e..8b3a018b08a 100644 --- a/src/dune_rules/dune_env.ml +++ b/src/dune_rules/dune_env.ml @@ -10,12 +10,14 @@ let foreign_flags ~since = Foreign_language.Dict.make ~c ~cxx ;; -let menhir_flags ~since = +let menhir_flags ~since ~deleted_in = let decode = - let decode = Ordered_set_lang.Unexpanded.decode in - match since with - | None -> decode - | Some since -> Dune_lang.Syntax.since Menhir_stanza.syntax since >>> decode + Dune_lang.Syntax.since Menhir_stanza.syntax since + >>> Dune_lang.Syntax.deleted_in + ~extra_info:"Use (menhir (flags ...)) instead." + Menhir_stanza.syntax + deleted_in + >>> Ordered_set_lang.Unexpanded.decode in field_o "menhir_flags" decode ;; @@ -75,7 +77,7 @@ type config = ; env_vars : Env.t ; binaries : File_binding.Unexpanded.t list option ; inline_tests : Inline_tests.t option - ; menhir_flags : Ordered_set_lang.Unexpanded.t option + ; menhir : Ordered_set_lang.Unexpanded.t Menhir_env.t ; odoc : Odoc.t ; js_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t ; coq : Coq_env.t @@ -97,7 +99,7 @@ let equal_config ; env_vars ; binaries ; inline_tests - ; menhir_flags + ; menhir ; odoc ; js_of_ocaml ; coq @@ -117,7 +119,7 @@ let equal_config && Env.equal env_vars t.env_vars && Option.equal (List.equal File_binding.Unexpanded.equal) binaries t.binaries && Option.equal Inline_tests.equal inline_tests t.inline_tests - && Option.equal Ordered_set_lang.Unexpanded.equal menhir_flags t.menhir_flags + && Menhir_env.equal menhir t.menhir && Odoc.equal odoc t.odoc && Coq_env.equal coq t.coq && Option.equal Format_config.equal format_config t.format_config @@ -136,7 +138,7 @@ let empty_config = ; env_vars = Env.empty ; binaries = None ; inline_tests = None - ; menhir_flags = None + ; menhir = Menhir_env.empty ; odoc = Odoc.empty ; js_of_ocaml = Js_of_ocaml.Env.empty ; coq = Coq_env.default @@ -209,6 +211,12 @@ let odoc_field = (Dune_lang.Syntax.since Stanza.syntax (2, 4) >>> Odoc.decode) ;; +let menhir_field ~since = + field_o + "menhir" + (Dune_lang.Syntax.since Menhir_stanza.syntax since >>> Menhir_env.decode) +;; + let js_of_ocaml_field = field "js_of_ocaml" @@ -229,19 +237,28 @@ let config = "binaries" (Dune_lang.Syntax.since Stanza.syntax (1, 6) >>> File_binding.Unexpanded.L.decode) and+ inline_tests = inline_tests_field - and+ menhir_flags = menhir_flags ~since:(Some (2, 1)) + and+ menhir = menhir_field ~since:Menhir_stanza.explain_since + and+ menhir_flags = menhir_flags ~since:(2, 1) ~deleted_in:Menhir_stanza.explain_since and+ odoc = odoc_field and+ js_of_ocaml = js_of_ocaml_field and+ coq = Coq_env.decode and+ format_config = Format_config.field ~since:(2, 8) and+ bin_annot = bin_annot in + let menhir = + match menhir_flags, menhir with + | Some flags, None -> { Menhir_env.empty with flags } + | None, Some env -> env + | None, None -> Menhir_env.empty + | Some _, Some _ -> + Code_error.raise "(menhir_flags) and (menhir) cannot both be present" [] + in { flags ; foreign_flags ; link_flags ; env_vars ; binaries ; inline_tests - ; menhir_flags + ; menhir ; odoc ; js_of_ocaml ; coq diff --git a/src/dune_rules/dune_env.mli b/src/dune_rules/dune_env.mli index bbe0aa39188..a1d46d8c330 100644 --- a/src/dune_rules/dune_env.mli +++ b/src/dune_rules/dune_env.mli @@ -27,7 +27,7 @@ type config = ; env_vars : Env.t ; binaries : File_binding.Unexpanded.t list option ; inline_tests : Inline_tests.t option - ; menhir_flags : Ordered_set_lang.Unexpanded.t option + ; menhir : Ordered_set_lang.Unexpanded.t Menhir_env.t ; odoc : Odoc.t ; js_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t ; coq : Coq_env.t diff --git a/src/dune_rules/dune_rules.ml b/src/dune_rules/dune_rules.ml index 85517881e50..4d571e1b305 100644 --- a/src/dune_rules/dune_rules.ml +++ b/src/dune_rules/dune_rules.ml @@ -6,6 +6,7 @@ module Env_node = Env_node module Link_flags = Link_flags module Ocaml_flags = Ocaml_flags module Js_of_ocaml = Js_of_ocaml +module Menhir_env = Menhir_env module Super_context = Super_context module Compilation_context = Compilation_context module Colors = Colors diff --git a/src/dune_rules/env_node.ml b/src/dune_rules/env_node.ml index 5429d3415ef..830b62bfaf4 100644 --- a/src/dune_rules/env_node.ml +++ b/src/dune_rules/env_node.ml @@ -8,7 +8,7 @@ type t = ; link_flags : Link_flags.t Memo.Lazy.t ; external_env : Env.t Memo.Lazy.t ; artifacts : Artifacts.t Memo.Lazy.t - ; menhir_flags : string list Action_builder.t Memo.Lazy.t + ; menhir : string list Action_builder.t Menhir_env.t Memo.Lazy.t ; js_of_ocaml : string list Action_builder.t Js_of_ocaml.Env.t Memo.Lazy.t ; coq_flags : Coq_flags.t Action_builder.t Memo.Lazy.t } @@ -21,7 +21,7 @@ let link_flags t = Memo.Lazy.force t.link_flags let external_env t = Memo.Lazy.force t.external_env let artifacts t = Memo.Lazy.force t.artifacts let js_of_ocaml t = Memo.Lazy.force t.js_of_ocaml -let menhir_flags t = Memo.Lazy.force t.menhir_flags |> Action_builder.of_memo_join +let menhir t = Memo.Lazy.force t.menhir let coq_flags t = Memo.Lazy.force t.coq_flags let expand_str_lazy expander sw = @@ -139,16 +139,17 @@ let make ~default:link_flags ~eval:(Expander.expand_and_eval_set expander)) in - let menhir_flags = + let menhir = inherited - ~field:(fun t -> Memo.return (menhir_flags t)) - ~root:(Action_builder.return []) - (fun flags -> - match config.menhir_flags with - | None -> Memo.return flags - | Some menhir_flags -> - let+ expander = Memo.Lazy.force expander in - Expander.expand_and_eval_set expander menhir_flags ~standard:flags) + ~field:menhir + ~root:(Menhir_env.map ~f:Action_builder.return Menhir_env.default) + (fun (menhir : _ Action_builder.t Menhir_env.t) -> + let local = config.menhir in + let+ expander = Memo.Lazy.force expander in + let flags = + Expander.expand_and_eval_set expander local.flags ~standard:menhir.flags + in + { Menhir_env.flags; explain = Option.first_some local.explain menhir.explain }) in let coq_flags : Coq_flags.t Action_builder.t Memo.Lazy.t = inherited @@ -178,7 +179,7 @@ let make ; artifacts ; local_binaries ; js_of_ocaml - ; menhir_flags + ; menhir ; coq_flags } ;; diff --git a/src/dune_rules/env_node.mli b/src/dune_rules/env_node.mli index 7256d4cb36e..8b921053384 100644 --- a/src/dune_rules/env_node.mli +++ b/src/dune_rules/env_node.mli @@ -31,4 +31,4 @@ val local_binaries : t -> File_binding.Expanded.t list Memo.t val artifacts : t -> Artifacts.t Memo.t val coq_flags : t -> Coq_flags.t Action_builder.t Memo.t -val menhir_flags : t -> string list Action_builder.t +val menhir : t -> string list Action_builder.t Menhir_env.t Memo.t diff --git a/src/dune_rules/menhir/menhir_env.ml b/src/dune_rules/menhir/menhir_env.ml new file mode 100644 index 00000000000..23a83ee0ae2 --- /dev/null +++ b/src/dune_rules/menhir/menhir_env.ml @@ -0,0 +1,34 @@ +open Import + +type 'a t = + { flags : 'a + ; explain : Blang.t option + } + +let map ~f t = { t with flags = f t.flags } + +let equal { flags; explain } t = + Ordered_set_lang.Unexpanded.equal flags t.flags + && Option.equal Blang.equal explain t.explain +;; + +let decode = + let open Dune_lang.Decoder in + fields + @@ let+ flags = Ordered_set_lang.Unexpanded.field "flags" + and+ explain = field_o "explain" Blang.decode in + { flags; explain } +;; + +let empty = { flags = Ordered_set_lang.Unexpanded.standard; explain = None } +let default = { flags = []; explain = None } + +let dump t = + let open Action_builder.O in + let+ flags = t.flags in + List.map + ~f:Dune_lang.Encoder.(pair string Fun.id) + [ "menhir_flags", Dune_lang.Encoder.(list string) flags + ; "menhir_explain", Dune_lang.Encoder.option Blang.encode t.explain + ] +;; diff --git a/src/dune_rules/menhir/menhir_env.mli b/src/dune_rules/menhir/menhir_env.mli new file mode 100644 index 00000000000..f2f89a71693 --- /dev/null +++ b/src/dune_rules/menhir/menhir_env.mli @@ -0,0 +1,13 @@ +open Import + +type 'a t = + { flags : 'a + ; explain : Blang.t option + } + +val map : f:('a -> 'b) -> 'a t -> 'b t +val equal : Ordered_set_lang.Unexpanded.t t -> Ordered_set_lang.Unexpanded.t t -> bool +val decode : Ordered_set_lang.Unexpanded.t t Dune_lang.Decoder.t +val empty : Ordered_set_lang.Unexpanded.t t +val default : string list t +val dump : string list Action_builder.t t -> Dune_lang.t list Action_builder.t diff --git a/src/dune_rules/menhir/menhir_rules.ml b/src/dune_rules/menhir/menhir_rules.ml index b008bb279d8..4ced175ab18 100644 --- a/src/dune_rules/menhir/menhir_rules.ml +++ b/src/dune_rules/menhir/menhir_rules.ml @@ -57,6 +57,12 @@ module Run (P : PARAMS) = struct let build_dir = Super_context.context sctx |> Context.build_dir let expander = Super_context.expander ~dir sctx + let env = + let open Memo.O in + let* env = Super_context.env_node ~dir sctx in + Env_node.menhir env + ;; + let sandbox = let scope = Compilation_context.scope cctx in let project = Scope.project scope in @@ -120,15 +126,31 @@ module Run (P : PARAMS) = struct Super_context.add_rule sctx ~dir ~mode ~loc:stanza.loc ;; - let expand_flags flags = - let standard = - Action_builder.of_memo @@ Super_context.env_node sctx ~dir >>= Env_node.menhir_flags + let explain_flags base stanza = + let open Memo.O in + let* expander = expander + and* env = env in + let+ explain = + match Option.first_some stanza.Menhir_stanza.explain env.Menhir_env.explain with + | None -> Memo.return (stanza.menhir_syntax >= Menhir_stanza.explain_since) + | Some explain -> Expander.eval_blang expander explain in + if explain + then + [ Command.Args.A "--explain" + ; Hidden_targets [ Path.Build.relative dir (base ^ ".conflicts") ] + ] + else [] + ;; + + let expand_flags flags = + let open Memo.O in + let+ env = env + and+ expander = expander in Action_builder.memoize ~cutoff:(List.equal String.equal) "menhir flags" - (let* expander = Action_builder.of_memo expander in - Expander.expand_and_eval_set expander flags ~standard) + (Expander.expand_and_eval_set expander flags ~standard:env.Menhir_env.flags) ;; (* ------------------------------------------------------------------------ *) @@ -162,6 +184,15 @@ module Run (P : PARAMS) = struct Ordered_set_lang.Unexpanded.fold_strings stanza.flags ~init:() ~f:(fun _pos sw () -> match String_with_vars.text_only sw with | None -> () + | Some "--explain" -> + if stanza.menhir_syntax >= Menhir_stanza.explain_since + then + User_error.raise + ~loc:(String_with_vars.loc sw) + [ Pp.textf + "The Menhir '.conflicts' file is generated by default, so '--explain' \ + should not be explicitly added to the list of Menhir flags." + ] | Some text -> if List.mem ~equal:String.equal @@ -186,7 +217,7 @@ module Run (P : PARAMS) = struct let process3 base ~cmly (stanza : stanza) : unit Memo.t = let open Memo.O in - let expanded_flags = expand_flags stanza.flags in + let* expanded_flags = expand_flags stanza.flags in (* 1. A first invocation of Menhir creates a mock [.ml] file. *) let* () = menhir @@ -225,9 +256,11 @@ module Run (P : PARAMS) = struct let* () = Module_compilation.ocamlc_i ~deps cctx mock_module ~output:(inferred_mli base) in + let* explain_flags = explain_flags base stanza in (* 3. A second invocation of Menhir reads the inferred [.mli] file. *) menhir [ Command.Args.dyn expanded_flags + ; S explain_flags ; Deps (sources stanza.modules) ; A "--base" ; Path (Path.relative (Path.build dir) base) @@ -244,9 +277,12 @@ module Run (P : PARAMS) = struct is a simpler one-step process where Menhir is invoked directly. *) let process1 base ~cmly (stanza : stanza) : unit Memo.t = - let expanded_flags = expand_flags stanza.flags in + let open Memo.O in + let* expanded_flags = expand_flags stanza.flags + and* explain_flags = explain_flags base stanza in menhir [ Command.Args.dyn expanded_flags + ; S explain_flags ; Deps (sources stanza.modules) ; A "--base" ; Path (Path.relative (Path.build dir) base) diff --git a/src/dune_rules/menhir/menhir_stanza.ml b/src/dune_rules/menhir/menhir_stanza.ml index 48d908b7e71..587cf7aa238 100644 --- a/src/dune_rules/menhir/menhir_stanza.ml +++ b/src/dune_rules/menhir/menhir_stanza.ml @@ -8,6 +8,7 @@ let syntax = ; (1, 1), `Since (1, 4) ; (2, 0), `Since (1, 4) ; (2, 1), `Since (2, 2) + ; (3, 0), `Since (3, 13) ] ;; @@ -21,8 +22,12 @@ type t = ; loc : Loc.t ; infer : bool ; enabled_if : Blang.t + ; explain : Blang.t option + ; menhir_syntax : Syntax.Version.t } +let explain_since = 3, 0 + let decode = fields (let+ merge_into = field_o "merge_into" string @@ -32,13 +37,16 @@ let decode = and+ infer = field_o_b "infer" ~check:(Dune_lang.Syntax.since syntax (2, 0)) and+ menhir_syntax = Dune_lang.Syntax.get_exn syntax and+ enabled_if = Enabled_if.decode ~allowed_vars:Any ~since:(Some (1, 4)) () - and+ loc = loc in + and+ loc = loc + and+ explain = + field_o "explain" (Dune_lang.Syntax.since syntax explain_since >>> Blang.decode) + in let infer = match infer with | Some infer -> infer | None -> menhir_syntax >= (2, 0) in - { merge_into; flags; modules; mode; loc; infer; enabled_if }) + { merge_into; flags; modules; mode; loc; infer; enabled_if; explain; menhir_syntax }) ;; include Stanza.Make (struct diff --git a/src/dune_rules/menhir/menhir_stanza.mli b/src/dune_rules/menhir/menhir_stanza.mli index ccc68291d00..c836455e4be 100644 --- a/src/dune_rules/menhir/menhir_stanza.mli +++ b/src/dune_rules/menhir/menhir_stanza.mli @@ -10,8 +10,11 @@ type t = ; loc : Loc.t ; infer : bool ; enabled_if : Blang.t + ; explain : Blang.t option + ; menhir_syntax : Syntax.Version.t } +val explain_since : Syntax.Version.t val modules : t -> string list (** Return the list of targets that are generated by this stanza. This list of diff --git a/test/blackbox-tests/test-cases/menhir/explain.t/parser.mly b/test/blackbox-tests/test-cases/menhir/explain.t/parser.mly new file mode 100644 index 00000000000..07e5ea5db3a --- /dev/null +++ b/test/blackbox-tests/test-cases/menhir/explain.t/parser.mly @@ -0,0 +1,4 @@ +%token START +%start start +%% +start: START { 42 } diff --git a/test/blackbox-tests/test-cases/menhir/explain.t/run.t b/test/blackbox-tests/test-cases/menhir/explain.t/run.t new file mode 100644 index 00000000000..ffd098ccc02 --- /dev/null +++ b/test/blackbox-tests/test-cases/menhir/explain.t/run.t @@ -0,0 +1,205 @@ +Support (explain) field in (menhir) stanza to produce .conflicts file: + + $ cat >dune < (menhir (modules parser) (explain true)) + > (library (name lib)) + > EOF + +First we check the version guards: + + $ cat >dune-project < (lang dune 3.12) + > (using menhir 2.1) + > EOF + + $ dune build + File "dune", line 1, characters 25-39: + 1 | (menhir (modules parser) (explain true)) + ^^^^^^^^^^^^^^ + Error: 'explain' is only available since version 3.0 of the menhir extension. + Please update your dune-project file to have (using menhir 3.0). + [1] + + $ cat >dune-project < (lang dune 3.12) + > (using menhir 3.0) + > EOF + + $ dune build + File "dune-project", line 2, characters 14-17: + 2 | (using menhir 3.0) + ^^^ + Error: Version 3.0 of the menhir extension is not supported until version + 3.13 of the dune language. + Supported versions of this extension in version 3.12 of the dune language: + - 1.0 to 1.1 + - 2.0 to 2.1 + [1] + + $ cat >dune-project < (lang dune 3.13) + > (using menhir 3.0) + > EOF + + $ dune build + +Let's check that the conflicts file has been generated successfully: + + $ test -f _build/default/parser.conflicts + +Let's check we can also pass `(explain false)`: + + $ cat >dune < (menhir (modules parser) (explain false)) + > (library (name lib)) + > EOF + + $ dune build + + $ ! test -f _build/default/parser.conflicts + +Let's check that it is generated by default if we omit the (explain) field: + + $ cat >dune < (menhir (modules parser)) + > (library (name lib)) + > EOF + + $ dune build + + $ test -f _build/default/parser.conflicts + +... but only if the Dune version is recent enough: + + $ cat >dune-project < (lang dune 3.13) + > (using menhir 2.1) + > EOF + + $ dune build + + $ ! test -f _build/default/parser.conflicts + +Let's check that the argument to (explain) can be a blang: + + $ cat >dune-project < (lang dune 3.13) + > (using menhir 3.0) + > EOF + + $ cat >dune < (menhir (modules parser) (explain (= true false))) + > (library (name lib)) + > EOF + + $ dune build + + $ ! test -f _build/default/parser.conflicts + +Let's check that we get a warning if we use --explain with the new mode + + $ cat >dune-project < (lang dune 3.13) + > (using menhir 3.0) + > EOF + + $ cat >dune < (menhir (modules parser) (flags --explain)) + > (library (name lib)) + > EOF + + $ dune build + File "dune", line 1, characters 32-41: + 1 | (menhir (modules parser) (flags --explain)) + ^^^^^^^^^ + Error: The Menhir '.conflicts' file is generated by default, so '--explain' + should not be explicitly added to the list of Menhir flags. + [1] + +Let's now test the new field of (env), (menhir): + + $ cat >dune-project < (lang dune 3.12) + > (using menhir 2.1) + > EOF + + $ cat >dune < (env (_ (menhir (explain false)))) + > (menhir (modules parser)) + > (library (name lib)) + > EOF + + $ dune build + File "dune", line 1, characters 8-32: + 1 | (env (_ (menhir (explain false)))) + ^^^^^^^^^^^^^^^^^^^^^^^^ + Error: 'menhir' is only available since version 3.0 of the menhir extension. + Please update your dune-project file to have (using menhir 3.0). + [1] + + $ cat >dune-project < (lang dune 3.13) + > (using menhir 3.0) + > EOF + + $ cat >dune < (env (_ (menhir_flags --explain))) + > (menhir (modules parser)) + > (library (name lib)) + > EOF + + $ dune build + File "dune", line 1, characters 8-32: + 1 | (env (_ (menhir_flags --explain))) + ^^^^^^^^^^^^^^^^^^^^^^^^ + Error: 'menhir_flags' was deleted in version 3.0 of the menhir extension. Use + (menhir (flags ...)) instead. + [1] + + $ cat >dune < (env (_ (menhir (explain false)))) + > (menhir (modules parser)) + > (library (name lib)) + > EOF + + $ dune build + + $ ! test -f _build/default/parser.conflicts + + $ cat >dune < (env (_ (menhir (explain false)))) + > (menhir (modules parser) (explain true)) + > (library (name lib)) + > EOF + + $ dune build + + $ test -f _build/default/parser.conflicts + +Also in subdirectories: + + $ mkdir -p sub + $ cp parser.mly sub/parser2.mly + + $ cat >sub/dune < (menhir (modules parser2)) + > (library (name lib2)) + > EOF + + $ dune printenv sub | grep menhir + (menhir_flags ()) + (menhir_explain (false)) + + $ dune build @sub/all + + $ ! test -f _build/default/sub/parser2.conflicts + + $ true >dune + + $ dune printenv sub | grep menhir + (menhir_flags ()) + (menhir_explain ()) + + $ dune build @sub/all + + $ test _build/default/sub/parser2.conflicts diff --git a/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t b/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t index 44443030bdd..bd7c0a3cf09 100644 --- a/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t +++ b/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t @@ -11,6 +11,7 @@ Workspaces also allow you to set the env for a context: (cxx_flags ()) (link_flags ()) (menhir_flags ()) + (menhir_explain ()) (coq_flags (-q)) (coqdoc_flags (--toc)) (js_of_ocaml_flags ())