aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--TODO53
-rw-r--r--dev/doc/econstr.md129
-rw-r--r--engine/proofview.ml12
-rw-r--r--ide/coqOps.ml49
-rw-r--r--ide/ide_slave.ml11
-rw-r--r--ide/session.ml2
-rw-r--r--ide/texmacspp.ml1
-rw-r--r--ide/wg_Command.ml13
-rw-r--r--ide/wg_Command.mli2
-rw-r--r--interp/coqlib.mli2
-rw-r--r--intf/vernacexpr.mli7
-rw-r--r--kernel/context.mli10
-rw-r--r--kernel/declarations.mli2
-rw-r--r--kernel/names.ml19
-rw-r--r--kernel/pre_env.ml18
-rw-r--r--lib/flags.ml16
-rw-r--r--lib/flags.mli16
-rw-r--r--library/loadpath.ml2
-rw-r--r--parsing/g_vernac.ml435
-rw-r--r--parsing/pcoq.ml2
-rw-r--r--plugins/funind/functional_principles_proofs.ml13
-rw-r--r--plugins/funind/functional_principles_proofs.mli2
-rw-r--r--plugins/funind/indfun_common.ml5
-rw-r--r--plugins/funind/indfun_common.mli5
-rw-r--r--plugins/funind/recdef.ml18
-rw-r--r--plugins/funind/recdef.mli2
-rw-r--r--plugins/ltac/g_ltac.ml42
-rw-r--r--pretyping/classops.ml2
-rw-r--r--pretyping/patternops.ml2
-rw-r--r--printing/ppvernac.ml11
-rw-r--r--proofs/proof_global.ml27
-rw-r--r--proofs/proof_global.mli1
-rw-r--r--stm/vernac_classifier.ml3
-rw-r--r--stm/workerLoop.ml2
-rw-r--r--tactics/class_tactics.ml2
-rw-r--r--tactics/hints.ml2
-rw-r--r--test-suite/bugs/closed/4306.v32
-rw-r--r--test-suite/bugs/closed/5476.v28
-rw-r--r--test-suite/output/Search.out8
-rw-r--r--test-suite/output/Search.v10
-rw-r--r--toplevel/coqtop.ml8
-rw-r--r--toplevel/vernac.ml4
-rw-r--r--vernac/command.ml2
-rw-r--r--vernac/mltop.ml4
-rw-r--r--vernac/topfmt.ml27
-rw-r--r--vernac/vernacentries.ml40
47 files changed, 409 insertions, 260 deletions
diff --git a/.travis.yml b/.travis.yml
index d35b7a8422..72ce17a09f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,6 +22,7 @@ env:
- NJOBS=2
# system is == 4.02.3
- COMPILER="system"
+ - CAMLP5_VER="6.14"
# Main test suites
matrix:
- TEST_TARGET="test-suite" COMPILER="4.02.3+32bit"
@@ -81,6 +82,7 @@ matrix:
- env:
- TEST_TARGET="test-suite"
- COMPILER="4.04.0"
+ - CAMLP5_VER="6.17"
- EXTRA_CONF="-coqide opt -with-doc yes"
- EXTRA_OPAM="lablgtk-extras hevea"
addons:
@@ -106,8 +108,8 @@ matrix:
install:
- opam init -j ${NJOBS} --compiler=${COMPILER} -n -y
- eval $(opam config env)
-- opam config var root
-- opam install -j ${NJOBS} -y camlp5 ocamlfind ${EXTRA_OPAM}
+- opam config list
+- opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind ${EXTRA_OPAM}
- opam list
script:
diff --git a/TODO b/TODO
deleted file mode 100644
index f24a37f389..0000000000
--- a/TODO
+++ /dev/null
@@ -1,53 +0,0 @@
-Langage:
-
-Distribution:
-
-Environnement:
-
-- Porter SearchIsos
-
-Noyau:
-
-Tactic:
-
-- Que contradiction raisonne a isomorphisme pres de False
-
-Vernac:
-
-- Print / Print Proof en fait identiques ; Print ne devrait pas afficher
- les constantes opaques (devrait afficher qqchose comme <opaque>)
-
-Theories:
-
-- Rendre transparent tous les theoremes prouvant {A}+{B}
-- Faire demarrer PolyList.nth a` l'indice 0
- Renommer l'actuel nth en nth1 ??
-
-Doc:
-
-- Mettre à jour les messages d'erreurs de Discriminate/Simplify_eq/Injection
-- Documenter le filtrage sur les types inductifs avec let-ins (dont la
- compatibilite V6)
-
-- Ajouter let dans les règles du CIC
- -> FAIT, mais reste a documenter le let dans les inductifs
- et les champs manifestes dans les Record
-- revoir le chapitre sur les tactiques utilisateur
-- faut-il mieux spécifier la sémantique de Simpl (??)
-
-- Préciser la clarification syntaxique de IntroPattern
-- preciser que Goal vient en dernier dans une clause pattern list et
- qu'il doit apparaitre si il y a un "in"
-
-- Omega Time debranche mais Omega System et Omega Action remarchent ?
-- Ajout "Replace in" (mais TODO)
-- Syntaxe Conditional tac Rewrite marche, à documenter
-- Documenter Dependent Rewrite et CutRewrite ?
-- Ajouter les motifs sous-termes de ltac
-
-- ajouter doc de GenFixpoint (mais avant: changer syntaxe) (J. Forest ou Pierre C.)
-- mettre à jour la doc de induction (arguments multiples) (Pierre C.)
-- mettre à jour la doc de functional induction/scheme (J. Forest ou Pierre C.)
---> mettre à jour le CHANGES (vers la ligne 72)
-
-
diff --git a/dev/doc/econstr.md b/dev/doc/econstr.md
new file mode 100644
index 0000000000..bb17e8fb62
--- /dev/null
+++ b/dev/doc/econstr.md
@@ -0,0 +1,129 @@
+# Evar-insensitive terms (EConstr)
+
+Evar-insensitive terms were introduced in 8.7, following
+[CEP #10](https://github.com/coq/ceps/blob/master/text/010-econstr.md). We will
+not recap the motivations in this document and rather summarize the code changes
+to perform.
+
+## Overview
+
+The essential datastructures are defined in
+[the `EConstr` module](/engine/eConstr.mli) module. It defines
+the tactic counterparts of kernel data structures such as terms
+(`EConstr.constr`), universes (`EConstr.ESorts.t`) and contexts
+(`EConstr.*_context`).
+
+The main difference with kernel-side types is that observing them requires
+an evar-map at hand in order to normalize evars on the fly. The basic primitive
+to observe an `EConstr.t` is the following function:
+```
+val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
+(** Same as {!Constr.kind} except that it expands evars and normalizes
+ universes on the fly. *)
+```
+
+Essentially, each time it sees an evar which happens to be defined in the
+provided evar-map, it replaces it with the corresponding body and carries on.
+
+Due to universe unification occuring at the tactic level, the same goes for
+universe instances and sorts. See the `ESort` and `EInstance` modules in
+`EConstr`.
+
+This normalization is critical for the soundness of tactics. Before EConstr, a
+lot of bugs were lurking in the code base, a few still are (most notably in
+meta-based unification) and failure to respect the guidelines thereafter may
+result in nasal demons.
+
+## Transition path
+
+### Types
+
+As a rule of thumb, all functions living at the tactic level should manipulate
+`EConstr.t` instead of `Constr.t`, and similarly for the other data structures.
+
+To ease the transition, the `EConstr` module defines a handful of aliases to
+shadow the type names from the kernel.
+
+It is recommended to perform the following replacement in headers.
+```ocaml
+(** Kernel types. You may remove the two following opens if you want. Beware
+ that [kind_of_term] needs to be in scope if you use [EConstr.kind] so that
+ you may still need to open one of the two. *)
+open Term
+open Constr
+(** Tactic types. Open this after to shadow kernel types. *)
+open EConstr
+```
+
+Note that the `EConstr` module also redefines a `Vars` submodule.
+
+### Evar-map-passing
+
+All functions deconstructing an econstr need to take an evar-map as a parameter.
+Therefore, you need to pass one as an argument virtually everywhere.
+
+In the Coq source code, it is recommended to take the evar-map as a first
+argument called `sigma`, except if the function also takes an environment in
+which case it is passed second. Namely, the two typical instances are:
+```ocaml
+let foo sigma c = mycode
+val foo : Evd.evar_map -> EConstr.t -> Foo.t
+
+let bar env sigma c = mycode
+val bar : Environ.env -> Evd.evar_map -> EConstr.t -> Bar.t
+```
+
+The EConstr API makes the code much more sensitive to evar-maps, because a
+lot of now useless normalizations were removed. Thus one should be cautious of
+**not** dropping the evar-map when it has been updated, and should rather stick
+to a strict state-passing discipline. Unsound primitives like
+`Typing.unsafe_type_of` are also a known source of problems, so you should
+replace them with the corresponding evar-map-returning function and thread it
+properly.
+
+### Functions
+
+Many functions from `Constr` and `Term` are redefined to work on econstr in
+the `EConstr` module, so that it is often enough to perform the `open` as
+described above to replace them. Their type may differ though, because they now
+need access to an evar-map. A lot of econstr-manipulating functions are also
+defined in [`Termops`](/engine/termops.mli).
+
+Functions manipulating tactic terms and kernel terms share the same name if they
+are the equivalent one of the other. Do not hesitate to grep Coq mli files to
+find the equivalent of a function you want to port if it is neither in `EConstr`
+nor in `Termops` (this should be very rare).
+
+### Conversion
+
+Sometimes you do not have any other choice than calling kernel-side functions
+on terms, and conversely to turn a kernel term into a tactic term.
+
+There are two functions to do so.
+* `EConstr.of_constr` turns kernel terms into tactic terms. It is currently
+the physical identity, and thus O(1), but this may change in the future.
+* `EConstr.to_constr` turns tactic terms into kernel terms. It performs a
+full-blown normalization of the given term, which is O(n) and potentially
+costly.
+
+For performance reasons, avoiding to jump back and forth between kernel and
+tactic terms is recommended.
+
+There are also a few unsafe conversion functions that take advantage of the
+fact that `EConstr.t` is internally the same as `Constr.t`. Namely,
+`EConstr.Unsafe.to_constr` is the physical identity. It should **not** be used
+in typical code and is instead provided for efficiency **when you know what you
+are doing**. Either use it to reimplement low-level functions that happen to
+be insensitive externally, or use it to provide backward compatibility with
+broken code that relies on evar-sensitivity. **Do not use it because it is
+easier than stuffing evar-maps everywhere.** You've been warned.
+
+## Notes
+
+The EConstr branch fixed a lot of eisenbugs linked to lack of normalization
+everywhere, most notably in unification. It may also have introduced a few, so
+if you see a change in behaviour *that looks like a bug*, please report it.
+Obviously, unification is not specified, so it's hard to tell apart, but still.
+
+Efficiency has been affected as well. We now pay an overhead when observing a
+term, but at the same time a lot of costly upfront normalizations were removed.
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 9c264439be..f054038e9c 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -1020,11 +1020,11 @@ module Goal = struct
let assume (gl : ('a, 'r) t) = (gl :> ([ `NF ], 'r) t)
- let env { env=env } = env
- let sigma { sigma=sigma } = Sigma.Unsafe.of_evar_map sigma
- let hyps { env=env } = EConstr.named_context env
- let concl { concl=concl } = concl
- let extra { sigma=sigma; self=self } = goal_extra sigma self
+ let env {env} = env
+ let sigma {sigma} = Sigma.Unsafe.of_evar_map sigma
+ let hyps {env} = EConstr.named_context env
+ let concl {concl} = concl
+ let extra {sigma; self} = goal_extra sigma self
let gmake_with info env sigma goal =
{ env = Environ.reset_with_named_context (Evd.evar_filtered_hyps info) env ;
@@ -1040,7 +1040,7 @@ module Goal = struct
let nf_enter f =
InfoL.tag (Info.Dispatch) begin
iter_goal begin fun goal ->
- Env.get >>= fun env ->
+ tclENV >>= fun env ->
tclEVARMAP >>= fun sigma ->
try
let (gl, sigma) = nf_gmake env sigma goal in
diff --git a/ide/coqOps.ml b/ide/coqOps.ml
index eb97755fa6..222b9eed9f 100644
--- a/ide/coqOps.ml
+++ b/ide/coqOps.ml
@@ -366,6 +366,9 @@ object(self)
(* This method is intended to perform stateless commands *)
method raw_coq_query phrase =
+ let sid = try Document.tip document
+ with Document.Empty -> Stateid.initial
+ in
let action = log "raw_coq_query starting now" in
let display_error s =
if not (validate s) then
@@ -373,11 +376,10 @@ object(self)
else messages#add s;
in
let query =
- Coq.query (phrase,Stateid.dummy) in
+ Coq.query (phrase,sid) in
let next = function
| Fail (_, _, err) -> display_error err; Coq.return ()
- | Good msg ->
- messages#add_string msg; Coq.return ()
+ | Good msg -> Coq.return ()
in
Coq.bind (Coq.seq action query) next
@@ -414,12 +416,9 @@ object(self)
buffer#apply_tag Tags.Script.tooltip ~start ~stop;
add_tooltip sentence pre post markup
- method private is_dummy_id id = Stateid.equal id Stateid.dummy
-
method private enqueue_feedback msg =
- (* Minilib.log ("Feedback received: " ^ Xml_printer.to_string_fmt (Xmlprotocol.of_feedback msg)); *)
- let id = msg.id in
- if self#is_dummy_id id then () else Queue.add msg feedbacks
+ (* Minilib.log ("Feedback received: " ^ Xml_printer.to_string_fmt Xmlprotocol.(of_feedback Ppcmds msg)); *)
+ Queue.add msg feedbacks
method private process_feedback () =
let rec eat_feedback n =
@@ -433,41 +432,41 @@ object(self)
| _ -> None in
try Some (Doc.find_map document finder)
with Not_found -> None in
- let log_pp s state_id =
+ let log_pp ?id s=
Minilib.log_pp Pp.(seq
- [str "Feedback "; s; str " on ";
- str (Stateid.to_string (Option.default Stateid.dummy state_id))]) in
- let log s state_id = log_pp (Pp.str s) state_id in
+ [str "Feedback "; s; pr_opt (fun id -> str " on " ++ str (Stateid.to_string id)) id])
+ in
+ let log ?id s = log_pp ?id (Pp.str s) in
begin match msg.contents, sentence with
| AddedAxiom, Some (id,sentence) ->
- log "AddedAxiom" id;
+ log ?id "AddedAxiom";
remove_flag sentence `PROCESSING;
remove_flag sentence `ERROR;
add_flag sentence `UNSAFE;
self#mark_as_needed sentence
| Processed, Some (id,sentence) ->
- log "Processed" id;
+ log ?id "Processed" ;
remove_flag sentence `PROCESSING;
self#mark_as_needed sentence
| ProcessingIn _, Some (id,sentence) ->
- log "ProcessingIn" id;
+ log ?id "ProcessingIn";
add_flag sentence `PROCESSING;
self#mark_as_needed sentence
| Incomplete, Some (id, sentence) ->
- log "Incomplete" id;
+ log ?id "Incomplete";
add_flag sentence `INCOMPLETE;
self#mark_as_needed sentence
| Complete, Some (id, sentence) ->
- log "Complete" id;
+ log ?id "Complete";
remove_flag sentence `INCOMPLETE;
self#mark_as_needed sentence
| GlobRef(loc, filepath, modpath, ident, ty), Some (id,sentence) ->
- log "GlobRef" id;
+ log ?id "GlobRef";
self#attach_tooltip ~loc sentence
(Printf.sprintf "%s %s %s" filepath ident ty)
| Message(Error, loc, msg), Some (id,sentence) ->
let uloc = Option.default Loc.ghost loc in
- log_pp Pp.(str "ErrorMsg" ++ msg) id;
+ log_pp ?id Pp.(str "ErrorMsg" ++ msg);
remove_flag sentence `PROCESSING;
let rmsg = Pp.string_of_ppcmds msg in
add_flag sentence (`ERROR (uloc, rmsg));
@@ -476,22 +475,24 @@ object(self)
self#position_tag_at_sentence ?loc Tags.Script.error sentence
| Message(Warning, loc, msg), Some (id,sentence) ->
let uloc = Option.default Loc.ghost loc in
- log_pp Pp.(str "WarningMsg" ++ msg) id;
+ log_pp ?id Pp.(str "WarningMsg" ++ msg);
let rmsg = Pp.string_of_ppcmds msg in
add_flag sentence (`WARNING (uloc, rmsg));
self#attach_tooltip sentence ?loc rmsg;
self#position_tag_at_sentence ?loc Tags.Script.warning sentence;
messages#push Warning msg
| Message(lvl, loc, msg), Some (id,sentence) ->
- log_pp Pp.(str "Msg" ++ msg) id;
+ log_pp ?id Pp.(str "Msg" ++ msg);
+ messages#push lvl msg
+ | Message(lvl, loc, msg), None ->
+ log_pp Pp.(str "Msg" ++ msg);
messages#push lvl msg
| InProgress n, _ ->
if n < 0 then processed <- processed + abs n
else to_process <- to_process + n
| WorkerStatus(id,status), _ ->
- log "WorkerStatus" None;
+ log "WorkerStatus";
slaves_status <- CString.Map.add id status slaves_status
-
| _ ->
if sentence <> None then Minilib.log "Unsupported feedback message"
else if Doc.is_empty document then ()
@@ -500,7 +501,7 @@ object(self)
match id, Doc.tip document with
| id1, id2 when Stateid.newer_than id2 id1 -> ()
| _ -> Queue.add msg feedbacks
- with Doc.Empty | Invalid_argument _ -> Queue.add msg feedbacks
+ with Doc.Empty | Invalid_argument _ -> Queue.add msg feedbacks
end;
eat_feedback (n-1)
in
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index 4b95e983d6..bf86db08ff 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -63,25 +63,26 @@ let is_known_option cmd = match cmd with
(** Check whether a command is forbidden in the IDE *)
-let ide_cmd_checks (loc,ast) =
+let ide_cmd_checks ~id (loc,ast) =
let user_error s = CErrors.user_err ~loc ~hdr:"CoqIde" (str s) in
+ let warn msg = Feedback.(feedback ~id (Message (Warning, Some loc, strbrk msg))) in
if is_debug ast then
user_error "Debug mode not available in the IDE";
if is_known_option ast then
- Feedback.msg_warning ~loc (strbrk "Set this option from the IDE menu instead");
+ warn "Set this option from the IDE menu instead";
if is_navigation_vernac ast || is_undo ast then
- Feedback.msg_warning ~loc (strbrk "Use IDE navigation instead");
+ warn "Use IDE navigation instead";
if is_query ast then
- Feedback.msg_warning ~loc (strbrk "Query commands should not be inserted in scripts")
+ warn "Query commands should not be inserted in scripts"
(** Interpretation (cf. [Ide_intf.interp]) *)
let add ((s,eid),(sid,verbose)) =
let pa = Pcoq.Gram.parsable (Stream.of_string s) in
let loc_ast = Stm.parse_sentence sid pa in
- ide_cmd_checks loc_ast;
let newid, rc = Stm.add ~ontop:sid verbose loc_ast in
let rc = match rc with `NewTip -> CSig.Inl () | `Unfocus id -> CSig.Inr id in
+ ide_cmd_checks newid loc_ast;
(* TODO: the "" parameter is a leftover of the times the protocol
* used to include stderr/stdout output.
*
diff --git a/ide/session.ml b/ide/session.ml
index fc6340d283..6262820e7b 100644
--- a/ide/session.ml
+++ b/ide/session.ml
@@ -386,12 +386,12 @@ let create file coqtop_args =
let proof = create_proof () in
let messages = create_messages () in
let segment = new Wg_Segment.segment () in
- let command = new Wg_Command.command_window basename coqtop in
let finder = new Wg_Find.finder basename (script :> GText.view) in
let fops = new FileOps.fileops (buffer :> GText.buffer) file reset in
let _ = fops#update_stats in
let cops =
new CoqOps.coqops script proof messages segment coqtop (fun () -> fops#filename) in
+ let command = new Wg_Command.command_window basename coqtop cops in
let errpage = create_errpage script in
let jobpage = create_jobpage coqtop cops in
let _ = set_buffer_handlers (buffer :> GText.buffer) script cops coqtop in
diff --git a/ide/texmacspp.ml b/ide/texmacspp.ml
index e787e48bf1..e20704b7fb 100644
--- a/ide/texmacspp.ml
+++ b/ide/texmacspp.ml
@@ -504,7 +504,6 @@ let rec tmpp v loc =
xmlApply loc (Element("timeout",["val",string_of_int s],[]) ::
[tmpp e loc])
| VernacFail e -> xmlApply loc (Element("fail",[],[]) :: [tmpp e loc])
- | VernacError _ -> xmlWithLoc loc "error" [] []
(* Syntax *)
| VernacSyntaxExtension (_, ((_, name), sml)) ->
diff --git a/ide/wg_Command.ml b/ide/wg_Command.ml
index 47dad8f196..3fcb7ce49e 100644
--- a/ide/wg_Command.ml
+++ b/ide/wg_Command.ml
@@ -8,7 +8,7 @@
open Preferences
-class command_window name coqtop =
+class command_window name coqtop coqops =
let frame = Wg_Detachable.detachable
~title:(Printf.sprintf "Query pane (%s)" name) () in
let _ = frame#hide in
@@ -26,6 +26,11 @@ object(self)
val notebook = notebook
+ (* We need access to coqops in order to place queries in the proper
+ document stint. This should remove access from this module to the
+ low-level Coq one. *)
+ val coqops = coqops
+
method pack_in (f : GObj.widget -> unit) = f frame#coerce
val mutable new_page : GObj.widget = (GMisc.label ())#coerce
@@ -101,7 +106,10 @@ object(self)
else com ^ " " ^ arg ^" . "
in
let process =
- Coq.bind (Coq.query (phrase,Stateid.dummy)) (function
+ (* We need to adapt this to route_id and redirect to the result buffer below *)
+ coqops#raw_coq_query phrase
+ (*
+ Coq.bind (Coq.query (phrase,sid)) (function
| Interface.Fail (_,l,str) ->
let width = Ideutils.textview_width result in
Ideutils.insert_xml result#buffer (Richpp.richpp_of_pp width str);
@@ -111,6 +119,7 @@ object(self)
result#buffer#insert res;
notebook#set_page ~tab_label:(new_tab_lbl arg) frame#coerce;
Coq.return ())
+ *)
in
result#buffer#set_text ("Result for command " ^ phrase ^ ":\n");
Coq.try_grab coqtop process ignore
diff --git a/ide/wg_Command.mli b/ide/wg_Command.mli
index fa50ba5fdd..341322be1b 100644
--- a/ide/wg_Command.mli
+++ b/ide/wg_Command.mli
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-class command_window : string -> Coq.coqtop ->
+class command_window : string -> Coq.coqtop -> CoqOps.coqops ->
object
method new_query : ?command:string -> ?term:string -> unit -> unit
method pack_in : (GObj.widget -> unit) -> unit
diff --git a/interp/coqlib.mli b/interp/coqlib.mli
index 5ba26d8286..1facb47e1e 100644
--- a/interp/coqlib.mli
+++ b/interp/coqlib.mli
@@ -19,7 +19,7 @@ open Util
(** [find_reference caller_message [dir;subdir;...] s] returns a global
reference to the name dir.subdir.(...).s; the corresponding module
must have been required or in the process of being compiled so that
- it must be used lazyly; it raises an anomaly with the given message
+ it must be used lazily; it raises an anomaly with the given message
if not found *)
type message = string
diff --git a/intf/vernacexpr.mli b/intf/vernacexpr.mli
index 25d3c705f4..f018d59e6b 100644
--- a/intf/vernacexpr.mli
+++ b/intf/vernacexpr.mli
@@ -71,7 +71,7 @@ type printable =
| PrintScopes
| PrintScope of string
| PrintVisibility of string option
- | PrintAbout of reference or_by_notation*int option
+ | PrintAbout of reference or_by_notation * goal_selector option
| PrintImplicit of reference or_by_notation
| PrintAssumptions of bool * bool * reference or_by_notation
| PrintStrategy of reference or_by_notation option
@@ -316,7 +316,6 @@ type vernac_expr =
| VernacRedirect of string * vernac_expr located
| VernacTimeout of int * vernac_expr
| VernacFail of vernac_expr
- | VernacError of exn (* always fails *)
(* Syntax *)
| VernacSyntaxExtension of
@@ -436,11 +435,11 @@ type vernac_expr =
| VernacRemoveOption of Goptions.option_name * option_ref_value list
| VernacMemOption of Goptions.option_name * option_ref_value list
| VernacPrintOption of Goptions.option_name
- | VernacCheckMayEval of Genredexpr.raw_red_expr option * int option * constr_expr
+ | VernacCheckMayEval of Genredexpr.raw_red_expr option * goal_selector option * constr_expr
| VernacGlobalCheck of constr_expr
| VernacDeclareReduction of string * Genredexpr.raw_red_expr
| VernacPrint of printable
- | VernacSearch of searchable * int option * search_restriction
+ | VernacSearch of searchable * goal_selector option * search_restriction
| VernacLocate of locatable
| VernacRegister of lident * register_kind
| VernacComments of comment list
diff --git a/kernel/context.mli b/kernel/context.mli
index 0c666a25d9..24e69ebd6e 100644
--- a/kernel/context.mli
+++ b/kernel/context.mli
@@ -214,7 +214,7 @@ sig
val to_rel_decl : ('c, 't) pt -> ('c, 't) Rel.Declaration.pt
end
- (** Rel-context is represented as a list of declarations.
+ (** Named-context is represented as a list of declarations.
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
@@ -223,7 +223,7 @@ sig
(** empty named-context *)
val empty : ('c, 't) pt
- (** Return a new rel-context enriched by with a given inner-most declaration. *)
+ (** Return a new named-context enriched by with a given inner-most declaration. *)
val add : ('c, 't) Declaration.pt -> ('c, 't) pt -> ('c, 't) pt
(** Return the number of {e local declarations} in a given named-context. *)
@@ -233,7 +233,7 @@ sig
@raise Not_found if the designated identifier is not bound in a given named-context. *)
val lookup : Id.t -> ('c, 't) pt -> ('c, 't) Declaration.pt
- (** Check whether given two rel-contexts are equal. *)
+ (** Check whether given two named-contexts are equal. *)
val equal : ('c -> 'c -> bool) -> ('c, 'c) pt -> ('c, 'c) pt -> bool
(** Map all terms in a given named-context. *)
@@ -253,8 +253,8 @@ sig
(** Return the set of all identifiers bound in a given named-context. *)
val to_vars : ('c, 't) pt -> Id.Set.t
- (** [instance_from_named_context Ω] builds an instance [args] such
- that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
+ (** [to_instance Ω] builds an instance [args] such
+ that [Ω ⊢ args:Ω] where [Ω] is a named-context and with the local
definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
gives [Var id1, Var id3]. All [idj] are supposed distinct. *)
val to_instance : (Id.t -> 'r) -> ('c, 't) pt -> 'r list
diff --git a/kernel/declarations.mli b/kernel/declarations.mli
index 7821ea20ff..71e228b19c 100644
--- a/kernel/declarations.mli
+++ b/kernel/declarations.mli
@@ -77,7 +77,7 @@ type typing_flags = {
}
(* some contraints are in constant_constraints, some other may be in
- * the OpaueDef *)
+ * the OpaqueDef *)
type constant_body = {
const_hyps : Context.Named.t; (** New: younger hyp at top *)
const_body : constant_def;
diff --git a/kernel/names.ml b/kernel/names.ml
index ee8d838da1..5c10badbec 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -162,21 +162,8 @@ module DirPath =
struct
type t = module_ident list
- let rec compare (p1 : t) (p2 : t) =
- if p1 == p2 then 0
- else begin match p1, p2 with
- | [], [] -> 0
- | [], _ -> -1
- | _, [] -> 1
- | id1 :: p1, id2 :: p2 ->
- let c = Id.compare id1 id2 in
- if Int.equal c 0 then compare p1 p2 else c
- end
-
- let rec equal p1 p2 = p1 == p2 || match p1, p2 with
- | [], [] -> true
- | id1 :: p1, id2 :: p2 -> Id.equal id1 id2 && equal p1 p2
- | _ -> false
+ let compare = List.compare Id.compare
+ let equal = List.equal Id.equal
let rec hash accu = function
| [] -> accu
@@ -191,7 +178,7 @@ struct
let empty = []
- let is_empty d = match d with [] -> true | _ -> false
+ let is_empty = List.is_empty
let to_string = function
| [] -> "<>"
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
index d14a254d32..48d7ee9ec3 100644
--- a/kernel/pre_env.ml
+++ b/kernel/pre_env.ml
@@ -68,8 +68,8 @@ type named_context_val = {
}
type env = {
- env_globals : globals;
- env_named_context : named_context_val;
+ env_globals : globals; (* globals = constants + inductive types + modules + module-types *)
+ env_named_context : named_context_val; (* section variables *)
env_rel_context : Context.Rel.t;
env_rel_val : lazy_val list;
env_nb_rel : int;
@@ -161,19 +161,7 @@ let map_named_val f ctxt =
else { env_named_ctx = ctx; env_named_map = map }
let push_named d env =
-(* if not (env.env_rel_context = []) then raise (ASSERT env.env_rel_context);
- assert (env.env_rel_context = []); *)
- { env_globals = env.env_globals;
- env_named_context = push_named_context_val d env.env_named_context;
- env_rel_context = env.env_rel_context;
- env_rel_val = env.env_rel_val;
- env_nb_rel = env.env_nb_rel;
- env_stratification = env.env_stratification;
- env_typing_flags = env.env_typing_flags;
- env_conv_oracle = env.env_conv_oracle;
- retroknowledge = env.retroknowledge;
- indirect_pterms = env.indirect_pterms;
- }
+ {env with env_named_context = push_named_context_val d env.env_named_context}
let lookup_named id env =
fst (Id.Map.find id env.env_named_context.env_named_map)
diff --git a/lib/flags.ml b/lib/flags.ml
index d87d9e7295..00f515b5a6 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -143,16 +143,16 @@ let beautify = ref false
let beautify_file = ref false
(* Silent / Verbose *)
-let silent = ref false
-let make_silent flag = silent := flag; ()
-let is_silent () = !silent
-let is_verbose () = not !silent
+let quiet = ref false
+let silently f x = with_option quiet f x
+let verbosely f x = without_option quiet f x
-let silently f x = with_option silent f x
-let verbosely f x = without_option silent f x
+let if_silent f x = if !quiet then f x
+let if_verbose f x = if not !quiet then f x
-let if_silent f x = if !silent then f x
-let if_verbose f x = if not !silent then f x
+let make_silent flag = quiet := flag
+let is_silent () = !quiet
+let is_verbose () = not !quiet
let auto_intros = ref true
let make_auto_intros flag = auto_intros := flag
diff --git a/lib/flags.mli b/lib/flags.mli
index c5c4a15aaa..0b00ac13c2 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -85,16 +85,22 @@ val pr_version : compat_version -> string
val beautify : bool ref
val beautify_file : bool ref
-(* Silent/verbose, both actually controlled by a single flag so they
- are mutually exclusive *)
-val make_silent : bool -> unit
-val is_silent : unit -> bool
-val is_verbose : unit -> bool
+(* Coq quiet mode. Note that normal mode is called "verbose" here,
+ whereas [quiet] supresses normal output such as goals in coqtop *)
+val quiet : bool ref
val silently : ('a -> 'b) -> 'a -> 'b
val verbosely : ('a -> 'b) -> 'a -> 'b
val if_silent : ('a -> unit) -> 'a -> unit
val if_verbose : ('a -> unit) -> 'a -> unit
+(* Deprecated *)
+val make_silent : bool -> unit
+[@@ocaml.deprecated "Please use Flags.quiet"]
+val is_silent : unit -> bool
+[@@ocaml.deprecated "Please use Flags.quiet"]
+val is_verbose : unit -> bool
+[@@ocaml.deprecated "Please use Flags.quiet"]
+
(* Miscellaneus flags for vernac *)
val make_auto_intros : bool -> unit
val is_auto_intros : unit -> bool
diff --git a/library/loadpath.ml b/library/loadpath.ml
index d03c6c5553..529b9502b0 100644
--- a/library/loadpath.ml
+++ b/library/loadpath.ml
@@ -113,5 +113,5 @@ let expand_path ?root dir =
let locate_file fname =
let paths = List.map physical !load_paths in
let _,longfname =
- System.find_file_in_path ~warn:(Flags.is_verbose()) paths fname in
+ System.find_file_in_path ~warn:(not !Flags.quiet) paths fname in
longfname
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 4fd316119f..011565d86a 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -40,7 +40,6 @@ let def_body = Gram.entry_create "vernac:def_body"
let decl_notation = Gram.entry_create "vernac:decl_notation"
let record_field = Gram.entry_create "vernac:record_field"
let of_type_with_opt_coercion = Gram.entry_create "vernac:of_type_with_opt_coercion"
-let subgoal_command = Gram.entry_create "proof_mode:subgoal_command"
let instance_name = Gram.entry_create "vernac:instance_name"
let section_subset_expr = Gram.entry_create "vernac:section_subset_expr"
@@ -53,7 +52,7 @@ let make_bullet s =
| _ -> assert false
GEXTEND Gram
- GLOBAL: vernac gallina_ext noedit_mode subprf subgoal_command;
+ GLOBAL: vernac gallina_ext noedit_mode subprf;
vernac: FIRST
[ [ IDENT "Time"; c = located_vernac -> VernacTime c
| IDENT "Redirect"; s = ne_string; c = located_vernac -> VernacRedirect (s, c)
@@ -92,7 +91,7 @@ GEXTEND Gram
[ [ prfcom = command_entry -> prfcom ] ]
;
noedit_mode:
- [ [ c = subgoal_command -> c None] ]
+ [ [ c = query_command -> c None] ]
;
subprf:
@@ -102,15 +101,6 @@ GEXTEND Gram
] ]
;
- subgoal_command:
- [ [ c = query_command; "." ->
- begin function
- | Some (SelectNth g) -> c (Some g)
- | None -> c None
- | _ ->
- VernacError (UserError (None,str"Typing and evaluation commands, cannot be used with the \"all:\" selector."))
- end ] ]
- ;
located_vernac:
[ [ v = vernac -> !@loc, v ] ]
;
@@ -918,29 +908,30 @@ GEXTEND Gram
VernacRemoveOption ([table], v) ]]
;
query_command: (* TODO: rapprocher Eval et Check *)
- [ [ IDENT "Eval"; r = red_expr; "in"; c = lconstr ->
+ [ [ IDENT "Eval"; r = red_expr; "in"; c = lconstr; "." ->
fun g -> VernacCheckMayEval (Some r, g, c)
- | IDENT "Compute"; c = lconstr ->
+ | IDENT "Compute"; c = lconstr; "." ->
fun g -> VernacCheckMayEval (Some (Genredexpr.CbvVm None), g, c)
- | IDENT "Check"; c = lconstr ->
+ | IDENT "Check"; c = lconstr; "." ->
fun g -> VernacCheckMayEval (None, g, c)
(* Searching the environment *)
- | IDENT "About"; qid = smart_global ->
+ | IDENT "About"; qid = smart_global; "." ->
fun g -> VernacPrint (PrintAbout (qid,g))
- | IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules ->
+ | IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules; "." ->
fun g -> VernacSearch (SearchHead c,g, l)
- | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules ->
+ | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules; "." ->
fun g -> VernacSearch (SearchPattern c,g, l)
- | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules ->
+ | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules; "." ->
fun g -> VernacSearch (SearchRewrite c,g, l)
- | IDENT "Search"; s = searchabout_query; l = searchabout_queries ->
+ | IDENT "Search"; s = searchabout_query; l = searchabout_queries; "." ->
let (sl,m) = l in fun g -> VernacSearch (SearchAbout (s::sl),g, m)
(* compatibility: SearchAbout *)
- | IDENT "SearchAbout"; s = searchabout_query; l = searchabout_queries ->
+ | IDENT "SearchAbout"; s = searchabout_query; l = searchabout_queries; "." ->
fun g -> let (sl,m) = l in VernacSearch (SearchAbout (s::sl),g, m)
(* compatibility: SearchAbout with "[ ... ]" *)
| IDENT "SearchAbout"; "["; sl = LIST1 searchabout_query; "]";
- l = in_or_out_modules -> fun g -> VernacSearch (SearchAbout sl,g, l)
+ l = in_or_out_modules; "." ->
+ fun g -> VernacSearch (SearchAbout sl,g, l)
] ]
;
printable:
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index 92d249e535..dad98e2e98 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -211,7 +211,7 @@ let camlp4_verbosity silent f x =
f x;
warning_verbose := a
-let camlp4_verbose f x = camlp4_verbosity (Flags.is_verbose ()) f x
+let camlp4_verbose f x = camlp4_verbosity (not !Flags.quiet) f x
(** Grammar extensions *)
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 48c0f5f04c..8dae17d69e 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -299,7 +299,7 @@ let change_eq env sigma hyp_id (context:rel_context) x t end_of_type =
Can be safely replaced by the next comment for Ocaml >= 3.08.4
*)
let sub = Int.Map.bindings sub in
- List.fold_left (fun end_of_type (i,t) -> lift 1 (substnl [t] (i-1) end_of_type))
+ List.fold_left (fun end_of_type (i,t) -> liftn 1 i (substnl [t] (i-1) end_of_type))
end_of_type_with_pop
sub
in
@@ -1401,8 +1401,8 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let prove_with_tcc tcc_lemma_constr eqs : tactic =
match !tcc_lemma_constr with
- | None -> anomaly (Pp.str "No tcc proof !!")
- | Some lemma ->
+ | Undefined -> anomaly (Pp.str "No tcc proof !!")
+ | Value lemma ->
fun gls ->
(* let hid = next_ident_away_in_goal h_id (pf_ids_of_hyps gls) in *)
(* let ids = hid::pf_ids_of_hyps gls in *)
@@ -1420,7 +1420,7 @@ let prove_with_tcc tcc_lemma_constr eqs : tactic =
Proofview.V82.of_tactic (Eauto.gen_eauto (false,5) [] (Some []))
]
gls
-
+ | Not_needed -> tclIDTAC
let backtrack_eqs_until_hrec hrec eqs : tactic =
fun gls ->
@@ -1599,8 +1599,9 @@ let prove_principle_for_gen
let args_ids = List.map (get_name %> Nameops.out_name) princ_info.args in
let lemma =
match !tcc_lemma_ref with
- | None -> error "No tcc proof !!"
- | Some lemma -> EConstr.of_constr lemma
+ | Undefined -> error "No tcc proof !!"
+ | Value lemma -> EConstr.of_constr lemma
+ | Not_needed -> EConstr.of_constr (Coqlib.build_coq_I ())
in
(* let rec list_diff del_list check_list = *)
(* match del_list with *)
diff --git a/plugins/funind/functional_principles_proofs.mli b/plugins/funind/functional_principles_proofs.mli
index 769d726d70..7ddc84d015 100644
--- a/plugins/funind/functional_principles_proofs.mli
+++ b/plugins/funind/functional_principles_proofs.mli
@@ -9,7 +9,7 @@ val prove_princ_for_struct :
val prove_principle_for_gen :
constant*constant*constant -> (* name of the function, the functional and the fixpoint equation *)
- constr option ref -> (* a pointer to the obligation proofs lemma *)
+ Indfun_common.tcc_lemma_value ref -> (* a pointer to the obligation proofs lemma *)
bool -> (* is that function uses measure *)
int -> (* the number of recursive argument *)
EConstr.types -> (* the type of the recursive argument *)
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index 20da12f395..7b0d7d27d7 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -543,3 +543,8 @@ let prodn n env b =
(* compose_prod [xn:Tn;..;x1:T1] b = (x1:T1)..(xn:Tn)b *)
let compose_prod l b = prodn (List.length l) l b
+
+type tcc_lemma_value =
+ | Undefined
+ | Value of Constr.constr
+ | Not_needed
diff --git a/plugins/funind/indfun_common.mli b/plugins/funind/indfun_common.mli
index 5c3e73e9d7..5ef8f05bb7 100644
--- a/plugins/funind/indfun_common.mli
+++ b/plugins/funind/indfun_common.mli
@@ -119,3 +119,8 @@ val decompose_lam_n : Evd.evar_map -> int -> EConstr.t ->
(Names.Name.t * EConstr.t) list * EConstr.t
val compose_lam : (Names.Name.t * EConstr.t) list -> EConstr.t -> EConstr.t
val compose_prod : (Names.Name.t * EConstr.t) list -> EConstr.t -> EConstr.t
+
+type tcc_lemma_value =
+ | Undefined
+ | Value of Constr.constr
+ | Not_needed
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 5460d6fb73..1e405d2c90 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -45,12 +45,6 @@ open Indfun_common
open Sigma.Notations
open Context.Rel.Declaration
-let local_assum (na, t) =
- LocalAssum (na, EConstr.Unsafe.to_constr t)
-
-let local_def (na, b, t) =
- LocalDef (na, EConstr.Unsafe.to_constr b, EConstr.Unsafe.to_constr t)
-
(* Ugly things which should not be here *)
let coq_constant m s =
@@ -1323,7 +1317,7 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp
| _ -> anomaly ~label:"equation_lemma" (Pp.str "not a constant")
in
let lemma = mkConst (Names.Constant.make1 (Lib.make_kn na)) in
- ref_ := Some (EConstr.Unsafe.to_constr lemma);
+ ref_ := Value (EConstr.Unsafe.to_constr lemma);
let lid = ref [] in
let h_num = ref (-1) in
let env = Global.env () in
@@ -1411,7 +1405,7 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp
let com_terminate
tcc_lemma_name
- (tcc_lemma_ref : Constr.t option ref)
+ tcc_lemma_ref
is_mes
fonctional_ref
input_type
@@ -1440,6 +1434,7 @@ let com_terminate
(new_goal_type);
with Failure "empty list of subgoals!" ->
(* a non recursive function declared with measure ! *)
+ tcc_lemma_ref := Not_needed;
defined ()
@@ -1515,7 +1510,6 @@ let (com_eqn : int -> Id.t ->
(* Pp.msgnl (str "eqn finished"); *)
);;
-
let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num eq
generate_induction_principle using_lemmas : unit =
let open Term in
@@ -1561,7 +1555,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
in
let evm = Evd.from_ctx evuctx in
let tcc_lemma_name = add_suffix function_name "_tcc" in
- let tcc_lemma_constr = ref None in
+ let tcc_lemma_constr = ref Undefined in
(* let _ = Pp.msgnl (str "relation := " ++ Printer.pr_lconstr_env env_with_pre_rec_args relation) in *)
let hook _ _ =
let term_ref = Nametab.locate (qualid_of_ident term_id) in
@@ -1590,8 +1584,8 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
and eq_ref = destConst (constr_of_global eq_ref) in
generate_induction_principle f_ref tcc_lemma_constr
functional_ref eq_ref rec_arg_num (EConstr.of_constr rec_arg_type) (nb_prod evm (EConstr.of_constr res)) (EConstr.of_constr relation);
- if Flags.is_verbose ()
- then msgnl (h 1 (Ppconstr.pr_id function_name ++
+ Flags.if_verbose
+ msgnl (h 1 (Ppconstr.pr_id function_name ++
spc () ++ str"is defined" )++ fnl () ++
h 1 (Ppconstr.pr_id equation_id ++
spc () ++ str"is defined" )
diff --git a/plugins/funind/recdef.mli b/plugins/funind/recdef.mli
index 9c1081b9d2..80f02e01c4 100644
--- a/plugins/funind/recdef.mli
+++ b/plugins/funind/recdef.mli
@@ -13,7 +13,7 @@ bool ->
Constrexpr.constr_expr ->
Constrexpr.constr_expr ->
int -> Constrexpr.constr_expr -> (Term.pconstant ->
- Term.constr option ref ->
+ Indfun_common.tcc_lemma_value ref ->
Term.pconstant ->
Term.pconstant -> int -> EConstr.types -> int -> EConstr.constr -> 'a) -> Constrexpr.constr_expr list -> unit
diff --git a/plugins/ltac/g_ltac.ml4 b/plugins/ltac/g_ltac.ml4
index ece0adb071..ca5d198c23 100644
--- a/plugins/ltac/g_ltac.ml4
+++ b/plugins/ltac/g_ltac.ml4
@@ -335,7 +335,7 @@ GEXTEND Gram
| IDENT "all"; ":" -> SelectAll ] ]
;
tactic_mode:
- [ [ g = OPT toplevel_selector; tac = G_vernac.subgoal_command -> tac g ] ]
+ [ [ g = OPT toplevel_selector; tac = G_vernac.query_command -> tac g ] ]
;
command:
[ [ IDENT "Proof"; "with"; ta = Pltac.tactic;
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index 632ba0d9cd..e9b3d197bc 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -388,7 +388,7 @@ let add_coercion_in_graph (ic,source,target) =
old_inheritance_graph
end;
let is_ambig = match !ambig_paths with [] -> false | _ -> true in
- if is_ambig && is_verbose () then
+ if is_ambig && not !quiet then
Feedback.msg_info (message_ambig !ambig_paths)
type coercion = {
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 2eff1936f4..b16d044956 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -220,6 +220,8 @@ let instantiate_pattern env sigma lvar c =
ctx
in
let c = substl inst c in
+ (** FIXME: Stupid workaround to pattern_of_constr being evar sensitive *)
+ let c = Evarutil.nf_evar sigma c in
pattern_of_constr env sigma (EConstr.Unsafe.to_constr c)
with Not_found (* List.index failed *) ->
let vars =
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index cfc2e48d11..e4a87739b1 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -107,7 +107,7 @@ open Decl_kinds
| SearchString (s,sc) -> qs s ++ pr_opt (fun sc -> str "%" ++ str sc) sc
let pr_search a gopt b pr_p =
- pr_opt (fun g -> int g ++ str ":"++ spc()) gopt
+ pr_opt (fun g -> Proof_global.pr_goal_selector g ++ str ":"++ spc()) gopt
++
match a with
| SearchHead c -> keyword "SearchHead" ++ spc() ++ pr_p c ++ pr_in_out_modules b
@@ -497,7 +497,7 @@ open Decl_kinds
| PrintVisibility s ->
keyword "Print Visibility" ++ pr_opt str s
| PrintAbout (qid,gopt) ->
- pr_opt (fun g -> int g ++ str ":"++ spc()) gopt
+ pr_opt (fun g -> Proof_global.pr_goal_selector g ++ str ":"++ spc()) gopt
++ keyword "About" ++ spc() ++ pr_smart_global qid
| PrintImplicit qid ->
keyword "Print Implicit" ++ spc() ++ pr_smart_global qid
@@ -619,8 +619,6 @@ open Decl_kinds
return (keyword "Timeout " ++ int n ++ spc() ++ pr_vernac_body v)
| VernacFail v ->
return (keyword "Fail" ++ spc() ++ pr_vernac_body v)
- | VernacError _ ->
- return (keyword "No-parsing-rule for VernacError")
(* Syntax *)
| VernacOpenCloseScope (_,(opening,sc)) ->
@@ -1140,7 +1138,8 @@ open Decl_kinds
spc() ++ keyword "in" ++ spc () ++ pr_lconstr c)
| None -> hov 2 (keyword "Check" ++ spc() ++ pr_lconstr c)
in
- let pr_i = match io with None -> mt () | Some i -> int i ++ str ": " in
+ let pr_i = match io with None -> mt ()
+ | Some i -> Proof_global.pr_goal_selector i ++ str ": " in
return (pr_i ++ pr_mayeval r c)
| VernacGlobalCheck c ->
return (hov 2 (keyword "Type" ++ pr_constrarg c))
@@ -1222,7 +1221,7 @@ open Decl_kinds
| Egramml.GramTerminal s :: rl, cl -> str s :: aux rl cl
| [], [] -> []
| _ -> assert false in
- hov 1 (pr_sequence (fun x -> x) (aux rl cl))
+ hov 1 (pr_sequence identity (aux rl cl))
with Not_found ->
hov 1 (str "TODO(" ++ str (fst s) ++ spc () ++ prlist_with_sep sep pr_arg cl ++ str ")")
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index e4cba6f07d..5f4a7766f3 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -88,7 +88,7 @@ type proof_terminator = proof_ending -> unit
type closed_proof = proof_object * proof_terminator
type pstate = {
- pid : Id.t;
+ pid : Id.t; (* the name of the theorem whose proof is being constructed *)
terminator : proof_terminator CEphemeron.key;
endline_tactic : Genarg.glob_generic_argument option;
section_vars : Context.Named.t option;
@@ -671,16 +671,18 @@ let _ =
let default_goal_selector = ref (Vernacexpr.SelectNth 1)
let get_default_goal_selector () = !default_goal_selector
-let print_range_selector (i, j) =
- if i = j then string_of_int i
- else string_of_int i ^ "-" ^ string_of_int j
+let pr_range_selector (i, j) =
+ if i = j then int i
+ else int i ++ str "-" ++ int j
-let print_goal_selector = function
- | Vernacexpr.SelectAll -> "all"
- | Vernacexpr.SelectNth i -> string_of_int i
- | Vernacexpr.SelectList l -> "[" ^
- String.concat ", " (List.map print_range_selector l) ^ "]"
- | Vernacexpr.SelectId id -> Id.to_string id
+let pr_goal_selector = function
+ | Vernacexpr.SelectAll -> str "all"
+ | Vernacexpr.SelectNth i -> int i
+ | Vernacexpr.SelectList l ->
+ str "["
+ ++ prlist_with_sep pr_comma pr_range_selector l
+ ++ str "]"
+ | Vernacexpr.SelectId id -> Id.print id
let parse_goal_selector = function
| "all" -> Vernacexpr.SelectAll
@@ -699,7 +701,10 @@ let _ =
optdepr = false;
optname = "default goal selector" ;
optkey = ["Default";"Goal";"Selector"] ;
- optread = begin fun () -> print_goal_selector !default_goal_selector end;
+ optread = begin fun () ->
+ string_of_ppcmds
+ (pr_goal_selector !default_goal_selector)
+ end;
optwrite = begin fun n ->
default_goal_selector := parse_goal_selector n
end
diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli
index 3b2cc6b23b..6bb6f5e2cb 100644
--- a/proofs/proof_global.mli
+++ b/proofs/proof_global.mli
@@ -198,6 +198,7 @@ end
(* *)
(**********************************************************)
+val pr_goal_selector : Vernacexpr.goal_selector -> Pp.std_ppcmds
val get_default_goal_selector : unit -> Vernacexpr.goal_selector
module V82 : sig
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index fb6adaec5f..c4f392f201 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -202,8 +202,7 @@ let rec classify_vernac e =
(* What are these? *)
| VernacToplevelControl _
| VernacRestoreState _
- | VernacWriteState _
- | VernacError _ -> VtUnknown, VtNow
+ | VernacWriteState _ -> VtUnknown, VtNow
(* Plugins should classify their commands *)
| VernacExtend (s,l) ->
try List.assoc s !classifiers l ()
diff --git a/stm/workerLoop.ml b/stm/workerLoop.ml
index 50b42512cb..86ef59dc30 100644
--- a/stm/workerLoop.ml
+++ b/stm/workerLoop.ml
@@ -13,7 +13,7 @@ let rec parse = function
let loop init args =
let args = parse args in
- Flags.make_silent true;
+ Flags.quiet := true;
init ();
CoqworkmgrApi.init !Flags.async_proofs_worker_priority;
args
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index ea19660931..df222eed80 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -590,7 +590,7 @@ let make_resolve_hyp env sigma st flags only_classes pri decl =
info.Vernacexpr.hint_pattern }
in
make_resolves env sigma ~name:(PathHints path)
- (true,false,Flags.is_verbose()) info false
+ (true,false,not !Flags.quiet) info false
(IsConstr (EConstr.of_constr c,Univ.ContextSet.empty)))
hints)
else []
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 77ed4330c1..bcc068d3da 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -1160,7 +1160,7 @@ let add_resolves env sigma clist local dbnames =
(fun dbname ->
let r =
List.flatten (List.map (fun (pri, poly, hnf, path, gr) ->
- make_resolves env sigma (true,hnf,Flags.is_verbose())
+ make_resolves env sigma (true,hnf,not !Flags.quiet)
pri poly ~name:path gr) clist)
in
let hint = make_hint ~local dbname (AddHints r) in
diff --git a/test-suite/bugs/closed/4306.v b/test-suite/bugs/closed/4306.v
new file mode 100644
index 0000000000..4aef5bb95e
--- /dev/null
+++ b/test-suite/bugs/closed/4306.v
@@ -0,0 +1,32 @@
+Require Import List.
+Require Import Arith.
+Require Import Recdef.
+Require Import Omega.
+
+Function foo (xys : (list nat * list nat)) {measure (fun xys => length (fst xys) + length (snd xys))} : list nat :=
+ match xys with
+ | (nil, _) => snd xys
+ | (_, nil) => fst xys
+ | (x :: xs', y :: ys') => match Compare_dec.nat_compare x y with
+ | Lt => x :: foo (xs', y :: ys')
+ | Eq => x :: foo (xs', ys')
+ | Gt => y :: foo (x :: xs', ys')
+ end
+ end.
+Proof.
+ intros; simpl; omega.
+ intros; simpl; omega.
+ intros; simpl; omega.
+Qed.
+
+Function bar (xys : (list nat * list nat)) {measure (fun xys => length (fst xys) + length (snd xys))} : list nat :=
+ let (xs, ys) := xys in
+ match (xs, ys) with
+ | (nil, _) => ys
+ | (_, nil) => xs
+ | (x :: xs', y :: ys') => match Compare_dec.nat_compare x y with
+ | Lt => x :: foo (xs', ys)
+ | Eq => x :: foo (xs', ys')
+ | Gt => y :: foo (xs, ys')
+ end
+ end. \ No newline at end of file
diff --git a/test-suite/bugs/closed/5476.v b/test-suite/bugs/closed/5476.v
new file mode 100644
index 0000000000..b2d9d943bc
--- /dev/null
+++ b/test-suite/bugs/closed/5476.v
@@ -0,0 +1,28 @@
+Require Setoid.
+
+Goal forall (P : Prop) (T : Type) (m m' : T) (T0 T1 : Type) (P2 : forall _ :
+Prop, Prop)
+ (P0 : Set) (x0 : P0) (P1 : forall (_ : P0) (_ : T), Prop)
+ (P3 : forall (_ : forall (_ : P0) (_ : T0) (_ : Prop), Prop) (_ :
+T) (_ : Prop), Prop)
+ (o : forall _ : P0, option T1)
+ (_ : P3
+ (fun (k : P0) (_ : T0) (_ : Prop) =>
+ match o k return Prop with
+ | Some _ => True
+ | None => False
+ end) m' P) (_ : P2 (P1 x0 m))
+ (_ : forall (f : forall (_ : P0) (_ : T0) (_ : Prop), Prop) (m1 m2
+: T)
+ (k : P0) (e : T0) (_ : P2 (P1 k m1)), iff (P3 f m2 P)
+(f k e (P3 f m1 P))), False.
+Proof.
+ intros ???????????? H0 H H1.
+ rewrite H1 in H0; eauto with nocore.
+ { lazymatch goal with
+ | H : match ?X with _ => _ end |- _
+ => first [ lazymatch goal with
+ | [ H' : context[X] |- _ ] => idtac H
+ end
+ | fail 1 "could not find" X ]
+ end.
diff --git a/test-suite/output/Search.out b/test-suite/output/Search.out
index 81fda176ec..7446c17d98 100644
--- a/test-suite/output/Search.out
+++ b/test-suite/output/Search.out
@@ -98,6 +98,14 @@ h: n <> newdef n
h': newdef n <> n
h: n <> newdef n
h: n <> newdef n
+h: n <> newdef n
+h': newdef n <> n
+The command has indeed failed with message:
+No such goal.
+The command has indeed failed with message:
+Query commands only support the single numbered goal selector.
+The command has indeed failed with message:
+Query commands only support the single numbered goal selector.
h: P n
h': ~ P n
h: P n
diff --git a/test-suite/output/Search.v b/test-suite/output/Search.v
index 2a0f0b407c..82096f29bf 100644
--- a/test-suite/output/Search.v
+++ b/test-suite/output/Search.v
@@ -10,11 +10,19 @@ Search (@eq _ _ _) true -false "prop" -"intro". (* andb_prop *)
Definition newdef := fun x:nat => x.
Goal forall n:nat, n <> newdef n -> newdef n <> n -> False.
- intros n h h'.
+ cut False.
+ intros _ n h h'.
Search n. (* search hypothesis *)
Search newdef. (* search hypothesis *)
Search ( _ <> newdef _). (* search hypothesis, pattern *)
Search ( _ <> newdef _) -"h'". (* search hypothesis, pattern *)
+
+ 1:Search newdef.
+ 2:Search newdef.
+
+ Fail 3:Search newdef.
+ Fail 1-2:Search newdef.
+ Fail all:Search newdef.
Abort.
Goal forall n (P:nat -> Prop), P n -> ~P n -> False.
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index a4dcefcbde..f5f43ff66f 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -215,7 +215,7 @@ let glob_opt = ref false
let add_compile verbose s =
set_batch_mode ();
- Flags.make_silent true;
+ Flags.quiet := true;
if not !glob_opt then Dumpglob.dump_to_dotglob ();
(** make the file name explicit; needed not to break up Coq loadpath stuff. *)
let s =
@@ -384,7 +384,7 @@ let vio_tasks = ref []
let add_vio_task f =
set_batch_mode ();
- Flags.make_silent true;
+ Flags.quiet := true;
vio_tasks := f :: !vio_tasks
let check_vio_tasks () =
@@ -398,7 +398,7 @@ let vio_files_j = ref 0
let vio_checking = ref false
let add_vio_file f =
set_batch_mode ();
- Flags.make_silent true;
+ Flags.quiet := true;
vio_files := f :: !vio_files
let set_vio_checking_j opt j =
@@ -563,7 +563,7 @@ let parse_args arglist =
|"-output-context" -> output_context := true
|"-profile-ltac" -> Flags.profile_ltac := true
|"-q" -> no_load_rc ()
- |"-quiet"|"-silent" -> Flags.make_silent true; Flags.make_warn false
+ |"-quiet"|"-silent" -> Flags.quiet := true; Flags.make_warn false
|"-quick" -> Flags.compilation_mode := BuildVio
|"-list-tags" -> print_tags := true
|"-time" -> Flags.time := true
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index 84330b88ac..3359a16721 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -116,7 +116,7 @@ let rec interp_vernac sid po (loc,com) =
load_vernac verbosely sid f
| v ->
try
- let nsid, ntip = Stm.add sid (Flags.is_verbose()) (loc,v) in
+ let nsid, ntip = Stm.add sid (not !Flags.quiet) (loc,v) in
(* Main STM interaction *)
if ntip <> `NewTip then
@@ -128,7 +128,7 @@ let rec interp_vernac sid po (loc,com) =
(* We could use a more refined criteria that depends on the
vernac. For now we imitate the old approach. *)
- let hide_goals = !Flags.batch_mode || is_query v ||
+ let hide_goals = !Flags.batch_mode || is_query v || !Flags.quiet ||
not (Proof_global.there_are_pending_proofs ()) in
if not hide_goals then Feedback.msg_notice (pr_open_cur_subgoals ());
diff --git a/vernac/command.ml b/vernac/command.ml
index 5ec708446d..45ff579552 100644
--- a/vernac/command.ml
+++ b/vernac/command.ml
@@ -234,7 +234,7 @@ match local with
let _ = declare_variable ident decl in
let () = assumption_message ident in
let () =
- if is_verbose () && Pfedit.refining () then
+ if not !Flags.quiet && Pfedit.refining () then
Feedback.msg_info (str"Variable" ++ spc () ++ pr_id ident ++
strbrk " is not visible from current goals")
in
diff --git a/vernac/mltop.ml b/vernac/mltop.ml
index 2396cf04a4..056ffca5c8 100644
--- a/vernac/mltop.ml
+++ b/vernac/mltop.ml
@@ -138,7 +138,7 @@ let dir_ml_load s =
match !load with
| WithTop _ -> ml_load s
| WithoutTop ->
- let warn = Flags.is_verbose() in
+ let warn = not !Flags.quiet in
let _,gname = find_file_in_path ~warn !coq_mlpath_copy s in
ml_load gname
@@ -365,7 +365,7 @@ let trigger_ml_object verb cache reinit ?path name =
else begin
let file = file_of_name (Option.default name path) in
let path =
- if_verbose_load (verb && is_verbose ()) load_ml_object name ?path file in
+ if_verbose_load (verb && not !quiet) load_ml_object name ?path file in
add_loaded_module name (Some path);
if cache then perform_cache_obj name
end
diff --git a/vernac/topfmt.ml b/vernac/topfmt.ml
index a4acd3f24e..c25dd55fb7 100644
--- a/vernac/topfmt.ml
+++ b/vernac/topfmt.ml
@@ -112,26 +112,23 @@ let msgnl_with ?pre_hdr fmt strm =
pp_with fmt (strm ++ fnl ());
Format.pp_print_flush fmt ()
-(* XXX: This is really painful! *)
module Emacs = struct
(* Special chars for emacs, to detect warnings inside goal output *)
- let emacs_quote_start = String.make 1 (Char.chr 254)
- let emacs_quote_end = String.make 1 (Char.chr 255)
+ let quote_warning_start = "<warning>"
+ let quote_warning_end = "</warning>"
- let emacs_quote_err g =
- hov 0 (str emacs_quote_start ++ g ++ str emacs_quote_end)
+ let quote_info_start = "<infomsg>"
+ let quote_info_end = "</infomsg>"
- let emacs_quote_info_start = "<infomsg>"
- let emacs_quote_info_end = "</infomsg>"
+ let quote_emacs q_start q_end msg =
+ hov 0 (seq [str q_start; brk(0,0); msg; brk(0,0); str q_end])
- let emacs_quote_info g =
- hov 0 (str emacs_quote_info_start++ brk(0,0) ++ g ++ brk(0,0) ++ str emacs_quote_info_end)
+ let quote_warning = quote_emacs quote_warning_start quote_warning_end
+ let quote_info = quote_emacs quote_info_start quote_info_end
end
-open Emacs
-
let dbg_hdr = tag Tag.debug (str "Debug:") ++ spc ()
let info_hdr = mt ()
let warn_hdr = tag Tag.warning (str "Warning:") ++ spc ()
@@ -144,13 +141,13 @@ let make_body quoter info ?pre_hdr s =
(* The empty quoter *)
let noq x = x
(* Generic logger *)
-let gen_logger dbg err ?pre_hdr level msg = match level with
+let gen_logger dbg warn ?pre_hdr level msg = match level with
| Debug -> msgnl_with !std_ft (make_body dbg dbg_hdr ?pre_hdr msg)
| Info -> msgnl_with !std_ft (make_body dbg info_hdr ?pre_hdr msg)
| Notice -> msgnl_with !std_ft (make_body noq info_hdr ?pre_hdr msg)
| Warning -> Flags.if_warn (fun () ->
- msgnl_with !err_ft (make_body err warn_hdr ?pre_hdr msg)) ()
- | Error -> msgnl_with !err_ft (make_body err err_hdr ?pre_hdr msg)
+ msgnl_with !err_ft (make_body warn warn_hdr ?pre_hdr msg)) ()
+ | Error -> msgnl_with !err_ft (make_body noq err_hdr ?pre_hdr msg)
(** Standard loggers *)
@@ -261,7 +258,7 @@ let init_color_output () =
- Warning/Error: emacs_quote_err
- Notice: unquoted
*)
-let emacs_logger = gen_logger emacs_quote_info emacs_quote_err
+let emacs_logger = gen_logger Emacs.quote_info Emacs.quote_warning
(* Output to file, used only in extraction so a candidate for removal *)
let ft_logger old_logger ft ?loc level mesg =
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 92b1a59562..0a5a000fec 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -780,7 +780,7 @@ let vernac_require from import qidl =
in
let locate (loc, qid) =
try
- let warn = Flags.is_verbose () in
+ let warn = not !Flags.quiet in
let (_, dir, f) = Library.locate_qualified_library ?root ~warn qid in
(dir, f)
with
@@ -1232,8 +1232,8 @@ let _ =
optdepr = false;
optname = "silent";
optkey = ["Silent"];
- optread = is_silent;
- optwrite = make_silent }
+ optread = (fun () -> !Flags.quiet);
+ optwrite = ((:=) Flags.quiet) }
let _ =
declare_bool_option
@@ -1533,7 +1533,14 @@ let get_current_context_of_args = function
| Some n -> get_goal_context n
| None -> get_current_context ()
-let vernac_check_may_eval redexp glopt rc =
+let query_command_selector ~loc = function
+ | None -> None
+ | Some (SelectNth n) -> Some n
+ | _ -> user_err ~loc ~hdr:"query_command_selector"
+ (str "Query commands only support the single numbered goal selector.")
+
+let vernac_check_may_eval ~loc redexp glopt rc =
+ let glopt = query_command_selector ~loc glopt in
let (sigma, env) = get_current_context_of_args glopt in
let sigma', c = interp_open_constr env sigma rc in
let c = EConstr.Unsafe.to_constr c in
@@ -1595,9 +1602,10 @@ exception NoHyp
(* Printing "About" information of a hypothesis of the current goal.
We only print the type and a small statement to this comes from the
goal. Precondition: there must be at least one current goal. *)
-let print_about_hyp_globs ref_or_by_not glnumopt =
+let print_about_hyp_globs ~loc ref_or_by_not glopt =
let open Context.Named.Declaration in
try
+ let glnumopt = query_command_selector ~loc glopt in
let gl,id =
match glnumopt,ref_or_by_not with
| None,AN (Ident (_loc,id)) -> (* goal number not given, catch any failure *)
@@ -1605,8 +1613,8 @@ let print_about_hyp_globs ref_or_by_not glnumopt =
| Some n,AN (Ident (_loc,id)) -> (* goal number given, catch if wong *)
(try get_nth_goal n,id
with
- Failure _ -> user_err ~hdr:"print_about_hyp_globs"
- (str "No such goal: " ++ int n ++ str "."))
+ Failure _ -> user_err ~loc ~hdr:"print_about_hyp_globs"
+ (str "No such goal: " ++ int n ++ str "."))
| _ , _ -> raise NoHyp in
let hyps = pf_hyps gl in
let decl = Context.Named.lookup id hyps in
@@ -1619,7 +1627,7 @@ let print_about_hyp_globs ref_or_by_not glnumopt =
| NoHyp | Not_found -> print_about ref_or_by_not
-let vernac_print = let open Feedback in function
+let vernac_print ~loc = let open Feedback in function
| PrintTables -> msg_notice (print_tables ())
| PrintFullContext-> msg_notice (print_full_context_typ ())
| PrintSectionContext qid -> msg_notice (print_sec_context_typ qid)
@@ -1664,7 +1672,7 @@ let vernac_print = let open Feedback in function
| PrintVisibility s ->
msg_notice (Notation.pr_visibility (Constrextern.without_symbols pr_lglob_constr) s)
| PrintAbout (ref_or_by_not,glnumopt) ->
- msg_notice (print_about_hyp_globs ref_or_by_not glnumopt)
+ msg_notice (print_about_hyp_globs ~loc ref_or_by_not glnumopt)
| PrintImplicit qid ->
dump_global qid; msg_notice (print_impargs qid)
| PrintAssumptions (o,t,r) ->
@@ -1729,7 +1737,8 @@ let _ =
optread = (fun () -> !search_output_name_only);
optwrite = (:=) search_output_name_only }
-let vernac_search s gopt r =
+let vernac_search ~loc s gopt r =
+ let gopt = query_command_selector ~loc gopt in
let r = interp_search_restriction r in
let env,gopt =
match gopt with | None ->
@@ -1935,9 +1944,6 @@ let interp ?proof ~loc locality poly c =
| VernacBack _ -> anomaly (str "VernacBack not handled by Stm")
| VernacBackTo _ -> anomaly (str "VernacBackTo not handled by Stm")
- (* Horrible Hack that should die. *)
- | VernacError e -> raise e
-
(* This one is possible to handle here *)
| VernacAbort id -> CErrors.user_err (str "Abort cannot be used through the Load command")
@@ -2039,11 +2045,11 @@ let interp ?proof ~loc locality poly c =
| VernacAddOption (key,v) -> vernac_add_option key v
| VernacMemOption (key,v) -> vernac_mem_option key v
| VernacPrintOption key -> vernac_print_option key
- | VernacCheckMayEval (r,g,c) -> vernac_check_may_eval r g c
+ | VernacCheckMayEval (r,g,c) -> vernac_check_may_eval ~loc r g c
| VernacDeclareReduction (s,r) -> vernac_declare_reduction locality s r
| VernacGlobalCheck c -> vernac_global_check c
- | VernacPrint p -> vernac_print p
- | VernacSearch (s,g,r) -> vernac_search s g r
+ | VernacPrint p -> vernac_print ~loc p
+ | VernacSearch (s,g,r) -> vernac_search ~loc s g r
| VernacLocate l -> vernac_locate l
| VernacRegister (id, r) -> vernac_register id r
| VernacComments l -> if_verbose Feedback.msg_info (str "Comments ok\n")
@@ -2173,7 +2179,7 @@ let with_fail b f =
| HasNotFailed ->
user_err ~hdr:"Fail" (str "The command has not failed!")
| HasFailed msg ->
- if is_verbose () || !test_mode || !ide_slave then Feedback.msg_info
+ if not !Flags.quiet || !test_mode || !ide_slave then Feedback.msg_info
(str "The command has indeed failed with message:" ++ fnl () ++ msg)
| _ -> assert false
end