aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdev/bench/render_results322
-rw-r--r--dev/top_printers.dbg1
-rw-r--r--dev/top_printers.ml1
-rw-r--r--dev/top_printers.mli1
-rw-r--r--doc/changelog/03-notations/11841-master+distinguishing-ident-name-in-grammar-entries.rst13
-rw-r--r--doc/changelog/04-tactics/13417-no_int_or_var.rst7
-rw-r--r--doc/sphinx/addendum/micromega.rst4
-rw-r--r--doc/sphinx/addendum/type-classes.rst6
-rw-r--r--doc/sphinx/language/extensions/canonical.rst4
-rw-r--r--doc/sphinx/proof-engine/ltac.rst14
-rw-r--r--doc/sphinx/proofs/writing-proofs/rewriting.rst6
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst91
-rw-r--r--doc/tools/docgram/common.edit_mlg40
-rw-r--r--doc/tools/docgram/fullGrammar52
-rw-r--r--doc/tools/docgram/orderedGrammar53
-rw-r--r--engine/logic_monad.ml2
-rw-r--r--engine/logic_monad.mli2
-rw-r--r--engine/proofview.ml22
-rw-r--r--engine/proofview.mli2
-rw-r--r--interp/constrintern.ml13
-rw-r--r--interp/notation.ml3
-rw-r--r--interp/notation_ops.ml4
-rw-r--r--interp/notation_term.ml5
-rw-r--r--interp/stdarg.ml3
-rw-r--r--interp/stdarg.mli2
-rw-r--r--kernel/cClosure.ml58
-rw-r--r--lib/cErrors.ml6
-rw-r--r--lib/control.ml24
-rw-r--r--lib/control.mli11
-rw-r--r--parsing/extend.ml2
-rw-r--r--parsing/extend.mli2
-rw-r--r--plugins/ltac/coretactics.mlg8
-rw-r--r--plugins/ltac/extratactics.mlg4
-rw-r--r--plugins/ltac/g_auto.mlg20
-rw-r--r--plugins/ltac/g_class.mlg8
-rw-r--r--plugins/ltac/g_ltac.mlg4
-rw-r--r--plugins/ltac/g_tactic.mlg2
-rw-r--r--plugins/ltac/pltac.ml2
-rw-r--r--plugins/ltac/pltac.mli1
-rw-r--r--plugins/ltac/tacintern.ml1
-rw-r--r--plugins/ltac/tacinterp.ml1
-rw-r--r--plugins/ltac/tacsubst.ml1
-rw-r--r--plugins/micromega/g_micromega.mlg6
-rw-r--r--plugins/ssr/ssrparser.mlg2
-rw-r--r--pretyping/unification.ml2
-rw-r--r--test-suite/bugs/closed/bug_9517.v1
-rw-r--r--test-suite/output/Notations2.v8
-rw-r--r--test-suite/output/Notations3.v2
-rw-r--r--test-suite/output/Notations4.v1
-rw-r--r--theories/Init/Logic.v10
-rw-r--r--theories/Logic/Hurkens.v16
-rw-r--r--theories/Program/Utils.v2
-rw-r--r--theories/ssr/ssrbool.v26
-rw-r--r--theories/ssr/ssreflect.v2
-rw-r--r--theories/ssr/ssrfun.v42
-rw-r--r--vernac/egramcoq.ml11
-rw-r--r--vernac/g_vernac.mlg17
-rw-r--r--vernac/metasyntax.ml32
-rw-r--r--vernac/ppvernac.ml11
-rw-r--r--vernac/vernacinterp.ml4
60 files changed, 608 insertions, 415 deletions
diff --git a/dev/bench/render_results b/dev/bench/render_results
index 72affd70b2..bd4308837b 100755
--- a/dev/bench/render_results
+++ b/dev/bench/render_results
@@ -76,25 +76,13 @@ let run_and_read cmd =
;;
let ( %> ) f g x = g (f x)
-;;
let run = run_and_read %> snd
-;;
module Float = struct
let nan = Pervasives.nan
end
-module Tuple4 = struct
-
- let first (x,_,_,_) = x
- let second (_,y,_,_) = y
- let third (_,_,z,_) = z
- let fourth (_,_,_,z) = z
-
-end
-;;
-
module List = struct
include List
@@ -149,6 +137,151 @@ module String = struct
end
;;
+module Table :
+sig
+ type header = string
+ type row = string list list
+ val print : header list -> row list -> string
+end =
+struct
+ type header = string
+
+ type row = string list list
+
+ let val_padding = 2
+ (* Padding between data in the same row *)
+ let row_padding = 1
+ (* Padding between rows *)
+
+ let homogeneous b = if b then () else failwith "Heterogeneous data"
+
+ let vert_split (ls : 'a list list) =
+ let split l = match l with
+ | [] -> failwith "vert_split"
+ | x :: l -> (x, l)
+ in
+ let ls = List.map split ls in
+ List.split ls
+
+ let rec last = function
+ | [] -> assert false
+ | [x] -> [], x
+ | x :: l ->
+ let (l, y) = last l in
+ (x :: l, y)
+
+ let justify n s =
+ let len = String.length s in
+ let () = assert (len <= n) in
+ let lft = (n - len) / 2 in
+ let rgt = n - lft - len in
+ String.make lft ' ' ^ s ^ String.make rgt ' '
+
+ let justify_row layout data =
+ let map n s =
+ let len = String.length s in
+ let () = assert (len <= n) in
+ (* Right align *)
+ let pad = n - len in
+ String.make pad ' ' ^ s
+ in
+ let data = List.map2 map layout data in
+ String.concat (String.make val_padding ' ') data
+
+ let angle hkind vkind = match hkind, vkind with
+ | `Lft, `Top -> "┌"
+ | `Rgt, `Top -> "┐"
+ | `Mid, `Top -> "┬"
+ | `Lft, `Mid -> "├"
+ | `Rgt, `Mid -> "┤"
+ | `Mid, `Mid -> "┼"
+ | `Lft, `Bot -> "└"
+ | `Rgt, `Bot -> "┘"
+ | `Mid, `Bot -> "┴"
+
+ let print_separator vkind col_size =
+ let rec dashes n = if n = 0 then "" else "─" ^ dashes (n - 1) in
+ let len = List.length col_size in
+ let pad = dashes row_padding in
+ let () = assert (0 < len) in
+ let map n = dashes n in
+ angle `Lft vkind ^ pad ^
+ String.concat (pad ^ angle `Mid vkind ^ pad) (List.map map col_size) ^
+ pad ^ angle `Rgt vkind
+
+ let print_blank col_size =
+ let len = List.length col_size in
+ let () = assert (0 < len) in
+ let pad = String.make row_padding ' ' in
+ let map n = String.make n ' ' in
+ "│" ^ pad ^ String.concat (pad ^ "│" ^ pad) (List.map map col_size) ^ pad ^ "│"
+
+ let print_row row =
+ let len = List.length row in
+ let () = assert (0 < len) in
+ let pad = String.make row_padding ' ' in
+ "│" ^ pad ^ String.concat (pad ^ "│" ^ pad) row ^ pad ^ "│"
+
+ (* Invariant : all rows must have the same shape *)
+
+ let print (headers : header list) (rows : row list) =
+ (* Sanitize input *)
+ let ncolums = List.length headers in
+ let shape = ref None in
+ let check row =
+ let () = homogeneous (List.length row = ncolums) in
+ let rshape : int list = List.map (fun data -> List.length data) row in
+ match !shape with
+ | None -> shape := Some rshape
+ | Some s -> homogeneous (rshape = s)
+ in
+ let () = List.iter check rows in
+ (* Compute layout *)
+ let rec layout n (rows : row list) =
+ if n = 0 then []
+ else
+ let (col, rows) = vert_split rows in
+ let ans = layout (n - 1) rows in
+ let data = ref None in
+ let iter args =
+ let size = List.map String.length args in
+ match !data with
+ | None -> data := Some size
+ | Some s ->
+ data := Some (List.map2 (fun len1 len2 -> max len1 len2) s size)
+ in
+ let () = List.iter iter col in
+ let data = match !data with None -> [] | Some s -> s in
+ data :: ans
+ in
+ let layout = layout ncolums rows in
+ let map hd shape =
+ let data_size = match shape with
+ | [] -> 0
+ | n :: shape -> List.fold_left (fun accu n -> accu + n + val_padding) n shape
+ in
+ max (String.length hd) data_size
+ in
+ let col_size = List.map2 map headers layout in
+ (* Justify the data *)
+ let headers = List.map2 justify col_size headers in
+ let rows = List.map (fun row -> List.map2 justify col_size (List.map2 justify_row layout row)) rows in
+ (* Print the table *)
+ let rows, last = last rows in
+ let sep = print_separator `Mid col_size in
+ let rows = List.concat @@ List.map (fun r -> [print_row r; sep]) rows in
+ let lines =
+ print_separator `Top col_size ::
+ print_row headers ::
+ print_blank col_size ::
+ rows @
+ print_row last ::
+ print_separator `Bot col_size ::
+ []
+ in
+ String.concat "\n" lines
+end
+
(******************************************************************************)
(* END Copied from batteries, to remove *)
(******************************************************************************)
@@ -203,10 +336,6 @@ let proportional_difference_of_integers new_value old_value =
else float_of_int (new_value - old_value) /. float_of_int old_value *. 100.0
in
-let count_number_of_digits_before_decimal_point =
- log10 %> floor %> int_of_float %> succ %> max 1
-in
-
(* parse the *.time and *.perf files *)
coq_opam_packages
|> List.map
@@ -259,138 +388,39 @@ coq_opam_packages
(* Below we take the measurements and format them to stdout. *)
+|> List.map begin fun (package_name, new_t, old_t, perc) ->
+
+ let precision = 2 in
+ let prf f = Printf.sprintf "%.*f" precision f in
+ let pri n = Printf.sprintf "%d" n in
+
+ [
+ [ package_name ];
+ [ prf new_t.user_time; prf old_t.user_time; prf perc.user_time ];
+ [ pri new_t.num_cycles; pri old_t.num_cycles; prf perc.num_cycles ];
+ [ pri new_t.num_instr; pri old_t.num_instr; prf perc.num_instr ];
+ [ pri new_t.num_mem; pri old_t.num_mem; prf perc.num_mem ];
+ [ pri new_t.num_faults; pri old_t.num_faults; prf perc.num_faults ];
+ ]
+
+ end
+
|> fun measurements ->
- let precision = 2 in
-
- (* the labels that we will print *)
- let package_name__label = "package_name" in
- let new__label = "NEW" in
- let old__label = "OLD" in
- let proportional_difference__label = "PDIFF" in
-
- (* the lengths of labels that we will print *)
- let new__label__length = String.length new__label in
- let proportional_difference__label__length = String.length proportional_difference__label in
-
- (* widths of individual columns of the table *)
- let package_name__width =
- max (measurements |> List.map (Tuple4.first %> String.length) |> List.max)
- (String.length package_name__label) in
-
- let llf proj =
- let lls = count_number_of_digits_before_decimal_point (List.max proj) + 1 + precision in
- max lls new__label__length in
-
- let lli proj =
- let lls = count_number_of_digits_before_decimal_point (float_of_int (List.(max proj))) + 1 + precision in
- max lls new__label__length in
-
- let new_timing_width = reduce_pkg_timings llf lli @@ List.map Tuple4.second measurements in
- let old_timing_width = reduce_pkg_timings llf lli @@ List.map Tuple4.third measurements in
-
- let llp proj =
- let lls =
- count_number_of_digits_before_decimal_point List.(max List.(map abs_float proj)) + 2 + precision in
- max lls proportional_difference__label__length in
-
- let perc_timing_width = reduce_pkg_timings llp llp @@ List.map Tuple4.fourth measurements in
-
- (* print the table *)
- let rec make_dashes = function
- | 0 -> ""
- | count -> "─" ^ make_dashes (pred count)
- in
-
- let vertical_separator left_glyph middle_glyph right_glyph =
- sprintf "%s─%s─%s─%s─%s─%s───%s─%s─%s─%s───%s─%s─%s─%s───%s─%s─%s─%s───%s─%s─%s─%s───%s\n"
- left_glyph
- (make_dashes package_name__width)
- middle_glyph
- (make_dashes new_timing_width.user_time)
- (make_dashes old_timing_width.user_time)
- (make_dashes perc_timing_width.user_time)
- middle_glyph
- (make_dashes new_timing_width.num_cycles)
- (make_dashes old_timing_width.num_cycles)
- (make_dashes perc_timing_width.num_cycles)
- middle_glyph
- (make_dashes new_timing_width.num_instr)
- (make_dashes old_timing_width.num_instr)
- (make_dashes perc_timing_width.num_instr)
- middle_glyph
- (make_dashes new_timing_width.num_mem)
- (make_dashes old_timing_width.num_mem)
- (make_dashes perc_timing_width.num_mem)
- middle_glyph
- (make_dashes new_timing_width.num_faults)
- (make_dashes old_timing_width.num_faults)
- (make_dashes perc_timing_width.num_faults)
- right_glyph
- in
-
- let center_string string width =
- let string_length = String.length string in
- let width = max width string_length in
- let left_hfill = (width - string_length) / 2 in
- let right_hfill = width - left_hfill - string_length in
- String.make left_hfill ' ' ^ string ^ String.make right_hfill ' '
- in
- printf "\n";
- print_string (vertical_separator "┌" "┬" "┐");
- "│" ^ String.make (1 + package_name__width + 1) ' ' ^ "│"
- ^ center_string "user time [s]" (1 + new_timing_width.user_time + 1 + old_timing_width.user_time + 1 + perc_timing_width.user_time + 3) ^ "│"
- ^ center_string "CPU cycles" (1 + new_timing_width.num_cycles + 1 + old_timing_width.num_cycles + 1 + perc_timing_width.num_cycles + 3) ^ "│"
- ^ center_string "CPU instructions" (1 + new_timing_width.num_instr + 1 + old_timing_width.num_instr + 1 + perc_timing_width.num_instr + 3) ^ "│"
- ^ center_string "max resident mem [KB]" (1 + new_timing_width.num_mem + 1 + old_timing_width.num_mem + 1 + perc_timing_width.num_mem + 3) ^ "│"
- ^ center_string "mem faults" (1 + new_timing_width.num_faults + 1 + old_timing_width.num_faults + 1 + perc_timing_width.num_faults + 3)
- ^ "│\n" |> print_string;
- printf "│%*s │ %*s│ %*s│ %*s│ %*s│ %*s│\n"
- (1 + package_name__width) ""
- (new_timing_width.user_time + 1 + old_timing_width.user_time + 1 + perc_timing_width.user_time + 3) ""
- (new_timing_width.num_cycles + 1 + old_timing_width.num_cycles + 1 + perc_timing_width.num_cycles + 3) ""
- (new_timing_width.num_instr + 1 + old_timing_width.num_instr + 1 + perc_timing_width.num_instr + 3) ""
- (new_timing_width.num_mem + 1 + old_timing_width.num_mem + 1 + perc_timing_width.num_mem + 3) ""
- (new_timing_width.num_faults + 1 + old_timing_width.num_faults + 1 + perc_timing_width.num_faults + 3) "";
- printf "│ %*s │ %*s %*s %*s │ %*s %*s %*s │ %*s %*s %*s │ %*s %*s %*s │ %*s %*s %*s │\n"
- package_name__width package_name__label
- new_timing_width.user_time new__label
- old_timing_width.user_time old__label
- perc_timing_width.user_time proportional_difference__label
- new_timing_width.num_cycles new__label
- old_timing_width.num_cycles old__label
- perc_timing_width.num_cycles proportional_difference__label
- new_timing_width.num_instr new__label
- old_timing_width.num_instr old__label
- perc_timing_width.num_instr proportional_difference__label
- new_timing_width.num_mem new__label
- old_timing_width.num_mem old__label
- perc_timing_width.num_mem proportional_difference__label
- new_timing_width.num_faults new__label
- old_timing_width.num_faults old__label
- perc_timing_width.num_faults proportional_difference__label;
- measurements |> List.iter
- (fun (package_name, new_t, old_t, perc) ->
- print_string (vertical_separator "├" "┼" "┤");
- printf "│ %*s │ %*.*f %*.*f %+*.*f %% │ %*d %*d %+*.*f %% │ %*d %*d %+*.*f %% │ %*d %*d %+*.*f %% │ %*d %*d %+*.*f %% │\n"
- package_name__width package_name
- new_timing_width.user_time precision new_t.user_time
- old_timing_width.user_time precision old_t.user_time
- perc_timing_width.user_time precision perc.user_time
- new_timing_width.num_cycles new_t.num_cycles
- old_timing_width.num_cycles old_t.num_cycles
- perc_timing_width.num_cycles precision perc.num_cycles
- new_timing_width.num_instr new_t.num_instr
- old_timing_width.num_instr old_t.num_instr
- perc_timing_width.num_instr precision perc.num_instr
- new_timing_width.num_mem new_t.num_mem
- old_timing_width.num_mem old_t.num_mem
- perc_timing_width.num_mem precision perc.num_mem
- new_timing_width.num_faults new_t.num_faults
- old_timing_width.num_faults old_t.num_faults
- perc_timing_width.num_faults precision perc.num_faults);
-
-print_string (vertical_separator "└" "┴" "┘");
+ let headers = [
+ "";
+ "user time [s]";
+ "CPU cycles";
+ "CPU instructions";
+ "max resident mem [KB]";
+ "mem faults";
+ ] in
+
+ let descr = ["NEW"; "OLD"; "PDIFF"] in
+ let top = [ [ "package_name" ]; descr; descr; descr; descr; descr ] in
+
+ printf "%s%!" (Table.print headers (top :: measurements))
+;
(* ejgallego: disable this as it is very verbose and brings up little info in the log. *)
if false then begin
diff --git a/dev/top_printers.dbg b/dev/top_printers.dbg
index 21d6fbe9aa..bfc186c862 100644
--- a/dev/top_printers.dbg
+++ b/dev/top_printers.dbg
@@ -46,6 +46,7 @@ install_printer Top_printers.pp_idpred
install_printer Top_printers.pp_cpred
install_printer Top_printers.pp_transparent_state
install_printer Top_printers.pp_stack_t
+install_printer Top_printers.pp_estack_t
install_printer Top_printers.pp_state_t
install_printer Top_printers.ppmetas
install_printer Top_printers.ppevm
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index e4dd7ef52c..a9438c4aca 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -165,6 +165,7 @@ let pp_idpred s = pp (pr_idpred s)
let pp_cpred s = pp (pr_cpred s)
let pp_transparent_state s = pp (pr_transparent_state s)
let pp_stack_t n = pp (Reductionops.Stack.pr (EConstr.of_constr %> pr_econstr) n)
+let pp_estack_t n = pp (Reductionops.Stack.pr pr_econstr n)
let pp_state_t n = pp (Reductionops.pr_state Global.(env()) Evd.empty n)
(* proof printers *)
diff --git a/dev/top_printers.mli b/dev/top_printers.mli
index 712f66112c..50495dc0a4 100644
--- a/dev/top_printers.mli
+++ b/dev/top_printers.mli
@@ -108,6 +108,7 @@ val pp_cpred : Names.Cpred.t -> unit
val pp_transparent_state : TransparentState.t -> unit
val pp_stack_t : Constr.t Reductionops.Stack.t -> unit
+val pp_estack_t : EConstr.t Reductionops.Stack.t -> unit
val pp_state_t : Reductionops.state -> unit
val ppmetas : Evd.Metaset.t -> unit
diff --git a/doc/changelog/03-notations/11841-master+distinguishing-ident-name-in-grammar-entries.rst b/doc/changelog/03-notations/11841-master+distinguishing-ident-name-in-grammar-entries.rst
new file mode 100644
index 0000000000..8d681361e8
--- /dev/null
+++ b/doc/changelog/03-notations/11841-master+distinguishing-ident-name-in-grammar-entries.rst
@@ -0,0 +1,13 @@
+- **Changed:**
+ In notations (except in custom entries), the misleading :n:`@syntax_modifier`
+ :n:`@ident ident` (which accepted either an identifier or
+ a :g:`_`) is deprecated and should be replaced by :n:`@ident name`. If
+ the intent was really to only parse identifiers, this will
+ eventually become possible, but only as of Coq 8.15.
+ In custom entries, the meaning of :n:`@ident ident` is silently changed
+ from parsing identifiers or :g:`_` to parsing only identifiers
+ without warning, but this presumably affects only rare, recent and
+ relatively experimental code
+ (`#11841 <https://github.com/coq/coq/pull/11841>`_,
+ fixes `#9514 <https://github.com/coq/coq/pull/9514>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/13417-no_int_or_var.rst b/doc/changelog/04-tactics/13417-no_int_or_var.rst
new file mode 100644
index 0000000000..667ee28eea
--- /dev/null
+++ b/doc/changelog/04-tactics/13417-no_int_or_var.rst
@@ -0,0 +1,7 @@
+- **Removed:**
+ A number of tactics that formerly accepted negative
+ numbers as parameters now give syntax errors for negative
+ values. These include {e}constructor, do, timeout,
+ 9 {e}auto tactics and psatz*.
+ (`#13417 <https://github.com/coq/coq/pull/13417>`_,
+ by Jim Fehrle).
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index fb9965e43a..28b60878d2 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -250,11 +250,11 @@ proof by abstracting monomials by variables.
`psatz`: a proof procedure for non-linear arithmetic
----------------------------------------------------
-.. tacn:: psatz @one_term {? @int_or_var }
+.. tacn:: psatz @one_term {? @nat_or_var }
:name: psatz
This tactic explores the *Cone* by increasing degrees – hence the
- depth parameter *n*. In theory, such a proof search is complete – if the
+ depth parameter :token:`nat_or_var`. In theory, such a proof search is complete – if the
goal is provable the search eventually stops. Unfortunately, the
external oracle is using numeric (approximate) optimization techniques
that might miss a refutation.
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
index 22527dc379..98445fca1a 100644
--- a/doc/sphinx/addendum/type-classes.rst
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -405,7 +405,7 @@ Summary of the commands
Shows the list of instances associated with the typeclass :token:`reference`.
-.. tacn:: typeclasses eauto {? bfs } {? @int_or_var } {? with {+ @ident } }
+.. tacn:: typeclasses eauto {? bfs } {? @nat_or_var } {? with {+ @ident } }
This proof search tactic uses the resolution engine that is run
implicitly during type checking. This tactic uses a different resolution
@@ -445,11 +445,11 @@ Summary of the commands
+ Use the :cmd:`Typeclasses eauto` command to customize the behavior of
this tactic.
- :n:`@int_or_var`
+ :n:`@nat_or_var`
Specifies the maximum depth of the search.
.. warning::
- The semantics for the limit :n:`@int_or_var`
+ The semantics for the limit :n:`@nat_or_var`
are different than for :tacn:`auto`. By default, if no limit is given, the
search is unbounded. Unlike :tacn:`auto`, introduction steps count against
the limit, which might result in larger limits being necessary when
diff --git a/doc/sphinx/language/extensions/canonical.rst b/doc/sphinx/language/extensions/canonical.rst
index f7ce7f1c6c..aa754ab63d 100644
--- a/doc/sphinx/language/extensions/canonical.rst
+++ b/doc/sphinx/language/extensions/canonical.rst
@@ -490,10 +490,10 @@ We need some infrastructure for that.
Definition id {T} {t : T} (x : phantom t) := x.
Notation "[find v | t1 ~ t2 ] p" := (fun v (_ : unify t1 t2 None) => p)
- (at level 50, v ident, only parsing).
+ (at level 50, v name, only parsing).
Notation "[find v | t1 ~ t2 | s ] p" := (fun v (_ : unify t1 t2 (Some s)) => p)
- (at level 50, v ident, only parsing).
+ (at level 50, v name, only parsing).
Notation "'Error : t : s" := (unify _ t (Some s))
(at level 50, format "''Error' : t : s").
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
index 6464f085b8..2fc3c9f748 100644
--- a/doc/sphinx/proof-engine/ltac.rst
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -480,15 +480,15 @@ separately. They succeed only if there is a success for each goal. For example
Do loop
~~~~~~~
-.. tacn:: do @int_or_var @ltac_expr3
+.. tacn:: do @nat_or_var @ltac_expr3
:name: do
- The do loop repeats a tactic :token:`int_or_var` times:
+ The do loop repeats a tactic :token:`nat_or_var` times:
- :n:`@ltac_expr` is evaluated to ``v`` which must be a tactic value. This tactic
- value ``v`` is applied :token:`int_or_var` times. Supposing :token:`int_or_var` > 1, after the
+ :n:`@ltac_expr` is evaluated to ``v``, which must be a tactic value. This tactic
+ value ``v`` is applied :token:`nat_or_var` times. If :token:`nat_or_var` > 1, after the
first application of ``v``, ``v`` is applied, at least once, to the generated
- subgoals and so on. It fails if the application of ``v`` fails before :token:`int_or_var`
+ subgoals and so on. It fails if the application of ``v`` fails before :token:`nat_or_var`
applications have been completed.
:tacn:`do` is an :token:`l3_tactic`.
@@ -973,11 +973,11 @@ Timeout
We can force a tactic to stop if it has not finished after a certain
amount of time:
-.. tacn:: timeout @int_or_var @ltac_expr3
+.. tacn:: timeout @nat_or_var @ltac_expr3
:name: timeout
:n:`@ltac_expr3` is evaluated to ``v`` which must be a tactic value. The tactic value
- ``v`` is applied normally, except that it is interrupted after :n:`@natural` seconds
+ ``v`` is applied normally, except that it is interrupted after :n:`@nat_or_var` seconds
if it is still running. In this case the outcome is a failure.
:tacn:`timeout` is an :token:`l3_tactic`.
diff --git a/doc/sphinx/proofs/writing-proofs/rewriting.rst b/doc/sphinx/proofs/writing-proofs/rewriting.rst
index 5283f60b11..9ec568c2c7 100644
--- a/doc/sphinx/proofs/writing-proofs/rewriting.rst
+++ b/doc/sphinx/proofs/writing-proofs/rewriting.rst
@@ -323,10 +323,12 @@ Performing computations
| delta {? @delta_flag }
ref_or_pattern_occ ::= @reference {? at @occs_nums }
| @one_term {? at @occs_nums }
- occs_nums ::= {+ {| @natural | @ident } }
- | - {+ {| @natural | @ident } }
+ occs_nums ::= {+ @nat_or_var }
+ | - {+ @nat_or_var }
int_or_var ::= @integer
| @ident
+ nat_or_var ::= @natural
+ | @ident
unfold_occ ::= @reference {? at @occs_nums }
pattern_occ ::= @one_term {? at @occs_nums }
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index 5cbd2e400e..df73de846f 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -603,7 +603,7 @@ Here is the basic example of a notation using a binder:
.. coqtop:: in
Notation "'sigma' x : A , B" := (sigT (fun x : A => B))
- (at level 200, x ident, A at level 200, right associativity).
+ (at level 200, x name, A at level 200, right associativity).
The binding variables in the right-hand side that occur as a parameter
of the notation (here :g:`x`) dynamically bind all the occurrences
@@ -616,8 +616,9 @@ application of the notation:
Check sigma z : nat, z = 0.
-Note the :n:`@syntax_modifier x ident` in the declaration of the
-notation. It tells to parse :g:`x` as a single identifier.
+Note the :n:`@syntax_modifier x name` in the declaration of the
+notation. It tells to parse :g:`x` as a single identifier (or as the
+unnamed variable :g:`_`).
Binders bound in the notation and parsed as patterns
++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -655,7 +656,7 @@ variable. Here is an example showing the difference:
Notation "'subset_bis' ' p , P" := (sig (fun p => P))
(at level 200, p strict pattern).
Notation "'subset_bis' p , P " := (sig (fun p => P))
- (at level 200, p ident).
+ (at level 200, p name).
.. coqtop:: all
@@ -675,18 +676,19 @@ the following:
.. coqdoc::
Notation "{ x : A | P }" := (sig (fun x : A => P))
- (at level 0, x at level 99 as ident).
+ (at level 0, x at level 99 as name).
This is so because the grammar also contains rules starting with :g:`{}` and
followed by a term, such as the rule for the notation :g:`{ A } + { B }` for the
constant :g:`sumbool` (see :ref:`specification`).
-Then, in the rule, ``x ident`` is replaced by ``x at level 99 as ident`` meaning
+Then, in the rule, ``x name`` is replaced by ``x at level 99 as name`` meaning
that ``x`` is parsed as a term at level 99 (as done in the notation for
-:g:`sumbool`), but that this term has actually to be an identifier.
+:g:`sumbool`), but that this term has actually to be a name, i.e. an
+identifier or :g:`_`.
The notation :g:`{ x | P }` is already defined in the standard
-library with the ``as ident`` :n:`@syntax_modifier`. We cannot redefine it but
+library with the ``as name`` :n:`@syntax_modifier`. We cannot redefine it but
one can define an alternative notation, say :g:`{ p such that P }`,
using instead ``as pattern``.
@@ -702,12 +704,12 @@ Then, the following works:
Check {(x,y) such that x+y=0}.
To enforce that the pattern should not be used for printing when it
-is just an identifier, one could have said
+is just a name, one could have said
``p at level 99 as strict pattern``.
-Note also that in the absence of a ``as ident``, ``as strict pattern`` or
+Note also that in the absence of a ``as name``, ``as strict pattern`` or
``as pattern`` :n:`@syntax_modifier`\s, the default is to consider sub-expressions occurring
-in binding position and parsed as terms to be ``as ident``.
+in binding position and parsed as terms to be ``as name``.
Binders bound in the notation and parsed as general binders
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -768,7 +770,7 @@ binding position. Here is an example:
Definition force n (P:nat -> Prop) := forall n', n' >= n -> P n'.
Notation "▢_ n P" := (force n (fun n => P))
- (at level 0, n ident, P at level 9, format "▢_ n P").
+ (at level 0, n name, P at level 9, format "▢_ n P").
.. coqtop:: all
@@ -946,16 +948,31 @@ position of :g:`x`:
(at level 10, f global, a1, an at level 9).
In addition to ``global``, one can restrict the syntax of a
-sub-expression by using the entry names ``ident`` or ``pattern``
+sub-expression by using the entry names ``ident``, ``name`` or ``pattern``
already seen in :ref:`NotationsWithBinders`, even when the
corresponding expression is not used as a binder in the right-hand
side. E.g.:
+ .. todo: these two Set Warnings and the note should be removed when
+ ident is reactivated with its literal meaning.
+
+.. coqtop:: none
+
+ Set Warnings "-deprecated-ident-entry".
+
.. coqtop:: in
Notation "'apply_id' f a1 .. an" := (.. (f a1) .. an)
(at level 10, f ident, a1, an at level 9).
+.. coqtop:: none
+
+ Set Warnings "+deprecated-ident-entry".
+
+.. note:: As of version 8.13, the entry ``ident`` is a deprecated
+ alias for ``name``. In the future, it is planned to strictly
+ parse an identifier (excluding :g:`_`).
+
.. _custom-entries:
Custom entries
@@ -1113,6 +1130,31 @@ gives a way to let any arbitrary expression which is not handled by the
custom entry ``expr`` be parsed or printed by the main grammar of term
up to the insertion of a pair of curly brackets.
+Another special situation is when parsing global references or
+identifiers. To indicate that a custom entry should parse identifiers,
+use the following form:
+
+.. coqtop:: none
+
+ Reset Initial.
+ Declare Custom Entry expr.
+
+.. coqtop:: in
+
+ Notation "x" := x (in custom expr at level 0, x ident).
+
+Similarly, to indicate that a custom entry should parse global references
+(i.e. qualified or non qualified identifiers), use the following form:
+
+.. coqtop:: none
+
+ Reset Initial.
+ Declare Custom Entry expr.
+
+.. coqtop:: in
+
+ Notation "x" := x (in custom expr at level 0, x global).
+
.. cmd:: Print Custom Grammar @ident
:name: Print Custom Grammar
@@ -1142,6 +1184,7 @@ Here are the syntax elements used by the various notation commands.
| only printing
| format @string {? @string }
explicit_subentry ::= ident
+ | name
| global
| bigint
| strict pattern {? at level @natural }
@@ -1151,6 +1194,7 @@ Here are the syntax elements used by the various notation commands.
| custom @ident {? at @level } {? @binder_interp }
| pattern {? at level @natural }
binder_interp ::= as ident
+ | as name
| as pattern
| as strict pattern
level ::= level @natural
@@ -1188,6 +1232,27 @@ Here are the syntax elements used by the various notation commands.
due to legacy notation in the Coq standard library.
It can be turned on with the ``-w disj-pattern-notation`` flag.
+.. note::
+
+ As of version 8.13, the entry ``ident`` is a deprecated alias for
+ ``name``. In the future, it is planned to strictly parse an
+ identifier (to the exclusion of :g:`_`). If the intent was to use
+ ``ident`` as an identifier (excluding :g:`_`), just silence the warning with
+ :n:`Set Warnings "-deprecated-ident-entry"` and it should automatically
+ get its intended meaning in version 8.15.
+
+ Similarly, ``as ident`` is a deprecated alias for ``as name``, which
+ will only accept an identifier in the future. If the
+ intent was to use ``as ident`` as an identifier
+ (excluding :g:`_`), just silence the warning with
+ :n:`Set Warnings "-deprecated-as-ident-kind"`.
+
+ However, this deprecation does not apply to custom entries, where it
+ already denotes an identifier, as expected.
+
+ .. todo: the note above should be removed at the end of deprecation
+ phase of ident
+ ..
.. _Scopes:
Notation scopes
diff --git a/doc/tools/docgram/common.edit_mlg b/doc/tools/docgram/common.edit_mlg
index 816acba4c1..4080eaae08 100644
--- a/doc/tools/docgram/common.edit_mlg
+++ b/doc/tools/docgram/common.edit_mlg
@@ -815,7 +815,10 @@ ltac_expr3: [
| REPLACE "abstract" ltac_expr2 "using" ident
| WITH "abstract" ltac_expr2 OPT ( "using" ident )
| l3_tactic
-| EDIT "do" ADD_OPT int_or_var ssrmmod ssrdotac ssrclauses TAG SSR
+(* | EDIT "do" ADD_OPT nat_or_var ssrmmod ssrdotac ssrclauses TAG SSR *)
+| DELETE "do" ssrmmod ssrdotac ssrclauses (* SSR plugin *)
+| DELETE "do" ssrortacarg ssrclauses (* SSR plugin *)
+| DELETE "do" nat_or_var ssrmmod ssrdotac ssrclauses (* SSR plugin *)
| MOVEALLBUT ltac_builtins
| l3_tactic
| ltac_expr2
@@ -917,13 +920,13 @@ simple_tactic: [
| REPLACE "cofix" ident "with" LIST1 cofixdecl
| WITH "cofix" ident OPT ( "with" LIST1 cofixdecl )
| DELETE "constructor"
-| DELETE "constructor" int_or_var
-| REPLACE "constructor" int_or_var "with" bindings
-| WITH "constructor" OPT int_or_var OPT ( "with" bindings )
+| DELETE "constructor" nat_or_var
+| REPLACE "constructor" nat_or_var "with" bindings
+| WITH "constructor" OPT nat_or_var OPT ( "with" bindings )
| DELETE "econstructor"
-| DELETE "econstructor" int_or_var
-| REPLACE "econstructor" int_or_var "with" bindings
-| WITH "econstructor" OPT ( int_or_var OPT ( "with" bindings ) )
+| DELETE "econstructor" nat_or_var
+| REPLACE "econstructor" nat_or_var "with" bindings
+| WITH "econstructor" OPT ( nat_or_var OPT ( "with" bindings ) )
| DELETE "dependent" "rewrite" orient constr
| REPLACE "dependent" "rewrite" orient constr "in" hyp
| WITH "dependent" "rewrite" orient constr OPT ( "in" hyp )
@@ -1042,12 +1045,12 @@ simple_tactic: [
| DELETE "finish_timing" OPT string
| REPLACE "finish_timing" "(" string ")" OPT string
| WITH "finish_timing" OPT ( "(" string ")" ) OPT string
-| REPLACE "hresolve_core" "(" ident ":=" constr ")" "at" int_or_var "in" constr
-| WITH "hresolve_core" "(" ident ":=" constr ")" OPT ( "at" int_or_var ) "in" constr
+| REPLACE "hresolve_core" "(" ident ":=" constr ")" "at" nat_or_var "in" constr
+| WITH "hresolve_core" "(" ident ":=" constr ")" OPT ( "at" nat_or_var ) "in" constr
| DELETE "hresolve_core" "(" ident ":=" constr ")" "in" constr
-| EDIT "psatz_R" ADD_OPT int_or_var tactic
-| EDIT "psatz_Q" ADD_OPT int_or_var tactic
-| EDIT "psatz_Z" ADD_OPT int_or_var tactic
+| EDIT "psatz_R" ADD_OPT nat_or_var tactic
+| EDIT "psatz_Q" ADD_OPT nat_or_var tactic
+| EDIT "psatz_Z" ADD_OPT nat_or_var tactic
| REPLACE "subst" LIST1 hyp
| WITH "subst" LIST0 hyp
| DELETE "subst"
@@ -1064,11 +1067,11 @@ simple_tactic: [
| DELETE "transparent_abstract" tactic3
| REPLACE "transparent_abstract" tactic3 "using" ident
| WITH "transparent_abstract" ltac_expr3 OPT ( "using" ident )
-| "typeclasses" "eauto" OPT "bfs" OPT int_or_var OPT ( "with" LIST1 preident )
-| DELETE "typeclasses" "eauto" "bfs" OPT int_or_var "with" LIST1 preident
-| DELETE "typeclasses" "eauto" OPT int_or_var "with" LIST1 preident
-| DELETE "typeclasses" "eauto" "bfs" OPT int_or_var
-| DELETE "typeclasses" "eauto" OPT int_or_var
+| "typeclasses" "eauto" OPT "bfs" OPT nat_or_var OPT ( "with" LIST1 preident )
+| DELETE "typeclasses" "eauto" "bfs" OPT nat_or_var "with" LIST1 preident
+| DELETE "typeclasses" "eauto" OPT nat_or_var "with" LIST1 preident
+| DELETE "typeclasses" "eauto" "bfs" OPT nat_or_var
+| DELETE "typeclasses" "eauto" OPT nat_or_var
(* in Tactic Notation: *)
| "setoid_replace" constr "with" constr OPT ( "using" "relation" constr ) OPT ( "in" hyp )
OPT ( "at" LIST1 int_or_var ) OPT ( "by" ltac_expr3 )
@@ -1789,7 +1792,7 @@ tactic_notation_tactics: [
| "field_simplify_eq" OPT ( "[" LIST1 constr "]" ) OPT ( "in" ident )
| "intuition" OPT ltac_expr5 (* todo: Not too keen on things like "with_power_flags" in tauto.ml, not easy to follow *)
| "nsatz" OPT ( "with" "radicalmax" ":=" constr "strategy" ":=" constr "parameters" ":=" constr "variables" ":=" constr )
-| "psatz" constr OPT int_or_var
+| "psatz" constr OPT nat_or_var
| "ring" OPT ( "[" LIST1 constr "]" )
| "ring_simplify" OPT ( "[" LIST1 constr "]" ) LIST1 constr OPT ( "in" ident ) (* todo: ident was "hyp", worth keeping? *)
]
@@ -2536,7 +2539,6 @@ SPLICE: [
| by_arg_tac
| by_tactic
| quantified_hypothesis
-| nat_or_var
| in_hyp_list
| rename
| export_token
diff --git a/doc/tools/docgram/fullGrammar b/doc/tools/docgram/fullGrammar
index 03a20d621b..d01f66c6d7 100644
--- a/doc/tools/docgram/fullGrammar
+++ b/doc/tools/docgram/fullGrammar
@@ -1420,6 +1420,7 @@ syntax_modifiers: [
explicit_subentry: [
| "ident"
+| "name"
| "global"
| "bigint"
| "binder"
@@ -1440,6 +1441,7 @@ at_level_opt: [
binder_interp: [
| "as" "ident"
+| "as" "name"
| "as" "pattern"
| "as" "strict" "pattern"
]
@@ -1479,11 +1481,11 @@ simple_tactic: [
| "right" "with" bindings
| "eright" "with" bindings
| "constructor"
-| "constructor" int_or_var
-| "constructor" int_or_var "with" bindings
+| "constructor" nat_or_var
+| "constructor" nat_or_var "with" bindings
| "econstructor"
-| "econstructor" int_or_var
-| "econstructor" int_or_var "with" bindings
+| "econstructor" nat_or_var
+| "econstructor" nat_or_var "with" bindings
| "specialize" constr_with_bindings
| "specialize" constr_with_bindings "as" simple_intropattern
| "symmetry"
@@ -1582,9 +1584,9 @@ simple_tactic: [
| "generalize_eqs_vars" hyp
| "dependent" "generalize_eqs_vars" hyp
| "specialize_eqs" hyp
-| "hresolve_core" "(" ident ":=" constr ")" "at" int_or_var "in" constr
+| "hresolve_core" "(" ident ":=" constr ")" "at" nat_or_var "in" constr
| "hresolve_core" "(" ident ":=" constr ")" "in" constr
-| "hget_evar" int_or_var
+| "hget_evar" nat_or_var
| "destauto"
| "destauto" "in" hyp
| "transparent_abstract" tactic3
@@ -1617,25 +1619,25 @@ simple_tactic: [
| "trivial" auto_using hintbases
| "info_trivial" auto_using hintbases
| "debug" "trivial" auto_using hintbases
-| "auto" OPT int_or_var auto_using hintbases
-| "info_auto" OPT int_or_var auto_using hintbases
-| "debug" "auto" OPT int_or_var auto_using hintbases
-| "eauto" OPT int_or_var OPT int_or_var auto_using hintbases
-| "new" "auto" OPT int_or_var auto_using hintbases
-| "debug" "eauto" OPT int_or_var OPT int_or_var auto_using hintbases
-| "info_eauto" OPT int_or_var OPT int_or_var auto_using hintbases
-| "dfs" "eauto" OPT int_or_var auto_using hintbases
-| "bfs" "eauto" OPT int_or_var auto_using hintbases
+| "auto" OPT nat_or_var auto_using hintbases
+| "info_auto" OPT nat_or_var auto_using hintbases
+| "debug" "auto" OPT nat_or_var auto_using hintbases
+| "eauto" OPT nat_or_var OPT nat_or_var auto_using hintbases
+| "new" "auto" OPT nat_or_var auto_using hintbases
+| "debug" "eauto" OPT nat_or_var OPT nat_or_var auto_using hintbases
+| "info_eauto" OPT nat_or_var OPT nat_or_var auto_using hintbases
+| "dfs" "eauto" OPT nat_or_var auto_using hintbases
+| "bfs" "eauto" OPT nat_or_var auto_using hintbases
| "autounfold" hintbases clause_dft_concl
| "autounfold_one" hintbases "in" hyp
| "autounfold_one" hintbases
| "unify" constr constr
| "unify" constr constr "with" preident
| "convert_concl_no_check" constr
-| "typeclasses" "eauto" "bfs" OPT int_or_var "with" LIST1 preident
-| "typeclasses" "eauto" OPT int_or_var "with" LIST1 preident
-| "typeclasses" "eauto" "bfs" OPT int_or_var
-| "typeclasses" "eauto" OPT int_or_var
+| "typeclasses" "eauto" "bfs" OPT nat_or_var "with" LIST1 preident
+| "typeclasses" "eauto" OPT nat_or_var "with" LIST1 preident
+| "typeclasses" "eauto" "bfs" OPT nat_or_var
+| "typeclasses" "eauto" OPT nat_or_var
| "head_of_constr" ident constr
| "not_evar" constr
| "is_ground" constr
@@ -1734,7 +1736,7 @@ simple_tactic: [
| "restart_timer" OPT string
| "finish_timing" OPT string
| "finish_timing" "(" string ")" OPT string
-| "psatz_Z" int_or_var tactic (* micromega plugin *)
+| "psatz_Z" nat_or_var tactic (* micromega plugin *)
| "psatz_Z" tactic (* micromega plugin *)
| "xlia" tactic (* micromega plugin *)
| "xnlia" tactic (* micromega plugin *)
@@ -1745,9 +1747,9 @@ simple_tactic: [
| "sos_R" tactic (* micromega plugin *)
| "lra_Q" tactic (* micromega plugin *)
| "lra_R" tactic (* micromega plugin *)
-| "psatz_R" int_or_var tactic (* micromega plugin *)
+| "psatz_R" nat_or_var tactic (* micromega plugin *)
| "psatz_R" tactic (* micromega plugin *)
-| "psatz_Q" int_or_var tactic (* micromega plugin *)
+| "psatz_Q" nat_or_var tactic (* micromega plugin *)
| "psatz_Q" tactic (* micromega plugin *)
| "zify_iter_specs" (* micromega plugin *)
| "zify_op" (* micromega plugin *)
@@ -2022,8 +2024,8 @@ ltac_expr4: [
ltac_expr3: [
| "try" ltac_expr3
-| "do" int_or_var ltac_expr3
-| "timeout" int_or_var ltac_expr3
+| "do" nat_or_var ltac_expr3
+| "timeout" nat_or_var ltac_expr3
| "time" OPT string ltac_expr3
| "repeat" ltac_expr3
| "progress" ltac_expr3
@@ -2036,7 +2038,7 @@ ltac_expr3: [
| ltac_expr2
| "do" ssrmmod ssrdotac ssrclauses (* SSR plugin *)
| "do" ssrortacarg ssrclauses (* SSR plugin *)
-| "do" int_or_var ssrmmod ssrdotac ssrclauses (* SSR plugin *)
+| "do" nat_or_var ssrmmod ssrdotac ssrclauses (* SSR plugin *)
| "abstract" ssrdgens (* SSR plugin *)
]
diff --git a/doc/tools/docgram/orderedGrammar b/doc/tools/docgram/orderedGrammar
index 0209cf762a..f62dd8f731 100644
--- a/doc/tools/docgram/orderedGrammar
+++ b/doc/tools/docgram/orderedGrammar
@@ -652,8 +652,8 @@ ref_or_pattern_occ: [
]
occs_nums: [
-| LIST1 [ natural | ident ]
-| "-" LIST1 [ natural | ident ]
+| LIST1 nat_or_var
+| "-" LIST1 nat_or_var
]
int_or_var: [
@@ -661,6 +661,11 @@ int_or_var: [
| ident
]
+nat_or_var: [
+| natural
+| ident
+]
+
unfold_occ: [
| reference OPT ( "at" occs_nums )
]
@@ -1574,6 +1579,7 @@ syntax_modifier: [
explicit_subentry: [
| "ident"
+| "name"
| "global"
| "bigint"
| "strict" "pattern" OPT ( "at" "level" natural )
@@ -1586,6 +1592,7 @@ explicit_subentry: [
binder_interp: [
| "as" "ident"
+| "as" "name"
| "as" "pattern"
| "as" "strict" "pattern"
]
@@ -1620,8 +1627,8 @@ simple_tactic: [
| "eleft" OPT ( "with" bindings )
| "right" OPT ( "with" bindings )
| "eright" OPT ( "with" bindings )
-| "constructor" OPT int_or_var OPT ( "with" bindings )
-| "econstructor" OPT ( int_or_var OPT ( "with" bindings ) )
+| "constructor" OPT nat_or_var OPT ( "with" bindings )
+| "econstructor" OPT ( nat_or_var OPT ( "with" bindings ) )
| "specialize" one_term OPT ( "with" bindings ) OPT ( "as" simple_intropattern )
| "symmetry" OPT ( "in" in_clause )
| "split" OPT ( "with" bindings )
@@ -1648,8 +1655,8 @@ simple_tactic: [
| bullet
| "}"
| "try" ltac_expr3
-| "do" int_or_var ltac_expr3
-| "timeout" int_or_var ltac_expr3
+| "do" nat_or_var ltac_expr3
+| "timeout" nat_or_var ltac_expr3
| "time" OPT string ltac_expr3
| "repeat" ltac_expr3
| "progress" ltac_expr3
@@ -1658,8 +1665,6 @@ simple_tactic: [
| "infoH" ltac_expr3
| "abstract" ltac_expr2 OPT ( "using" ident )
| "only" selector ":" ltac_expr3
-| "do" "[" ssrortacs "]" OPT ssr_in (* SSR plugin *)
-| "do" OPT int_or_var ssrmmod [ ltac_expr3 | "[" ssrortacs "]" (* SSR plugin *) ] OPT ssr_in (* SSR plugin *)
| "tryif" ltac_expr "then" ltac_expr "else" ltac_expr2
| "first" "[" LIST0 ltac_expr SEP "|" "]"
| "solve" "[" LIST0 ltac_expr SEP "|" "]"
@@ -1718,8 +1723,8 @@ simple_tactic: [
| "generalize_eqs_vars" ident
| "dependent" "generalize_eqs_vars" ident
| "specialize_eqs" ident
-| "hresolve_core" "(" ident ":=" one_term ")" OPT ( "at" int_or_var ) "in" one_term
-| "hget_evar" int_or_var
+| "hresolve_core" "(" ident ":=" one_term ")" OPT ( "at" nat_or_var ) "in" one_term
+| "hget_evar" nat_or_var
| "destauto" OPT ( "in" ident )
| "transparent_abstract" ltac_expr3 OPT ( "using" ident )
| "constr_eq" one_term one_term
@@ -1756,20 +1761,20 @@ simple_tactic: [
| "trivial" OPT auto_using OPT hintbases
| "info_trivial" OPT auto_using OPT hintbases
| "debug" "trivial" OPT auto_using OPT hintbases
-| "auto" OPT int_or_var OPT auto_using OPT hintbases
-| "info_auto" OPT int_or_var OPT auto_using OPT hintbases
-| "debug" "auto" OPT int_or_var OPT auto_using OPT hintbases
-| "eauto" OPT int_or_var OPT int_or_var OPT auto_using OPT hintbases
-| "new" "auto" OPT int_or_var OPT auto_using OPT hintbases
-| "debug" "eauto" OPT int_or_var OPT int_or_var OPT auto_using OPT hintbases
-| "info_eauto" OPT int_or_var OPT int_or_var OPT auto_using OPT hintbases
-| "dfs" "eauto" OPT int_or_var OPT auto_using OPT hintbases
-| "bfs" "eauto" OPT int_or_var OPT auto_using OPT hintbases
+| "auto" OPT nat_or_var OPT auto_using OPT hintbases
+| "info_auto" OPT nat_or_var OPT auto_using OPT hintbases
+| "debug" "auto" OPT nat_or_var OPT auto_using OPT hintbases
+| "eauto" OPT nat_or_var OPT nat_or_var OPT auto_using OPT hintbases
+| "new" "auto" OPT nat_or_var OPT auto_using OPT hintbases
+| "debug" "eauto" OPT nat_or_var OPT nat_or_var OPT auto_using OPT hintbases
+| "info_eauto" OPT nat_or_var OPT nat_or_var OPT auto_using OPT hintbases
+| "dfs" "eauto" OPT nat_or_var OPT auto_using OPT hintbases
+| "bfs" "eauto" OPT nat_or_var OPT auto_using OPT hintbases
| "autounfold" OPT hintbases OPT clause_dft_concl
| "autounfold_one" OPT hintbases OPT ( "in" ident )
| "unify" one_term one_term OPT ( "with" ident )
| "convert_concl_no_check" one_term
-| "typeclasses" "eauto" OPT "bfs" OPT int_or_var OPT ( "with" LIST1 ident )
+| "typeclasses" "eauto" OPT "bfs" OPT nat_or_var OPT ( "with" LIST1 ident )
| "head_of_constr" ident one_term
| "not_evar" one_term
| "is_ground" one_term
@@ -1859,7 +1864,7 @@ simple_tactic: [
| "functional" "inversion" [ ident | natural ] OPT qualid (* funind plugin *)
| "functional" "induction" term OPT ( "using" one_term OPT ( "with" bindings ) ) OPT ( "as" simple_intropattern ) (* funind plugin *)
| "soft" "functional" "induction" LIST1 one_term OPT ( "using" one_term OPT ( "with" bindings ) ) OPT ( "as" simple_intropattern ) (* funind plugin *)
-| "psatz_Z" OPT int_or_var ltac_expr
+| "psatz_Z" OPT nat_or_var ltac_expr
| "xlia" ltac_expr (* micromega plugin *)
| "xnlia" ltac_expr (* micromega plugin *)
| "xnra" ltac_expr (* micromega plugin *)
@@ -1869,8 +1874,8 @@ simple_tactic: [
| "sos_R" ltac_expr (* micromega plugin *)
| "lra_Q" ltac_expr (* micromega plugin *)
| "lra_R" ltac_expr (* micromega plugin *)
-| "psatz_R" OPT int_or_var ltac_expr
-| "psatz_Q" OPT int_or_var ltac_expr
+| "psatz_R" OPT nat_or_var ltac_expr
+| "psatz_Q" OPT nat_or_var ltac_expr
| "zify_iter_specs" (* micromega plugin *)
| "zify_op" (* micromega plugin *)
| "zify_saturate" (* micromega plugin *)
@@ -1942,7 +1947,7 @@ simple_tactic: [
| "field_simplify_eq" OPT ( "[" LIST1 one_term "]" ) OPT ( "in" ident )
| "intuition" OPT ltac_expr
| "nsatz" OPT ( "with" "radicalmax" ":=" one_term "strategy" ":=" one_term "parameters" ":=" one_term "variables" ":=" one_term )
-| "psatz" one_term OPT int_or_var
+| "psatz" one_term OPT nat_or_var
| "ring" OPT ( "[" LIST1 one_term "]" )
| "ring_simplify" OPT ( "[" LIST1 one_term "]" ) LIST1 one_term OPT ( "in" ident )
| "match" ltac2_expr5 "with" OPT ltac2_branches "end"
diff --git a/engine/logic_monad.ml b/engine/logic_monad.ml
index 4c7ed9047d..38ec668884 100644
--- a/engine/logic_monad.ml
+++ b/engine/logic_monad.ml
@@ -99,7 +99,7 @@ struct
let print_char = fun c -> (); fun () -> print_char c
let timeout = fun n t -> (); fun () ->
- Control.timeout n t () (Exception Tac_Timeout)
+ Control.timeout n t ()
let make f = (); fun () ->
try f ()
diff --git a/engine/logic_monad.mli b/engine/logic_monad.mli
index 7df29c6653..7784b38c80 100644
--- a/engine/logic_monad.mli
+++ b/engine/logic_monad.mli
@@ -74,7 +74,7 @@ module NonLogical : sig
(** [try ... with ...] but restricted to {!Exception}. *)
val catch : 'a t -> (Exninfo.iexn -> 'a t) -> 'a t
- val timeout : int -> 'a t -> 'a t
+ val timeout : int -> 'a t -> 'a option t
(** Construct a monadified side-effect. Exceptions raised by the argument are
wrapped with {!Exception}. *)
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 978088872c..22863f451d 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -937,22 +937,12 @@ let tclTIMEOUT n t =
Proof.get >>= fun initial ->
Proof.current >>= fun envvar ->
Proof.lift begin
- Logic_monad.NonLogical.catch
- begin
- let open Logic_monad.NonLogical in
- timeout n (Proof.repr (Proof.run t envvar initial)) >>= fun r ->
- match r with
- | Logic_monad.Nil e -> return (Util.Inr e)
- | Logic_monad.Cons (r, _) -> return (Util.Inl r)
- end
- begin let open Logic_monad.NonLogical in function (e, info) ->
- match e with
- | Logic_monad.Tac_Timeout ->
- return (Util.Inr (Logic_monad.Tac_Timeout, info))
- | Logic_monad.TacticFailure e ->
- return (Util.Inr (e, info))
- | e -> Logic_monad.NonLogical.raise (e, info)
- end
+ let open Logic_monad.NonLogical in
+ timeout n (Proof.repr (Proof.run t envvar initial)) >>= fun r ->
+ match r with
+ | None -> return (Util.Inr (Logic_monad.Tac_Timeout, Exninfo.null))
+ | Some (Logic_monad.Nil e) -> return (Util.Inr e)
+ | Some (Logic_monad.Cons (r, _)) -> return (Util.Inl r)
end >>= function
| Util.Inl (res,s,m,i) ->
Proof.set s >>
diff --git a/engine/proofview.mli b/engine/proofview.mli
index 816b45984b..fe0d7ae51e 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -417,7 +417,7 @@ end
val tclCHECKINTERRUPT : unit tactic
(** [tclTIMEOUT n t] can have only one success.
- In case of timeout if fails with [tclZERO Timeout]. *)
+ In case of timeout it fails with [tclZERO Tac_Timeout]. *)
val tclTIMEOUT : int -> 'a tactic -> 'a tactic
(** [tclTIME s t] displays time for each atomic call to t, using s as an
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 8bd77abc4a..0645636255 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -976,6 +976,9 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
into a substitution for interpretation and based on binding/constr
distinction *)
+let cases_pattern_of_id {loc;v=id} =
+ CAst.make ?loc (CPatAtom (Some (qualid_of_ident ?loc id)))
+
let cases_pattern_of_name {loc;v=na} =
let atom = match na with Name id -> Some (qualid_of_ident ?loc id) | Anonymous -> None in
CAst.make ?loc (CPatAtom atom)
@@ -991,16 +994,20 @@ let split_by_type ids subst =
| NtnTypeConstr ->
let terms,terms' = bind id scl terms terms' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
- | NtnTypeBinder NtnBinderParsedAsConstr (AsIdentOrPattern | AsStrictPattern) ->
+ | NtnTypeBinder NtnBinderParsedAsConstr (AsNameOrPattern | AsStrictPattern) ->
let a,terms = match terms with a::terms -> a,terms | _ -> assert false in
let binders' = Id.Map.add id ((coerce_to_cases_pattern_expr a,Explicit),(false,scl)) binders' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
| NtnTypeBinder NtnBinderParsedAsConstr AsIdent ->
let a,terms = match terms with a::terms -> a,terms | _ -> assert false in
+ let binders' = Id.Map.add id ((cases_pattern_of_id (coerce_to_id a),Explicit),(true,scl)) binders' in
+ (terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
+ | NtnTypeBinder NtnBinderParsedAsConstr AsName ->
+ let a,terms = match terms with a::terms -> a,terms | _ -> assert false in
let binders' = Id.Map.add id ((cases_pattern_of_name (coerce_to_name a),Explicit),(true,scl)) binders' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
- | NtnTypeBinder (NtnParsedAsIdent | NtnParsedAsPattern _ | NtnParsedAsBinder as x) ->
- let onlyident = (x = NtnParsedAsIdent) in
+ | NtnTypeBinder (NtnParsedAsIdent | NtnParsedAsName | NtnParsedAsPattern _ | NtnParsedAsBinder as x) ->
+ let onlyident = (x = NtnParsedAsIdent || x = NtnParsedAsName) in
let binders,binders' = bind id (onlyident,scl) binders binders' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
| NtnTypeConstrList ->
diff --git a/interp/notation.ml b/interp/notation.ml
index b5951a9c59..c35ba44aa5 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -62,10 +62,11 @@ let pair_eq f g (x1, y1) (x2, y2) = f x1 x2 && g y1 y2
let notation_binder_source_eq s1 s2 = match s1, s2 with
| NtnParsedAsIdent, NtnParsedAsIdent -> true
+| NtnParsedAsName, NtnParsedAsName -> true
| NtnParsedAsPattern b1, NtnParsedAsPattern b2 -> b1 = b2
| NtnBinderParsedAsConstr bk1, NtnBinderParsedAsConstr bk2 -> bk1 = bk2
| NtnParsedAsBinder, NtnParsedAsBinder -> true
-| (NtnParsedAsIdent | NtnParsedAsPattern _ | NtnBinderParsedAsConstr _ | NtnParsedAsBinder), _ -> false
+| (NtnParsedAsIdent | NtnParsedAsName | NtnParsedAsPattern _ | NtnBinderParsedAsConstr _ | NtnParsedAsBinder), _ -> false
let ntpe_eq t1 t2 = match t1, t2 with
| NtnTypeConstr, NtnTypeConstr -> true
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index f51d3bfdfb..036970ce37 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -881,7 +881,7 @@ let is_onlybinding_meta id metas =
let is_onlybinding_pattern_like_meta isvar id metas =
try match Id.List.assoc id metas with
| _,NtnTypeBinder (NtnBinderParsedAsConstr
- (AsIdentOrPattern | AsStrictPattern)) -> true
+ (AsNameOrPattern | AsStrictPattern)) -> true
| _,NtnTypeBinder (NtnParsedAsPattern strict) -> not (strict && isvar)
| _,NtnTypeBinder NtnParsedAsBinder -> not isvar
| _ -> false
@@ -1533,7 +1533,7 @@ let match_notation_constr ~print_univ c ~vars (metas,pat) =
let v = glob_constr_of_cases_pattern (Global.env()) pat in
(((vars,v),scl)::terms',termlists',binders',binderlists')
| _ -> raise No_match)
- | NtnTypeBinder (NtnParsedAsIdent | NtnParsedAsPattern _ | NtnParsedAsBinder) ->
+ | NtnTypeBinder (NtnParsedAsIdent | NtnParsedAsName | NtnParsedAsPattern _ | NtnParsedAsBinder) ->
(terms',termlists',(Id.List.assoc x binders,scl)::binders',binderlists')
| NtnTypeConstrList ->
(terms',(Id.List.assoc x termlists,scl)::termlists',binders',binderlists')
diff --git a/interp/notation_term.ml b/interp/notation_term.ml
index 29db23cc54..c541a19bfd 100644
--- a/interp/notation_term.ml
+++ b/interp/notation_term.ml
@@ -67,7 +67,8 @@ type extended_subscopes = Constrexpr.notation_entry_level * subscopes
type constr_as_binder_kind =
| AsIdent
- | AsIdentOrPattern
+ | AsName
+ | AsNameOrPattern
| AsStrictPattern
type notation_binder_source =
@@ -76,6 +77,8 @@ type notation_binder_source =
| NtnParsedAsPattern of bool
(* This accepts only ident *)
| NtnParsedAsIdent
+ (* This accepts only name *)
+ | NtnParsedAsName
(* This accepts ident, or pattern, or both *)
| NtnBinderParsedAsConstr of constr_as_binder_kind
(* This accepts ident, _, and quoted pattern *)
diff --git a/interp/stdarg.ml b/interp/stdarg.ml
index 70be55f843..a953ca8898 100644
--- a/interp/stdarg.ml
+++ b/interp/stdarg.ml
@@ -37,6 +37,9 @@ let wit_pre_ident : string uniform_genarg_type =
let wit_int_or_var =
make0 ~dyn:(val_tag (topwit wit_int)) "int_or_var"
+let wit_nat_or_var =
+ make0 ~dyn:(val_tag (topwit wit_nat)) "nat_or_var"
+
let wit_ident =
make0 "ident"
diff --git a/interp/stdarg.mli b/interp/stdarg.mli
index bd34af5543..0a8fdf53b1 100644
--- a/interp/stdarg.mli
+++ b/interp/stdarg.mli
@@ -35,6 +35,8 @@ val wit_pre_ident : string uniform_genarg_type
val wit_int_or_var : (int or_var, int or_var, int) genarg_type
+val wit_nat_or_var : (int or_var, int or_var, int) genarg_type
+
val wit_ident : Id.t uniform_genarg_type
val wit_hyp : (lident, lident, Id.t) genarg_type
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index 17feeb9b5a..c9326615dc 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -263,7 +263,7 @@ let assoc_defined id env = match Environ.lookup_named id env with
* before the term is computed.
*)
-(* Norm means the term is fully normalized and cannot create a redex
+(* Ntrl means the term is fully normalized and cannot create a redex
when substituted
Cstr means the term is in head normal form and that it can
create a redex when substituted (i.e. constructor, fix, lambda)
@@ -271,10 +271,10 @@ let assoc_defined id env = match Environ.lookup_named id env with
create a redex when substituted
Red is used for terms that might be reduced
*)
-type red_state = Norm | Cstr | Whnf | Red
+type red_state = Ntrl | Cstr | Whnf | Red
let neutr = function
- | Whnf|Norm -> Whnf
+ | Whnf|Ntrl -> Whnf
| Red|Cstr -> Red
type optrel = Unknown | KnownR | KnownI
@@ -293,13 +293,13 @@ module Mark : sig
val neutr : t -> t
- val set_norm : t -> t
+ val set_ntrl : t -> t
end = struct
type t = int
let[@inline] of_state = function
- | Norm -> 0b00 | Cstr -> 0b01 | Whnf -> 0b10 | Red -> 0b11
+ | Ntrl -> 0b00 | Cstr -> 0b01 | Whnf -> 0b10 | Red -> 0b11
let[@inline] of_relevance = function
| Unknown -> 0
@@ -315,15 +315,15 @@ end = struct
| _ -> assert false
let[@inline] red_state x = match x land 0b1100 with
- | 0b0000 -> Norm
+ | 0b0000 -> Ntrl
| 0b0100 -> Cstr
| 0b1000 -> Whnf
| 0b1100 -> Red
| _ -> assert false
- let[@inline] neutr x = x lor 0b1000 (* Whnf|Norm -> Whnf | Red|Cstr -> Red *)
+ let[@inline] neutr x = x lor 0b1000 (* Whnf|Ntrl -> Whnf | Red|Cstr -> Red *)
- let[@inline] set_norm x = x land 0b0011
+ let[@inline] set_ntrl x = x land 0b0011
end
let mark = Mark.mark
@@ -358,10 +358,10 @@ and fterm =
and finvert = Univ.Instance.t * fconstr array
let fterm_of v = v.term
-let set_norm v = v.mark <- Mark.set_norm v.mark
-let is_val v = match Mark.red_state v.mark with Norm -> true | Cstr | Whnf | Red -> false
+let set_ntrl v = v.mark <- Mark.set_ntrl v.mark
+let is_val v = match Mark.red_state v.mark with Ntrl -> true | Cstr | Whnf | Red -> false
-let mk_atom c = {mark=mark Norm Unknown;term=FAtom c}
+let mk_atom c = {mark=mark Ntrl Unknown;term=FAtom c}
let mk_red f = {mark=mark Red Unknown;term=f}
(* Could issue a warning if no is still Red, pointing out that we loose
@@ -448,7 +448,7 @@ let rec lft_fconstr n ft =
let r = Mark.relevance ft.mark in
match ft.term with
| (FInd _|FConstruct _|FFlex(ConstKey _|VarKey _)|FInt _|FFloat _) -> ft
- | FRel i -> {mark=mark Norm r;term=FRel(i+n)}
+ | FRel i -> {mark=mark Ntrl r;term=FRel(i+n)}
| FLambda(k,tys,f,e) -> {mark=mark Cstr r; term=FLambda(k,tys,f,subs_shft(n,e))}
| FFix(fx,e) ->
{mark=mark Cstr r; term=FFix(fx,subs_shft(n,e))}
@@ -466,7 +466,7 @@ let lift_fconstr_vect k v =
let clos_rel e i =
match expand_rel i e with
| Inl(n,mt) -> lift_fconstr n mt
- | Inr(k,None) -> {mark=mark Norm Unknown; term= FRel k}
+ | Inr(k,None) -> {mark=mark Ntrl Unknown; term= FRel k}
| Inr(k,Some p) ->
lift_fconstr (k-p) {mark=mark Red Unknown;term=FFlex(RelKey p)}
@@ -488,7 +488,7 @@ let compact_stack head stk =
(* Put an update mark in the stack, only if needed *)
let zupdate info m s =
let share = info.i_cache.i_share in
- if share && begin match Mark.red_state m.mark with Red -> true | Norm | Whnf | Cstr -> false end
+ if share && begin match Mark.red_state m.mark with Red -> true | Ntrl | Whnf | Cstr -> false end
then
let s' = compact_stack m s in
let _ = m.term <- FLOCKED in
@@ -514,8 +514,8 @@ let mk_clos e t =
| Rel i -> clos_rel e i
| Var x -> {mark = mark Red Unknown; term = FFlex (VarKey x) }
| Const c -> {mark = mark Red Unknown; term = FFlex (ConstKey c) }
- | Meta _ | Sort _ -> {mark = mark Norm KnownR; term = FAtom t }
- | Ind kn -> {mark = mark Norm KnownR; term = FInd kn }
+ | Meta _ | Sort _ -> {mark = mark Ntrl KnownR; term = FAtom t }
+ | Ind kn -> {mark = mark Ntrl KnownR; term = FInd kn }
| Construct kn -> {mark = mark Cstr Unknown; term = FConstruct kn }
| Int i -> {mark = mark Cstr Unknown; term = FInt i}
| Float f -> {mark = mark Cstr Unknown; term = FFloat f}
@@ -734,11 +734,11 @@ let strip_update_shift_app_red head stk =
strip_rec [] head 0 stk
let strip_update_shift_app head stack =
- assert (match Mark.red_state head.mark with Red -> false | Norm | Cstr | Whnf -> true);
+ assert (match Mark.red_state head.mark with Red -> false | Ntrl | Cstr | Whnf -> true);
strip_update_shift_app_red head stack
let get_nth_arg head n stk =
- assert (match Mark.red_state head.mark with Red -> false | Norm | Cstr | Whnf -> true);
+ assert (match Mark.red_state head.mark with Red -> false | Ntrl | Cstr | Whnf -> true);
let rec strip_rec rstk h n = function
| Zshift(k) as e :: s ->
strip_rec (e::rstk) (lift_fconstr k h) n s
@@ -787,7 +787,7 @@ let rec eta_expand_stack = function
| Zshift _ | Zupdate _ | Zprimitive _ as e) :: s ->
e :: eta_expand_stack s
| [] ->
- [Zshift 1; Zapp [|{mark=mark Norm Unknown; term= FRel 1}|]]
+ [Zshift 1; Zapp [|{mark=mark Ntrl Unknown; term= FRel 1}|]]
(* Get the arguments of a native operator *)
let rec skip_native_args rargs nargs =
@@ -968,7 +968,7 @@ module FNativeEntries =
| FArray (_u,t,_ty) -> t
| _ -> raise Not_found
- let dummy = {mark = mark Norm KnownR; term = FRel 0}
+ let dummy = {mark = mark Ntrl KnownR; term = FRel 0}
let current_retro = ref Retroknowledge.empty
let defined_int = ref false
@@ -978,7 +978,7 @@ module FNativeEntries =
match retro.Retroknowledge.retro_int63 with
| Some c ->
defined_int := true;
- fint := { mark = mark Norm KnownR; term = FFlex (ConstKey (Univ.in_punivs c)) }
+ fint := { mark = mark Ntrl KnownR; term = FFlex (ConstKey (Univ.in_punivs c)) }
| None -> defined_int := false
let defined_float = ref false
@@ -988,7 +988,7 @@ module FNativeEntries =
match retro.Retroknowledge.retro_float64 with
| Some c ->
defined_float := true;
- ffloat := { mark = mark Norm KnownR; term = FFlex (ConstKey (Univ.in_punivs c)) }
+ ffloat := { mark = mark Ntrl KnownR; term = FFlex (ConstKey (Univ.in_punivs c)) }
| None -> defined_float := false
let defined_bool = ref false
@@ -1039,7 +1039,7 @@ module FNativeEntries =
fLt := { mark = mark Cstr KnownR; term = FConstruct (Univ.in_punivs cLt) };
fGt := { mark = mark Cstr KnownR; term = FConstruct (Univ.in_punivs cGt) };
let (icmp, _) = cEq in
- fcmp := { mark = mark Norm KnownR; term = FInd (Univ.in_punivs icmp) }
+ fcmp := { mark = mark Ntrl KnownR; term = FInd (Univ.in_punivs icmp) }
| None -> defined_cmp := false
let defined_f_cmp = ref false
@@ -1327,19 +1327,19 @@ let rec knr info tab m stk =
let rargs, a, nargs, stk = get_native_args1 op c stk in
kni info tab a (Zprimitive(op,c,rargs,nargs)::stk)
else
- (* Similarly to fix, partially applied primitives are not Norm! *)
+ (* Similarly to fix, partially applied primitives are not Ntrl! *)
(m, stk)
- | Undef _ | OpaqueDef _ -> (set_norm m; (m,stk)))
+ | Undef _ | OpaqueDef _ -> (set_ntrl m; (m,stk)))
| FFlex(VarKey id) when red_set info.i_flags (fVAR id) ->
(match ref_value_cache info tab (VarKey id) with
| Def v -> kni info tab v stk
| Primitive _ -> assert false
- | OpaqueDef _ | Undef _ -> (set_norm m; (m,stk)))
+ | OpaqueDef _ | Undef _ -> (set_ntrl m; (m,stk)))
| FFlex(RelKey k) when red_set info.i_flags fDELTA ->
(match ref_value_cache info tab (RelKey k) with
| Def v -> kni info tab v stk
| Primitive _ -> assert false
- | OpaqueDef _ | Undef _ -> (set_norm m; (m,stk)))
+ | OpaqueDef _ | Undef _ -> (set_ntrl m; (m,stk)))
| FConstruct((_ind,c),_u) ->
let use_match = red_set info.i_flags fMATCH in
let use_fix = red_set info.i_flags fFIX in
@@ -1523,9 +1523,9 @@ let norm_val info tab v =
with_stats (lazy (kl info tab v))
let whd_stack infos tab m stk = match Mark.red_state m.mark with
-| Whnf | Norm ->
+| Whnf | Ntrl ->
(** No need to perform [kni] nor to unlock updates because
- every head subterm of [m] is [Whnf] or [Norm] *)
+ every head subterm of [m] is [Whnf] or [Ntrl] *)
knh infos m stk
| Red | Cstr ->
let k = kni infos tab m stk in
diff --git a/lib/cErrors.ml b/lib/cErrors.ml
index cb64e36755..760c07783b 100644
--- a/lib/cErrors.ml
+++ b/lib/cErrors.ml
@@ -37,7 +37,7 @@ let user_err ?loc ?info ?hdr strm =
let info = Option.cata (Loc.add_loc info) info loc in
Exninfo.iraise (UserError (hdr, strm), info)
-exception Timeout
+exception Timeout = Control.Timeout
(** Only anomalies should reach the bottom of the handler stack.
In usual situation, the [handle_stack] is treated as it if was always
@@ -135,7 +135,7 @@ let _ = register_handler begin function
| UserError(s, pps) ->
Some (where s ++ pps)
| _ -> None
-end
+ end
(** Critical exceptions should not be caught and ignored by mistake
by inner functions during a [vernacinterp]. They should be handled
@@ -145,7 +145,7 @@ end
let noncritical = function
| Sys.Break | Out_of_memory | Stack_overflow
| Assert_failure _ | Match_failure _ | Anomaly _
- | Timeout -> false
+ | Control.Timeout -> false
| Invalid_argument "equal: functional value" -> false
| _ -> true
[@@@ocaml.warning "+52"]
diff --git a/lib/control.ml b/lib/control.ml
index 95ea3935a7..7da95ff3dd 100644
--- a/lib/control.ml
+++ b/lib/control.ml
@@ -16,6 +16,8 @@ let steps = ref 0
let enable_thread_delay = ref false
+exception Timeout
+
let check_for_interrupt () =
if !interrupt then begin interrupt := false; raise Sys.Break end;
if !enable_thread_delay then begin
@@ -27,8 +29,8 @@ let check_for_interrupt () =
end
(** This function does not work on windows, sigh... *)
-let unix_timeout n f x e =
- let timeout_handler _ = raise e in
+let unix_timeout n f x =
+ let timeout_handler _ = raise Timeout in
let psh = Sys.signal Sys.sigalrm (Sys.Signal_handle timeout_handler) in
let _ = Unix.alarm n in
let restore_timeout () =
@@ -38,13 +40,13 @@ let unix_timeout n f x e =
try
let res = f x in
restore_timeout ();
- res
- with e ->
- let e = Exninfo.capture e in
+ Some res
+ with Timeout ->
restore_timeout ();
- Exninfo.iraise e
+ None
+
-let windows_timeout n f x e =
+let windows_timeout n f x =
let killed = ref false in
let exited = ref false in
let thread init =
@@ -70,18 +72,18 @@ let windows_timeout n f x e =
exited := true;
raise Sys.Break
end in
- res
+ Some res
with
| Sys.Break ->
(* Just in case, it could be a regular Ctrl+C *)
if not !exited then begin killed := true; raise Sys.Break end
- else raise e
+ else None
| e ->
let e = Exninfo.capture e in
let () = killed := true in
Exninfo.iraise e
-type timeout = { timeout : 'a 'b. int -> ('a -> 'b) -> 'a -> exn -> 'b }
+type timeout = { timeout : 'a 'b. int -> ('a -> 'b) -> 'a -> 'b option }
let timeout_fun = match Sys.os_type with
| "Unix" | "Cygwin" -> { timeout = unix_timeout }
@@ -90,7 +92,7 @@ let timeout_fun = match Sys.os_type with
let timeout_fun_ref = ref timeout_fun
let set_timeout f = timeout_fun_ref := f
-let timeout n f e = !timeout_fun_ref.timeout n f e
+let timeout n f = !timeout_fun_ref.timeout n f
let protect_sigalrm f x =
let timed_out = ref false in
diff --git a/lib/control.mli b/lib/control.mli
index 25135934bc..9465d8f0d5 100644
--- a/lib/control.mli
+++ b/lib/control.mli
@@ -10,6 +10,9 @@
(** Global control of Coq. *)
+(** Used to convert signals to exceptions *)
+exception Timeout
+
(** Will periodically call [Thread.delay] if set to true *)
val enable_thread_delay : bool ref
@@ -21,13 +24,13 @@ val check_for_interrupt : unit -> unit
(** Use this function as a potential yield function. If {!interrupt} has been
set, il will raise [Sys.Break]. *)
-val timeout : int -> ('a -> 'b) -> 'a -> exn -> 'b
-(** [timeout n f x e] tries to compute [f x], and if it fails to do so
- before [n] seconds, it raises [e] instead. *)
+val timeout : int -> ('a -> 'b) -> 'a -> 'b option
+(** [timeout n f x] tries to compute [Some (f x)], and if it fails to do so
+ before [n] seconds, returns [None] instead. *)
(** Set a particular timeout function; warning, this is an internal
API and it is scheduled to go away. *)
-type timeout = { timeout : 'a 'b. int -> ('a -> 'b) -> 'a -> exn -> 'b }
+type timeout = { timeout : 'a 'b. int -> ('a -> 'b) -> 'a -> 'b option }
val set_timeout : timeout -> unit
(** [protect_sigalrm f x] computes [f x], but if SIGALRM is received during that
diff --git a/parsing/extend.ml b/parsing/extend.ml
index 94c3768116..7d2ed9aed0 100644
--- a/parsing/extend.ml
+++ b/parsing/extend.ml
@@ -32,6 +32,7 @@ let production_level_eq lev1 lev2 =
type 'a constr_entry_key_gen =
| ETIdent
+ | ETName of bool (* Temporary: true = user told "name", false = user wrote "ident" *)
| ETGlobal
| ETBigint
| ETBinder of bool (* open list of binders if true, closed list of binders otherwise *)
@@ -55,6 +56,7 @@ type binder_entry_kind = ETBinderOpen | ETBinderClosed of string Tok.p list
type binder_target = ForBinder | ForTerm
type constr_prod_entry_key =
+ | ETProdIdent (* Parsed as an ident *)
| ETProdName (* Parsed as a name (ident or _) *)
| ETProdReference (* Parsed as a global reference *)
| ETProdBigint (* Parsed as an (unbounded) integer *)
diff --git a/parsing/extend.mli b/parsing/extend.mli
index b698415fd6..3cea45c3f5 100644
--- a/parsing/extend.mli
+++ b/parsing/extend.mli
@@ -27,6 +27,7 @@ val production_level_eq : production_level -> production_level -> bool
type 'a constr_entry_key_gen =
| ETIdent
+ | ETName of bool (* Temporary: true = user told "name", false = user wrote "ident" *)
| ETGlobal
| ETBigint
| ETBinder of bool (* open list of binders if true, closed list of binders otherwise *)
@@ -50,6 +51,7 @@ type binder_entry_kind = ETBinderOpen | ETBinderClosed of string Tok.p list
type binder_target = ForBinder | ForTerm
type constr_prod_entry_key =
+ | ETProdIdent (* Parsed as an ident *)
| ETProdName (* Parsed as a name (ident or _) *)
| ETProdReference (* Parsed as a global reference *)
| ETProdBigint (* Parsed as an (unbounded) integer *)
diff --git a/plugins/ltac/coretactics.mlg b/plugins/ltac/coretactics.mlg
index b7ac71181a..e39c066c95 100644
--- a/plugins/ltac/coretactics.mlg
+++ b/plugins/ltac/coretactics.mlg
@@ -122,10 +122,10 @@ END
TACTIC EXTEND constructor
| [ "constructor" ] -> { Tactics.any_constructor false None }
-| [ "constructor" int_or_var(i) ] -> {
+| [ "constructor" nat_or_var(i) ] -> {
Tactics.constructor_tac false None i NoBindings
}
-| [ "constructor" int_or_var(i) "with" bindings(bl) ] -> {
+| [ "constructor" nat_or_var(i) "with" bindings(bl) ] -> {
let tac bl = Tactics.constructor_tac false None i bl in
Tacticals.New.tclDELAYEDWITHHOLES false bl tac
}
@@ -133,10 +133,10 @@ END
TACTIC EXTEND econstructor
| [ "econstructor" ] -> { Tactics.any_constructor true None }
-| [ "econstructor" int_or_var(i) ] -> {
+| [ "econstructor" nat_or_var(i) ] -> {
Tactics.constructor_tac true None i NoBindings
}
-| [ "econstructor" int_or_var(i) "with" bindings(bl) ] -> {
+| [ "econstructor" nat_or_var(i) "with" bindings(bl) ] -> {
let tac bl = Tactics.constructor_tac true None i bl in
Tacticals.New.tclDELAYEDWITHHOLES true bl tac
}
diff --git a/plugins/ltac/extratactics.mlg b/plugins/ltac/extratactics.mlg
index a2a47c0bf4..6ab82b1253 100644
--- a/plugins/ltac/extratactics.mlg
+++ b/plugins/ltac/extratactics.mlg
@@ -686,7 +686,7 @@ let hResolve_auto id c t =
}
TACTIC EXTEND hresolve_core
-| [ "hresolve_core" "(" ident(id) ":=" constr(c) ")" "at" int_or_var(occ) "in" constr(t) ] -> { hResolve id c occ t }
+| [ "hresolve_core" "(" ident(id) ":=" constr(c) ")" "at" nat_or_var(occ) "in" constr(t) ] -> { hResolve id c occ t }
| [ "hresolve_core" "(" ident(id) ":=" constr(c) ")" "in" constr(t) ] -> { hResolve_auto id c t }
END
@@ -695,7 +695,7 @@ END
*)
TACTIC EXTEND hget_evar
-| [ "hget_evar" int_or_var(n) ] -> { Evar_tactics.hget_evar n }
+| [ "hget_evar" nat_or_var(n) ] -> { Evar_tactics.hget_evar n }
END
(**********************************************************************)
diff --git a/plugins/ltac/g_auto.mlg b/plugins/ltac/g_auto.mlg
index 7e8400910c..eed9419946 100644
--- a/plugins/ltac/g_auto.mlg
+++ b/plugins/ltac/g_auto.mlg
@@ -96,17 +96,17 @@ TACTIC EXTEND debug_trivial
END
TACTIC EXTEND auto
-| [ "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+| [ "auto" nat_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
{ Auto.h_auto n (eval_uconstrs ist lems) db }
END
TACTIC EXTEND info_auto
-| [ "info_auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+| [ "info_auto" nat_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
{ Auto.h_auto ~debug:Info n (eval_uconstrs ist lems) db }
END
TACTIC EXTEND debug_auto
-| [ "debug" "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+| [ "debug" "auto" nat_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
{ Auto.h_auto ~debug:Debug n (eval_uconstrs ist lems) db }
END
@@ -130,15 +130,15 @@ let deprecated_bfs tacname =
}
TACTIC EXTEND eauto
-| [ "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+| [ "eauto" nat_or_var_opt(n) nat_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
{
( match n,p with Some _, Some _ -> deprecated_eauto_bfs () | _ -> () );
Eauto.gen_eauto (Eauto.make_dimension n p) (eval_uconstrs ist lems) db }
END
-TACTIC EXTEND new_eauto
-| [ "new" "auto" int_or_var_opt(n) auto_using(lems)
+TACTIC EXTEND new_eauto (* todo: name doesn't match syntax *)
+| [ "new" "auto" nat_or_var_opt(n) auto_using(lems)
hintbases(db) ] ->
{ match db with
| None -> Auto.new_full_auto (make_depth n) (eval_uconstrs ist lems)
@@ -146,7 +146,7 @@ TACTIC EXTEND new_eauto
END
TACTIC EXTEND debug_eauto
-| [ "debug" "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+| [ "debug" "eauto" nat_or_var_opt(n) nat_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
{
( match n,p with Some _, Some _ -> (deprecated_bfs "debug eauto") () | _ -> () );
@@ -154,7 +154,7 @@ TACTIC EXTEND debug_eauto
END
TACTIC EXTEND info_eauto
-| [ "info_eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+| [ "info_eauto" nat_or_var_opt(n) nat_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
{
( match n,p with Some _, Some _ -> (deprecated_bfs "info_eauto") () | _ -> () );
@@ -162,13 +162,13 @@ TACTIC EXTEND info_eauto
END
TACTIC EXTEND dfs_eauto
-| [ "dfs" "eauto" int_or_var_opt(p) auto_using(lems)
+| [ "dfs" "eauto" nat_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
{ Eauto.gen_eauto (Eauto.make_dimension p None) (eval_uconstrs ist lems) db }
END
TACTIC EXTEND bfs_eauto
-| [ "bfs" "eauto" int_or_var_opt(p) auto_using(lems)
+| [ "bfs" "eauto" nat_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
{ Eauto.gen_eauto (true, Eauto.make_depth p) (eval_uconstrs ist lems) db }
END
diff --git a/plugins/ltac/g_class.mlg b/plugins/ltac/g_class.mlg
index 8c2e633be5..0f59ac07b4 100644
--- a/plugins/ltac/g_class.mlg
+++ b/plugins/ltac/g_class.mlg
@@ -86,13 +86,13 @@ END
(** Compatibility: typeclasses eauto has 8.5 and 8.6 modes *)
TACTIC EXTEND typeclasses_eauto
- | [ "typeclasses" "eauto" "bfs" int_or_var_opt(d) "with" ne_preident_list(l) ] ->
+ | [ "typeclasses" "eauto" "bfs" nat_or_var_opt(d) "with" ne_preident_list(l) ] ->
{ typeclasses_eauto ~depth:d ~strategy:Bfs l }
- | [ "typeclasses" "eauto" int_or_var_opt(d) "with" ne_preident_list(l) ] ->
+ | [ "typeclasses" "eauto" nat_or_var_opt(d) "with" ne_preident_list(l) ] ->
{ typeclasses_eauto ~depth:d l }
- | [ "typeclasses" "eauto" "bfs" int_or_var_opt(d) ] -> {
+ | [ "typeclasses" "eauto" "bfs" nat_or_var_opt(d) ] -> {
typeclasses_eauto ~depth:d ~strategy:Bfs ~only_classes:true [Class_tactics.typeclasses_db] }
- | [ "typeclasses" "eauto" int_or_var_opt(d) ] -> {
+ | [ "typeclasses" "eauto" nat_or_var_opt(d) ] -> {
typeclasses_eauto ~depth:d ~only_classes:true [Class_tactics.typeclasses_db] }
END
diff --git a/plugins/ltac/g_ltac.mlg b/plugins/ltac/g_ltac.mlg
index c2e95c45f9..b1b96ea9a7 100644
--- a/plugins/ltac/g_ltac.mlg
+++ b/plugins/ltac/g_ltac.mlg
@@ -112,8 +112,8 @@ GRAMMAR EXTEND Gram
| true , None -> TacThens (ta0,first) } ]
| "3" RIGHTA
[ IDENT "try"; ta = ltac_expr -> { TacTry ta }
- | IDENT "do"; n = int_or_var; ta = ltac_expr -> { TacDo (n,ta) }
- | IDENT "timeout"; n = int_or_var; ta = ltac_expr -> { TacTimeout (n,ta) }
+ | IDENT "do"; n = nat_or_var; ta = ltac_expr -> { TacDo (n,ta) }
+ | IDENT "timeout"; n = nat_or_var; ta = ltac_expr -> { TacTimeout (n,ta) }
| IDENT "time"; s = OPT string; ta = ltac_expr -> { TacTime (s,ta) }
| IDENT "repeat"; ta = ltac_expr -> { TacRepeat ta }
| IDENT "progress"; ta = ltac_expr -> { TacProgress ta }
diff --git a/plugins/ltac/g_tactic.mlg b/plugins/ltac/g_tactic.mlg
index 89a14c7c12..43957bbde5 100644
--- a/plugins/ltac/g_tactic.mlg
+++ b/plugins/ltac/g_tactic.mlg
@@ -190,7 +190,7 @@ open Pvernac.Vernac_
GRAMMAR EXTEND Gram
GLOBAL: simple_tactic constr_with_bindings quantified_hypothesis
- bindings red_expr int_or_var open_constr uconstr
+ bindings red_expr int_or_var nat_or_var open_constr uconstr
simple_intropattern in_clause clause_dft_concl hypident destruction_arg;
int_or_var:
diff --git a/plugins/ltac/pltac.ml b/plugins/ltac/pltac.ml
index 94e398fe5d..196a68e67c 100644
--- a/plugins/ltac/pltac.ml
+++ b/plugins/ltac/pltac.ml
@@ -29,6 +29,7 @@ let quantified_hypothesis =
Entry.create "quantified_hypothesis"
let destruction_arg = Entry.create "destruction_arg"
let int_or_var = Entry.create "int_or_var"
+let nat_or_var = Entry.create "nat_or_var"
let simple_intropattern =
Entry.create "simple_intropattern"
let in_clause = Entry.create "in_clause"
@@ -52,6 +53,7 @@ let () =
let open Stdarg in
let open Tacarg in
register_grammar wit_int_or_var (int_or_var);
+ register_grammar wit_nat_or_var (nat_or_var);
register_grammar wit_intro_pattern (simple_intropattern); (* To remove at end of deprecation phase *)
(* register_grammar wit_intropattern (intropattern); *) (* To be added at end of deprecation phase *)
register_grammar wit_simple_intropattern (simple_intropattern);
diff --git a/plugins/ltac/pltac.mli b/plugins/ltac/pltac.mli
index 3a4a081c93..c0bf6b9f76 100644
--- a/plugins/ltac/pltac.mli
+++ b/plugins/ltac/pltac.mli
@@ -27,6 +27,7 @@ val uconstr : constr_expr Entry.t
val quantified_hypothesis : quantified_hypothesis Entry.t
val destruction_arg : constr_expr with_bindings Tactics.destruction_arg Entry.t
val int_or_var : int Locus.or_var Entry.t
+val nat_or_var : int Locus.or_var Entry.t
val simple_tactic : raw_tactic_expr Entry.t
val simple_intropattern : constr_expr intro_pattern_expr CAst.t Entry.t
val in_clause : Names.lident Locus.clause_expr Entry.t
diff --git a/plugins/ltac/tacintern.ml b/plugins/ltac/tacintern.ml
index 871f418915..8bee7afa2c 100644
--- a/plugins/ltac/tacintern.ml
+++ b/plugins/ltac/tacintern.ml
@@ -799,6 +799,7 @@ let intern_ltac ist tac =
let () =
Genintern.register_intern0 wit_int_or_var (lift intern_int_or_var);
+ Genintern.register_intern0 wit_nat_or_var (lift intern_int_or_var);
Genintern.register_intern0 wit_smart_global (lift intern_smart_global);
Genintern.register_intern0 wit_ref (lift intern_global_reference);
Genintern.register_intern0 wit_pre_ident (fun ist c -> (ist,c));
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index db86567114..00ac155f0e 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -2099,6 +2099,7 @@ let interp_pre_ident ist env sigma s =
let () =
register_interp0 wit_int_or_var (fun ist n -> Ftactic.return (interp_int_or_var ist n));
+ register_interp0 wit_nat_or_var (fun ist n -> Ftactic.return (interp_int_or_var ist n));
register_interp0 wit_smart_global (lift interp_reference);
register_interp0 wit_ref (lift interp_reference);
register_interp0 wit_pre_ident (lift interp_pre_ident);
diff --git a/plugins/ltac/tacsubst.ml b/plugins/ltac/tacsubst.ml
index 5f09666778..90546ea939 100644
--- a/plugins/ltac/tacsubst.ml
+++ b/plugins/ltac/tacsubst.ml
@@ -279,6 +279,7 @@ and subst_genarg subst (GenArg (Glbwit wit, x)) =
let () =
Genintern.register_subst0 wit_int_or_var (fun _ v -> v);
+ Genintern.register_subst0 wit_nat_or_var (fun _ v -> v);
Genintern.register_subst0 wit_ref subst_global_reference;
Genintern.register_subst0 wit_smart_global subst_global_reference;
Genintern.register_subst0 wit_pre_ident (fun _ v -> v);
diff --git a/plugins/micromega/g_micromega.mlg b/plugins/micromega/g_micromega.mlg
index 40eea91b31..852a485329 100644
--- a/plugins/micromega/g_micromega.mlg
+++ b/plugins/micromega/g_micromega.mlg
@@ -29,7 +29,7 @@ open Tacarg
DECLARE PLUGIN "micromega_plugin"
TACTIC EXTEND PsatzZ
-| [ "psatz_Z" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Z i
+| [ "psatz_Z" nat_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Z i
(Tacinterp.tactic_of_value ist t))
}
| [ "psatz_Z" tactic(t)] -> { (Coq_micromega.psatz_Z (-1)) (Tacinterp.tactic_of_value ist t) }
@@ -74,12 +74,12 @@ TACTIC EXTEND LRA_R
END
TACTIC EXTEND PsatzR
-| [ "psatz_R" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_R i (Tacinterp.tactic_of_value ist t)) }
+| [ "psatz_R" nat_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_R i (Tacinterp.tactic_of_value ist t)) }
| [ "psatz_R" tactic(t) ] -> { (Coq_micromega.psatz_R (-1) (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND PsatzQ
-| [ "psatz_Q" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Q i (Tacinterp.tactic_of_value ist t)) }
+| [ "psatz_Q" nat_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Q i (Tacinterp.tactic_of_value ist t)) }
| [ "psatz_Q" tactic(t) ] -> { (Coq_micromega.psatz_Q (-1) (Tacinterp.tactic_of_value ist t)) }
END
diff --git a/plugins/ssr/ssrparser.mlg b/plugins/ssr/ssrparser.mlg
index ccdf5fa68e..f06b460ee9 100644
--- a/plugins/ssr/ssrparser.mlg
+++ b/plugins/ssr/ssrparser.mlg
@@ -1792,7 +1792,7 @@ GRAMMAR EXTEND Gram
{ ssrdotac_expr ~loc noindex m tac clauses }
| IDENT "do"; tac = ssrortacarg; clauses = ssrclauses ->
{ ssrdotac_expr ~loc noindex Once tac clauses }
- | IDENT "do"; n = int_or_var; m = ssrmmod;
+ | IDENT "do"; n = nat_or_var; m = ssrmmod;
tac = ssrdotac; clauses = ssrclauses ->
{ ssrdotac_expr ~loc (mk_index ~loc n) m tac clauses }
] ];
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index c352a6ac1f..1c24578a1c 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -1944,7 +1944,7 @@ let w_unify_to_subterm_list env evd flags hdmeta oplist t =
try (* First try finding a subterm w/o conversion on open terms *)
let flags = set_no_delta_open_flags flags in
w_unify_to_subterm env evd ~flags t'
- with e ->
+ with e when CErrors.noncritical e ->
(* If this fails, try with full conversion *)
w_unify_to_subterm env evd ~flags t'
else w_unify_to_subterm env evd ~flags t'
diff --git a/test-suite/bugs/closed/bug_9517.v b/test-suite/bugs/closed/bug_9517.v
index bb43edbe74..93ed94df39 100644
--- a/test-suite/bugs/closed/bug_9517.v
+++ b/test-suite/bugs/closed/bug_9517.v
@@ -2,6 +2,7 @@ Declare Custom Entry expr.
Declare Custom Entry stmt.
Notation "x" := x (in custom stmt, x ident).
Notation "x" := x (in custom expr, x ident).
+Notation "'_'" := _ (in custom expr).
Notation "1" := 1 (in custom expr).
diff --git a/test-suite/output/Notations2.v b/test-suite/output/Notations2.v
index bcb2468792..05712eaac7 100644
--- a/test-suite/output/Notations2.v
+++ b/test-suite/output/Notations2.v
@@ -62,7 +62,7 @@ Check `(∀ n p : A, n=p).
Notation "'let'' f x .. y := t 'in' u":=
(let f := fun x => .. (fun y => t) .. in u)
- (f ident, x closed binder, y closed binder, at level 200,
+ (f name, x closed binder, y closed binder, at level 200,
right associativity).
Check let' f x y (a:=0) z (b:bool) := x+y+z+1 in f 0 1 2.
@@ -93,7 +93,7 @@ End A.
Notation "'mylet' f [ x ; .. ; y ] := t 'in' u":=
(let f := fun x => .. (fun y => t) .. in u)
- (f ident, x closed binder, y closed binder, at level 200,
+ (f name, x closed binder, y closed binder, at level 200,
right associativity).
Check mylet f [x;y;z;(a:bool)] := x+y+z+1 in f 0 1 2.
@@ -104,7 +104,7 @@ Check mylet f [x;y;z;(a:bool)] := x+y+z+1 in f 0 1 2.
(* Old request mentioned again on coq-club 20/1/2012 *)
Notation "# x : T => t" := (fun x : T => t)
- (at level 0, t at level 200, x ident).
+ (at level 0, t at level 200, x name).
Check # x : nat => x.
Check # _ : nat => 2.
@@ -116,7 +116,7 @@ Parameters (A : Set) (x y : A) (Q : A -> A -> Prop) (conj : Q x y).
Check (exist (Q x) y conj).
(* Check bug #4854 *)
-Notation "% i" := (fun i : nat => i) (at level 0, i ident).
+Notation "% i" := (fun i : nat => i) (at level 0, i name).
Check %i.
Check %j.
diff --git a/test-suite/output/Notations3.v b/test-suite/output/Notations3.v
index 04a91c14d9..6c714fc624 100644
--- a/test-suite/output/Notations3.v
+++ b/test-suite/output/Notations3.v
@@ -305,7 +305,7 @@ Module E.
Inductive myex2 {A:Type} (P Q:A -> Prop) : Prop :=
myex_intro2 : forall x:A, P x -> Q x -> myex2 P Q.
Notation "'myexists2' x : A , p & q" := (myex2 (A:=A) (fun x => p) (fun x => q))
- (at level 200, x ident, A at level 200, p at level 200, right associativity,
+ (at level 200, x name, A at level 200, p at level 200, right associativity,
format "'[' 'myexists2' '/ ' x : A , '/ ' '[' p & '/' q ']' ']'")
: type_scope.
Check myex2 (fun x => let '(y,z) := x in y>z) (fun x => let '(y,z) := x in z>y).
diff --git a/test-suite/output/Notations4.v b/test-suite/output/Notations4.v
index ebc1426fc8..ce488fe18d 100644
--- a/test-suite/output/Notations4.v
+++ b/test-suite/output/Notations4.v
@@ -327,6 +327,7 @@ Module P.
Module NotationMixedTermBinderAsIdent.
+ Set Warnings "-deprecated-ident-entry". (* We do want ident! *)
Notation "▢_ n P" := (pseudo_force n (fun n => P))
(at level 0, n ident, P at level 9, format "▢_ n P").
Check exists p, ▢_p (p >= 1).
diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v
index 023705e169..5247c7b56a 100644
--- a/theories/Init/Logic.v
+++ b/theories/Init/Logic.v
@@ -309,9 +309,9 @@ Notation "'exists' x .. y , p" := (ex (fun x => .. (ex (fun y => p)) ..))
: type_scope.
Notation "'exists2' x , p & q" := (ex2 (fun x => p) (fun x => q))
- (at level 200, x ident, p at level 200, right associativity) : type_scope.
+ (at level 200, x name, p at level 200, right associativity) : type_scope.
Notation "'exists2' x : A , p & q" := (ex2 (A:=A) (fun x => p) (fun x => q))
- (at level 200, x ident, A at level 200, p at level 200, right associativity,
+ (at level 200, x name, A at level 200, p at level 200, right associativity,
format "'[' 'exists2' '/ ' x : A , '/ ' '[' p & '/' q ']' ']'")
: type_scope.
@@ -489,18 +489,18 @@ Module EqNotations.
:= (match H as p in (_ = y) return P with
| eq_refl => H'
end)
- (at level 10, H' at level 10, y ident, p ident,
+ (at level 10, H' at level 10, y name, p name,
format "'[' 'rew' 'dependent' [ 'fun' y p => P ] '/ ' H in '/' H' ']'").
Notation "'rew' 'dependent' -> [ 'fun' y p => P ] H 'in' H'"
:= (match H as p in (_ = y) return P with
| eq_refl => H'
end)
- (at level 10, H' at level 10, y ident, p ident, only parsing).
+ (at level 10, H' at level 10, y name, p name, only parsing).
Notation "'rew' 'dependent' <- [ 'fun' y p => P ] H 'in' H'"
:= (match eq_sym H as p in (_ = y) return P with
| eq_refl => H'
end)
- (at level 10, H' at level 10, y ident, p ident,
+ (at level 10, H' at level 10, y name, p name,
format "'[' 'rew' 'dependent' <- [ 'fun' y p => P ] '/ ' H in '/' H' ']'").
Notation "'rew' 'dependent' [ P ] H 'in' H'"
:= (match H as p in (_ = y) return P y p with
diff --git a/theories/Logic/Hurkens.v b/theories/Logic/Hurkens.v
index 84d40035bf..1a2c4ba171 100644
--- a/theories/Logic/Hurkens.v
+++ b/theories/Logic/Hurkens.v
@@ -96,19 +96,19 @@ Module Generic.
(* begin hide *)
(* Notations used in the proof. Hidden in coqdoc. *)
-Reserved Notation "'∀₁' x : A , B" (at level 200, x ident, A at level 200,right associativity).
+Reserved Notation "'∀₁' x : A , B" (at level 200, x name, A at level 200,right associativity).
Reserved Notation "A '⟶₁' B" (at level 99, right associativity, B at level 200).
-Reserved Notation "'λ₁' x , u" (at level 200, x ident, right associativity).
+Reserved Notation "'λ₁' x , u" (at level 200, x name, right associativity).
Reserved Notation "f '·₁' x" (at level 5, left associativity).
-Reserved Notation "'∀₂' A , F" (at level 200, A ident, right associativity).
-Reserved Notation "'λ₂' x , u" (at level 200, x ident, right associativity).
+Reserved Notation "'∀₂' A , F" (at level 200, A name, right associativity).
+Reserved Notation "'λ₂' x , u" (at level 200, x name, right associativity).
Reserved Notation "f '·₁' [ A ]" (at level 5, left associativity).
-Reserved Notation "'∀₀' x : A , B" (at level 200, x ident, A at level 200,right associativity).
+Reserved Notation "'∀₀' x : A , B" (at level 200, x name, A at level 200,right associativity).
Reserved Notation "A '⟶₀' B" (at level 99, right associativity, B at level 200).
-Reserved Notation "'λ₀' x , u" (at level 200, x ident, right associativity).
+Reserved Notation "'λ₀' x , u" (at level 200, x name, right associativity).
Reserved Notation "f '·₀' x" (at level 5, left associativity).
-Reserved Notation "'∀₀¹' A : U , F" (at level 200, A ident, right associativity).
-Reserved Notation "'λ₀¹' x , u" (at level 200, x ident, right associativity).
+Reserved Notation "'∀₀¹' A : U , F" (at level 200, A name, right associativity).
+Reserved Notation "'λ₀¹' x , u" (at level 200, x name, right associativity).
Reserved Notation "f '·₀' [ A ]" (at level 5, left associativity).
(* end hide *)
diff --git a/theories/Program/Utils.v b/theories/Program/Utils.v
index 9c8508bf39..b2bdd8099a 100644
--- a/theories/Program/Utils.v
+++ b/theories/Program/Utils.v
@@ -18,7 +18,7 @@ Set Implicit Arguments.
Notation "{ ( x , y ) : A | P }" :=
(sig (fun anonymous : A => let (x,y) := anonymous in P))
- (x ident, y ident, at level 10) : type_scope.
+ (x name, y name, at level 10) : type_scope.
Declare Scope program_scope.
Delimit Scope program_scope with prg.
diff --git a/theories/ssr/ssrbool.v b/theories/ssr/ssrbool.v
index d1cefeb552..a563dcbf95 100644
--- a/theories/ssr/ssrbool.v
+++ b/theories/ssr/ssrbool.v
@@ -335,19 +335,19 @@ Reserved Notation "[ 'predType' 'of' T ]" (at level 0,
Reserved Notation "[ 'pred' : T | E ]" (at level 0,
format "'[hv' [ 'pred' : T | '/ ' E ] ']'").
-Reserved Notation "[ 'pred' x | E ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x | E ]" (at level 0, x name,
format "'[hv' [ 'pred' x | '/ ' E ] ']'").
-Reserved Notation "[ 'pred' x : T | E ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x : T | E ]" (at level 0, x name,
format "'[hv' [ 'pred' x : T | '/ ' E ] ']'").
-Reserved Notation "[ 'pred' x | E1 & E2 ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x | E1 & E2 ]" (at level 0, x name,
format "'[hv' [ 'pred' x | '/ ' E1 & '/ ' E2 ] ']'").
-Reserved Notation "[ 'pred' x : T | E1 & E2 ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x : T | E1 & E2 ]" (at level 0, x name,
format "'[hv' [ 'pred' x : T | '/ ' E1 & E2 ] ']'").
-Reserved Notation "[ 'pred' x 'in' A ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x 'in' A ]" (at level 0, x name,
format "'[hv' [ 'pred' x 'in' A ] ']'").
-Reserved Notation "[ 'pred' x 'in' A | E ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x 'in' A | E ]" (at level 0, x name,
format "'[hv' [ 'pred' x 'in' A | '/ ' E ] ']'").
-Reserved Notation "[ 'pred' x 'in' A | E1 & E2 ]" (at level 0, x ident,
+Reserved Notation "[ 'pred' x 'in' A | E1 & E2 ]" (at level 0, x name,
format "'[hv' [ 'pred' x 'in' A | '/ ' E1 & '/ ' E2 ] ']'").
Reserved Notation "[ 'qualify' x | P ]" (at level 0, x at level 99,
@@ -363,17 +363,17 @@ Reserved Notation "[ 'qualify' 'an' x | P ]" (at level 0, x at level 99,
Reserved Notation "[ 'qualify' 'an' x : T | P ]" (at level 0, x at level 99,
format "'[hv' [ 'qualify' 'an' x : T | '/ ' P ] ']'").
-Reserved Notation "[ 'rel' x y | E ]" (at level 0, x ident, y ident,
+Reserved Notation "[ 'rel' x y | E ]" (at level 0, x name, y name,
format "'[hv' [ 'rel' x y | '/ ' E ] ']'").
-Reserved Notation "[ 'rel' x y : T | E ]" (at level 0, x ident, y ident,
+Reserved Notation "[ 'rel' x y : T | E ]" (at level 0, x name, y name,
format "'[hv' [ 'rel' x y : T | '/ ' E ] ']'").
-Reserved Notation "[ 'rel' x y 'in' A & B | E ]" (at level 0, x ident, y ident,
+Reserved Notation "[ 'rel' x y 'in' A & B | E ]" (at level 0, x name, y name,
format "'[hv' [ 'rel' x y 'in' A & B | '/ ' E ] ']'").
-Reserved Notation "[ 'rel' x y 'in' A & B ]" (at level 0, x ident, y ident,
+Reserved Notation "[ 'rel' x y 'in' A & B ]" (at level 0, x name, y name,
format "'[hv' [ 'rel' x y 'in' A & B ] ']'").
-Reserved Notation "[ 'rel' x y 'in' A | E ]" (at level 0, x ident, y ident,
+Reserved Notation "[ 'rel' x y 'in' A | E ]" (at level 0, x name, y name,
format "'[hv' [ 'rel' x y 'in' A | '/ ' E ] ']'").
-Reserved Notation "[ 'rel' x y 'in' A ]" (at level 0, x ident, y ident,
+Reserved Notation "[ 'rel' x y 'in' A ]" (at level 0, x name, y name,
format "'[hv' [ 'rel' x y 'in' A ] ']'").
Reserved Notation "[ 'mem' A ]" (at level 0, format "[ 'mem' A ]").
diff --git a/theories/ssr/ssreflect.v b/theories/ssr/ssreflect.v
index d0508bef2e..dc81b5cca7 100644
--- a/theories/ssr/ssreflect.v
+++ b/theories/ssr/ssreflect.v
@@ -110,7 +110,7 @@ Reserved Notation "'if' c 'then' vT 'else' vF" (at level 200,
Reserved Notation "'if' c 'return' R 'then' vT 'else' vF" (at level 200,
c, R, vT, vF at level 200).
Reserved Notation "'if' c 'as' x 'return' R 'then' vT 'else' vF" (at level 200,
- c, R, vT, vF at level 200, x ident).
+ c, R, vT, vF at level 200, x name).
Reserved Notation "x : T" (at level 100, right associativity,
format "'[hv' x '/ ' : T ']'").
diff --git a/theories/ssr/ssrfun.v b/theories/ssr/ssrfun.v
index e1442e1da2..ba66e04e4a 100644
--- a/theories/ssr/ssrfun.v
+++ b/theories/ssr/ssrfun.v
@@ -236,19 +236,19 @@ Reserved Notation "'fun' => E" (at level 200, format "'fun' => E").
Reserved Notation "[ 'fun' : T => E ]" (at level 0,
format "'[hv' [ 'fun' : T => '/ ' E ] ']'").
Reserved Notation "[ 'fun' x => E ]" (at level 0,
- x ident, format "'[hv' [ 'fun' x => '/ ' E ] ']'").
+ x name, format "'[hv' [ 'fun' x => '/ ' E ] ']'").
Reserved Notation "[ 'fun' x : T => E ]" (at level 0,
- x ident, format "'[hv' [ 'fun' x : T => '/ ' E ] ']'").
+ x name, format "'[hv' [ 'fun' x : T => '/ ' E ] ']'").
Reserved Notation "[ 'fun' x y => E ]" (at level 0,
- x ident, y ident, format "'[hv' [ 'fun' x y => '/ ' E ] ']'").
+ x name, y name, format "'[hv' [ 'fun' x y => '/ ' E ] ']'").
Reserved Notation "[ 'fun' x y : T => E ]" (at level 0,
- x ident, y ident, format "'[hv' [ 'fun' x y : T => '/ ' E ] ']'").
+ x name, y name, format "'[hv' [ 'fun' x y : T => '/ ' E ] ']'").
Reserved Notation "[ 'fun' ( x : T ) y => E ]" (at level 0,
- x ident, y ident, format "'[hv' [ 'fun' ( x : T ) y => '/ ' E ] ']'").
+ x name, y name, format "'[hv' [ 'fun' ( x : T ) y => '/ ' E ] ']'").
Reserved Notation "[ 'fun' x ( y : T ) => E ]" (at level 0,
- x ident, y ident, format "'[hv' [ 'fun' x ( y : T ) => '/ ' E ] ']'").
+ x name, y name, format "'[hv' [ 'fun' x ( y : T ) => '/ ' E ] ']'").
Reserved Notation "[ 'fun' ( x : T ) ( y : U ) => E ]" (at level 0,
- x ident, y ident, format "[ 'fun' ( x : T ) ( y : U ) => E ]" ).
+ x name, y name, format "[ 'fun' ( x : T ) ( y : U ) => E ]" ).
Reserved Notation "f =1 g" (at level 70, no associativity).
Reserved Notation "f =1 g :> A" (at level 70, g at next level, A at level 90).
@@ -259,33 +259,33 @@ Reserved Notation "f \; g" (at level 60, right associativity,
format "f \; '/ ' g").
Reserved Notation "{ 'morph' f : x / a >-> r }" (at level 0, f at level 99,
- x ident, format "{ 'morph' f : x / a >-> r }").
+ x name, format "{ 'morph' f : x / a >-> r }").
Reserved Notation "{ 'morph' f : x / a }" (at level 0, f at level 99,
- x ident, format "{ 'morph' f : x / a }").
+ x name, format "{ 'morph' f : x / a }").
Reserved Notation "{ 'morph' f : x y / a >-> r }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'morph' f : x y / a >-> r }").
+ x name, y name, format "{ 'morph' f : x y / a >-> r }").
Reserved Notation "{ 'morph' f : x y / a }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'morph' f : x y / a }").
+ x name, y name, format "{ 'morph' f : x y / a }").
Reserved Notation "{ 'homo' f : x / a >-> r }" (at level 0, f at level 99,
- x ident, format "{ 'homo' f : x / a >-> r }").
+ x name, format "{ 'homo' f : x / a >-> r }").
Reserved Notation "{ 'homo' f : x / a }" (at level 0, f at level 99,
- x ident, format "{ 'homo' f : x / a }").
+ x name, format "{ 'homo' f : x / a }").
Reserved Notation "{ 'homo' f : x y / a >-> r }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'homo' f : x y / a >-> r }").
+ x name, y name, format "{ 'homo' f : x y / a >-> r }").
Reserved Notation "{ 'homo' f : x y / a }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'homo' f : x y / a }").
+ x name, y name, format "{ 'homo' f : x y / a }").
Reserved Notation "{ 'homo' f : x y /~ a }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'homo' f : x y /~ a }").
+ x name, y name, format "{ 'homo' f : x y /~ a }").
Reserved Notation "{ 'mono' f : x / a >-> r }" (at level 0, f at level 99,
- x ident, format "{ 'mono' f : x / a >-> r }").
+ x name, format "{ 'mono' f : x / a >-> r }").
Reserved Notation "{ 'mono' f : x / a }" (at level 0, f at level 99,
- x ident, format "{ 'mono' f : x / a }").
+ x name, format "{ 'mono' f : x / a }").
Reserved Notation "{ 'mono' f : x y / a >-> r }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'mono' f : x y / a >-> r }").
+ x name, y name, format "{ 'mono' f : x y / a >-> r }").
Reserved Notation "{ 'mono' f : x y / a }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'mono' f : x y / a }").
+ x name, y name, format "{ 'mono' f : x y / a }").
Reserved Notation "{ 'mono' f : x y /~ a }" (at level 0, f at level 99,
- x ident, y ident, format "{ 'mono' f : x y /~ a }").
+ x name, y name, format "{ 'mono' f : x y /~ a }").
Reserved Notation "@ 'id' T" (at level 10, T at level 8, format "@ 'id' T").
Reserved Notation "@ 'sval'" (at level 10, format "@ 'sval'").
diff --git a/vernac/egramcoq.ml b/vernac/egramcoq.ml
index ad6ac8d3f3..9fe3e2f7ab 100644
--- a/vernac/egramcoq.ml
+++ b/vernac/egramcoq.ml
@@ -246,6 +246,7 @@ type _ target =
type prod_info = production_level * production_position
type (_, _) entry =
+| TTIdent : ('self, lident) entry
| TTName : ('self, lname) entry
| TTReference : ('self, qualid) entry
| TTBigint : ('self, string) entry
@@ -364,6 +365,7 @@ let symbol_of_entry : type s r. _ -> _ -> (s, r) entry -> (s, r) mayrec_symbol =
| TTPattern p -> MayRecNo (Pcoq.Symbol.nterml Constr.pattern (string_of_int p))
| TTClosedBinderList [] -> MayRecNo (Pcoq.Symbol.list1 (Pcoq.Symbol.nterm Constr.binder))
| TTClosedBinderList tkl -> MayRecNo (Pcoq.Symbol.list1sep (Pcoq.Symbol.nterm Constr.binder) (make_sep_rules tkl) false)
+| TTIdent -> MayRecNo (Pcoq.Symbol.nterm Prim.identref)
| TTName -> MayRecNo (Pcoq.Symbol.nterm Prim.name)
| TTBinder true -> MayRecNo (Pcoq.Symbol.nterm Constr.one_open_binder)
| TTBinder false -> MayRecNo (Pcoq.Symbol.nterm Constr.one_closed_binder)
@@ -372,6 +374,7 @@ let symbol_of_entry : type s r. _ -> _ -> (s, r) entry -> (s, r) mayrec_symbol =
| TTReference -> MayRecNo (Pcoq.Symbol.nterm Constr.global)
let interp_entry forpat e = match e with
+| ETProdIdent -> TTAny TTIdent
| ETProdName -> TTAny TTName
| ETProdReference -> TTAny TTReference
| ETProdBigint -> TTAny TTBigint
@@ -382,6 +385,9 @@ let interp_entry forpat e = match e with
| ETProdBinderList ETBinderOpen -> TTAny TTOpenBinderList
| ETProdBinderList (ETBinderClosed tkl) -> TTAny (TTClosedBinderList tkl)
+let cases_pattern_expr_of_id { CAst.loc; v = id } =
+ CAst.make ?loc @@ CPatAtom (Some (qualid_of_ident ?loc id))
+
let cases_pattern_expr_of_name { CAst.loc; v = na } = CAst.make ?loc @@ match na with
| Anonymous -> CPatAtom None
| Name id -> CPatAtom (Some (qualid_of_ident ?loc id))
@@ -398,6 +404,11 @@ let push_constr subst v = { subst with constrs = v :: subst.constrs }
let push_item : type s r. s target -> (s, r) entry -> s env -> r -> s env = fun forpat e subst v ->
match e with
| TTConstr _ -> push_constr subst v
+| TTIdent ->
+ begin match forpat with
+ | ForConstr -> { subst with binders = (cases_pattern_expr_of_id v, Glob_term.Explicit) :: subst.binders }
+ | ForPattern -> push_constr subst (cases_pattern_expr_of_id v)
+ end
| TTName ->
begin match forpat with
| ForConstr -> { subst with binders = (cases_pattern_expr_of_name v, Glob_term.Explicit) :: subst.binders }
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
index 116cfc6413..5c329f60a9 100644
--- a/vernac/g_vernac.mlg
+++ b/vernac/g_vernac.mlg
@@ -531,6 +531,10 @@ let warn_deprecated_include_type =
CWarnings.create ~name:"deprecated-include-type" ~category:"deprecated"
(fun () -> strbrk "Include Type is deprecated; use Include instead")
+let warn_deprecated_as_ident_kind =
+ CWarnings.create ~name:"deprecated-as-ident-kind" ~category:"deprecated"
+ (fun () -> strbrk "grammar kind \"as ident\" no longer accepts \"_\"; use \"as name\" instead to accept \"_\", too, or silence the warning if you actually intended to accept only identifiers.")
+
}
(* Modules and Sections *)
@@ -1242,7 +1246,13 @@ GRAMMAR EXTEND Gram
] ]
;
explicit_subentry:
- [ [ IDENT "ident" -> { ETIdent } | IDENT "global" -> { ETGlobal }
+ [ [ (* Warning to be turn into an error at the end of deprecation phase (for 8.14) *)
+ IDENT "ident" -> { ETName false }
+ (* To be activated at the end of transitory phase (for 8.15)
+ | IDENT "ident" -> { ETIdent }
+ *)
+ | IDENT "name" -> { ETName true } (* Boolean to remove at the end of transitory phase *)
+ | IDENT "global" -> { ETGlobal }
| IDENT "bigint" -> { ETBigint }
| IDENT "binder" -> { ETBinder true }
| IDENT "constr" -> { ETConstr (InConstrEntry,None,DefaultLevel) }
@@ -1261,8 +1271,9 @@ GRAMMAR EXTEND Gram
| -> { DefaultLevel } ] ]
;
binder_interp:
- [ [ "as"; IDENT "ident" -> { Notation_term.AsIdent }
- | "as"; IDENT "pattern" -> { Notation_term.AsIdentOrPattern }
+ [ [ "as"; IDENT "ident" -> { warn_deprecated_as_ident_kind (); Notation_term.AsIdent }
+ | "as"; IDENT "name" -> { Notation_term.AsName }
+ | "as"; IDENT "pattern" -> { Notation_term.AsNameOrPattern }
| "as"; IDENT "strict"; IDENT "pattern" -> { Notation_term.AsStrictPattern } ] ]
;
END
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index 8759798331..06eb330958 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -340,11 +340,11 @@ let unparsing_metavar i from typs =
let x = List.nth typs (i-1) in
let prec,side = unparsing_precedence_of_entry_type from x in
match x with
- | ETConstr _ | ETGlobal | ETBigint ->
+ | ETConstr _ | ETGlobal | ETBigint | ETIdent ->
UnpMetaVar (prec,side)
- | ETPattern _ | ETIdent ->
+ | ETPattern _ | ETName _ ->
UnpBinderMetaVar (prec,NotQuotedPattern)
- | ETBinder _ ->
+ | ETBinder isopen ->
UnpBinderMetaVar (prec,QuotedPattern)
(* Heuristics for building default printing rules *)
@@ -631,7 +631,8 @@ let include_possible_similar_trailing_pattern typ etyps sl l =
try_aux 0 l
let prod_entry_type = function
- | ETIdent -> ETProdName
+ | ETIdent -> ETProdIdent
+ | ETName _ -> ETProdName
| ETGlobal -> ETProdReference
| ETBigint -> ETProdBigint
| ETBinder o -> ETProdOneBinder o
@@ -891,6 +892,11 @@ let default = {
end
+(* To be turned into a fatal warning in 8.14 *)
+let warn_deprecated_ident_entry =
+ CWarnings.create ~name:"deprecated-ident-entry" ~category:"deprecated"
+ (fun () -> strbrk "grammar entry \"ident\" permitted \"_\" in addition to proper identifiers; this use is deprecated and its meaning will change in the future; use \"name\" instead.")
+
let interp_modifiers modl = let open NotationMods in
let rec interp subtyps acc = function
| [] -> subtyps, acc
@@ -952,6 +958,13 @@ let interp_modifiers modl = let open NotationMods in
let subtyps,mods = interp [] default modl in
(* interpret item levels wrt to main entry *)
let extra_etyps = List.map (fun (id,bko,n) -> (id,ETConstr (mods.custom,bko,n))) subtyps in
+ (* Temporary hack: "ETName false" (i.e. "ident" in deprecation phase) means "ETIdent" for custom entries *)
+ let mods =
+ { mods with etyps = List.map (function
+ | (id,ETName false) ->
+ if mods.custom = InConstrEntry then (warn_deprecated_ident_entry (); (id,ETName true))
+ else (id,ETIdent)
+ | x -> x) mods.etyps } in
{ mods with etyps = extra_etyps@mods.etyps }
let check_infix_modifiers modifiers =
@@ -1000,7 +1013,7 @@ let set_entry_type from n etyps (x,typ) =
| ETConstr (s,bko,n), InternalProd ->
ETConstr (s,bko,(n,InternalProd))
| ETPattern (b,n), _ -> ETPattern (b,n)
- | (ETIdent | ETBigint | ETGlobal | ETBinder _ as x), _ -> x
+ | (ETIdent | ETName _ | ETBigint | ETGlobal | ETBinder _ as x), _ -> x
with Not_found ->
ETConstr (from,None,(make_lev n from,typ))
in (x,typ)
@@ -1023,7 +1036,7 @@ let join_auxiliary_recursive_types recvars etyps =
let internalization_type_of_entry_type = function
| ETBinder _ -> NtnInternTypeOnlyBinder
| ETConstr _ | ETBigint | ETGlobal
- | ETIdent | ETPattern _ -> NtnInternTypeAny
+ | ETIdent | ETName _ | ETPattern _ -> NtnInternTypeAny
let set_internalization_type typs =
List.map (fun (_, e) -> internalization_type_of_entry_type e) typs
@@ -1043,6 +1056,7 @@ let make_interpretation_type isrec isonlybinding default_if_binding = function
| ETConstr (_,None,_) -> NtnTypeConstr
(* Others *)
| ETIdent -> NtnTypeBinder NtnParsedAsIdent
+ | ETName _ -> NtnTypeBinder NtnParsedAsName
| ETPattern (ppstrict,_) -> NtnTypeBinder (NtnParsedAsPattern ppstrict) (* Parsed as ident/pattern, primarily interpreted as binder; maybe strict at printing *)
| ETBigint | ETGlobal -> NtnTypeConstr
| ETBinder _ ->
@@ -1063,7 +1077,7 @@ let subentry_of_constr_prod_entry from_level = function
| _ -> InConstrEntrySomeLevel
let make_interpretation_vars
- (* For binders, default is to parse only as an ident *) ?(default_if_binding=AsIdent)
+ (* For binders, default is to parse only as an ident *) ?(default_if_binding=AsName)
recvars level allvars typs =
let eq_subscope (sc1, l1) (sc2, l2) =
Option.equal String.equal sc1 sc2 &&
@@ -1159,7 +1173,7 @@ let find_precedence custom lev etyps symbols onlyprint =
user_err Pp.(str "The level of the leftmost non-terminal cannot be changed.") in
(try match List.assoc x etyps, custom with
| ETConstr (s,_,(NumLevel _ | NextLevel)), s' when s = s' -> test ()
- | (ETIdent | ETBigint | ETGlobal), _ ->
+ | (ETIdent | ETName _ | ETBigint | ETGlobal), _ ->
begin match lev with
| None ->
([fun () -> Flags.if_verbose (Feedback.msg_info ?loc:None) (strbrk "Setting notation at level 0.")],0)
@@ -1798,7 +1812,7 @@ let add_syntactic_definition ~local deprecation env ident (vars,c) { onlyparsing
interp_notation_constr env nenv c
in
let in_pat id = (id,ETConstr (Constrexpr.InConstrEntry,None,(NextLevel,InternalProd))) in
- let interp = make_interpretation_vars ~default_if_binding:AsIdentOrPattern [] 0 acvars (List.map in_pat vars) in
+ let interp = make_interpretation_vars ~default_if_binding:AsNameOrPattern [] 0 acvars (List.map in_pat vars) in
let vars = List.map (fun x -> (x, Id.Map.find x interp)) vars in
let also_in_cases_pattern = has_no_binders_type vars in
let onlyparsing = onlyparsing || fst (printability None [] false reversibility pat) in
diff --git a/vernac/ppvernac.ml b/vernac/ppvernac.ml
index 4cee4f7a47..01873918aa 100644
--- a/vernac/ppvernac.ml
+++ b/vernac/ppvernac.ml
@@ -187,13 +187,16 @@ let level_of_pattern_level = function None -> DefaultLevel | Some n -> NumLevel
let pr_constr_as_binder_kind = let open Notation_term in function
| AsIdent -> spc () ++ keyword "as ident"
- | AsIdentOrPattern -> spc () ++ keyword "as pattern"
+ | AsName -> spc () ++ keyword "as name"
+ | AsNameOrPattern -> spc () ++ keyword "as pattern"
| AsStrictPattern -> spc () ++ keyword "as strict pattern"
let pr_strict b = if b then str "strict " else mt ()
let pr_set_entry_type pr = function
| ETIdent -> str"ident"
+ | ETName false -> str"ident" (* temporary *)
+ | ETName true -> str"name"
| ETGlobal -> str"global"
| ETPattern (b,n) -> pr_strict b ++ str"pattern" ++ pr_at_level (level_of_pattern_level n)
| ETConstr (s,bko,lev) -> pr_notation_entry s ++ pr lev ++ pr_opt pr_constr_as_binder_kind bko
@@ -268,9 +271,9 @@ let pr_reference_or_constr pr_c = function
| HintsConstr c -> pr_c c
let pr_hint_mode = let open Hints in function
- | ModeInput -> str"+"
- | ModeNoHeadEvar -> str"!"
- | ModeOutput -> str"-"
+ | ModeInput -> str"+"
+ | ModeNoHeadEvar -> str"!"
+ | ModeOutput -> str"-"
let pr_hint_info pr_pat { Typeclasses.hint_priority = pri; hint_pattern = pat } =
pr_opt (fun x -> str"|" ++ int x) pri ++
diff --git a/vernac/vernacinterp.ml b/vernac/vernacinterp.ml
index 57d9e0ac3c..e5971e1aaa 100644
--- a/vernac/vernacinterp.ml
+++ b/vernac/vernacinterp.ml
@@ -82,7 +82,9 @@ let vernac_timeout ?timeout (f : 'a -> 'b) (x : 'a) : 'b =
match !default_timeout, timeout with
| _, Some n
| Some n, None ->
- Control.timeout n f x CErrors.Timeout
+ (match Control.timeout n f x with
+ | None -> Exninfo.iraise (Exninfo.capture CErrors.Timeout)
+ | Some x -> x)
| None, None ->
f x