aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml2
-rw-r--r--.gitlab-ci.yml4
-rw-r--r--.travis.yml5
-rw-r--r--CHANGES1
-rw-r--r--CONTRIBUTING.md20
-rw-r--r--README.md6
-rw-r--r--checker/check.mllib1
-rw-r--r--checker/cic.mli5
-rw-r--r--checker/declarations.ml9
-rw-r--r--checker/environ.ml3
-rw-r--r--checker/environ.mli1
-rw-r--r--checker/subtyping.ml4
-rw-r--r--checker/values.ml11
-rw-r--r--clib/cArray.ml4
-rw-r--r--clib/canary.ml28
-rw-r--r--clib/canary.mli27
-rw-r--r--clib/clib.mllib1
-rw-r--r--clib/hashcons.ml40
-rw-r--r--clib/hashcons.mli3
-rw-r--r--dev/ci/README.md36
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile4
-rw-r--r--dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh4
-rw-r--r--dev/ci/user-overlays/README.md4
-rw-r--r--dev/doc/MERGING.md20
-rwxr-xr-xdev/tools/merge-pr.sh18
-rw-r--r--doc/sphinx/addendum/generalized-rewriting.rst2
-rwxr-xr-xdoc/sphinx/conf.py6
-rw-r--r--doc/sphinx/language/gallina-extensions.rst83
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst3
-rw-r--r--interp/constrintern.ml2
-rw-r--r--interp/declare.ml37
-rw-r--r--kernel/constr.ml16
-rw-r--r--kernel/constr.mli30
-rw-r--r--kernel/cooking.ml2
-rw-r--r--kernel/cooking.mli1
-rw-r--r--kernel/declarations.ml3
-rw-r--r--kernel/declareops.ml3
-rw-r--r--kernel/entries.ml5
-rw-r--r--kernel/environ.ml2
-rw-r--r--kernel/indtypes.ml57
-rw-r--r--kernel/indtypes.mli2
-rw-r--r--kernel/mod_subst.ml11
-rw-r--r--kernel/mod_subst.mli2
-rw-r--r--kernel/modops.ml3
-rw-r--r--kernel/names.ml11
-rw-r--r--kernel/term_typing.ml31
-rw-r--r--lib/spawn.ml59
-rw-r--r--lib/spawn.mli4
-rw-r--r--library/global.ml3
-rw-r--r--library/global.mli2
-rw-r--r--library/heads.ml2
-rw-r--r--plugins/extraction/extraction.ml16
-rw-r--r--plugins/ltac/tacinterp.ml3
-rw-r--r--pretyping/cases.ml1
-rw-r--r--pretyping/detyping.ml5
-rw-r--r--pretyping/evarsolve.ml2
-rw-r--r--pretyping/glob_ops.ml14
-rw-r--r--pretyping/inductiveops.ml104
-rw-r--r--pretyping/inductiveops.mli12
-rw-r--r--pretyping/typing.ml7
-rw-r--r--proofs/clenvtac.ml2
-rw-r--r--stm/spawned.ml4
-rw-r--r--tactics/tactics.ml30
-rw-r--r--test-suite/README.md22
-rw-r--r--test-suite/bugs/closed/2800.v13
-rw-r--r--test-suite/bugs/closed/5500.v35
-rw-r--r--test-suite/bugs/closed/5547.v16
-rw-r--r--test-suite/bugs/closed/7615.v19
-rw-r--r--test-suite/bugs/closed/7779.v15
-rw-r--r--test-suite/bugs/closed/7780.v16
-rw-r--r--test-suite/bugs/closed/7811.v114
-rw-r--r--test-suite/output/PrintAssumptions.out2
-rw-r--r--test-suite/output/PrintAssumptions.v27
-rw-r--r--test-suite/output/Unicode.out41
-rw-r--r--test-suite/output/Unicode.v28
-rw-r--r--test-suite/success/Hints.v2
-rw-r--r--theories/Unicode/Utf8_core.v6
-rw-r--r--tools/CoqMakefile.in2
-rw-r--r--tools/coq_makefile.ml2
-rw-r--r--vernac/assumptions.ml13
80 files changed, 778 insertions, 438 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index cff461295..03aeed2eb 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -11,7 +11,7 @@ defaults:
- image: $CI_REGISTRY_IMAGE:$CACHEKEY
environment: &envvars
- CACHEKEY: "bionic_coq-V2018-06-04-V2"
+ CACHEKEY: "bionic_coq-V2018-06-13-V1"
CI_REGISTRY_IMAGE: registry.gitlab.com/coq/coq
version: 2
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0bc67dfcc..971a281ea 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,7 +9,7 @@ stages:
variables:
# Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
# for reference]
- CACHEKEY: "bionic_coq-V2018-06-04-V2"
+ CACHEKEY: "bionic_coq-V2018-06-13-V1"
IMAGE: "$CI_REGISTRY_IMAGE:$CACHEKEY"
# By default, jobs run in the base switch; override to select another switch
OPAM_SWITCH: "base"
@@ -31,6 +31,8 @@ docker-boot:
except:
variables:
- $SKIP_DOCKER == "true"
+ tags:
+ - docker
before_script:
- cat /proc/{cpu,mem}info || true
diff --git a/.travis.yml b/.travis.yml
index 86a2aea66..627334690 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -82,11 +82,6 @@ matrix:
- TEST_TARGET="ci-coquelicot"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-elpi" EXTRA_OPAM="elpi"
- # ppx_tools_versioned requires a specific version findlib
- - FINDLIB_VER=""
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-equations"
- if: NOT (type = pull_request)
env:
diff --git a/CHANGES b/CHANGES
index 787c9ba12..ce8e313b9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -61,6 +61,7 @@ Changes from 8.8.0 to 8.8.1
Kernel
- Fix a critical bug with cofixpoints and vm_compute/native_compute (#7333).
+- Fix a critical bug with inlining of polymorphic constants (#7615).
Notations
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7b2229cb7..2dffd2019 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -22,21 +22,30 @@ If you want to minimize your bug (or help minimize someone else's) for more extr
If you want to contribute a bug fix or feature yourself, pull requests on the [GitHub repository](https://github.com/coq/coq) are the way to contribute directly to the Coq implementation. We recommend you create a fork of the repository on GitHub and push your changes to a new "topic branch" in that fork. From there you can follow the [GitHub pull request documentation](https://help.github.com/articles/about-pull-requests/) to get your changes reviewed and pulled into the Coq source repository.
-Documentation for getting started with the Coq sources is located in various files in [`dev/doc`](/dev/doc) (for example, [debugging.md](/dev/doc/debugging.md)). For further help with the Coq sources, feel free to join the [Coq Gitter chat](https://gitter.im/coq/coq) and ask questions.
+Documentation for getting started with the Coq sources is located in various
+files in [`dev/doc`](dev/doc) (for example, [debugging.md](dev/doc/debugging.md)).
+For further help with the Coq sources, feel free to join
+the [Coq Gitter chat](https://gitter.im/coq/coq) and ask questions.
Please make pull requests against the `master` branch.
-If it's your first significant contribution to Coq (significant means: more than fixing a typo), your pull request should include a commit adding your name to the [`CREDITS`](/CREDITS) file (possibly with the name of your institution / employer if relevant to your contribution, an ORCID if you have one —you may log into https://orcid.org/ using your institutional account to get one—, and the year of your contribution).
+If it's your first significant contribution to Coq (significant means: more
+than fixing a typo), your pull request should include a commit adding your name
+to the [`CREDITS`](CREDITS) file (possibly with the name of your
+institution / employer if relevant to your contribution, an ORCID if you have
+one —you may log into https://orcid.org/ using your institutional account to
+get one—, and the year of your contribution).
It's helpful to run the Coq test suite with `make test-suite` before submitting
your change. Our CI runs this test suite and lots of other tests, including
building external Coq developments, on every pull request, but these results
take significantly longer to come back (on the order of a few hours). Running
the test suite locally will take somewhere around 10-15 minutes. Refer to
-[`dev/ci/README.md`](/dev/ci/README.md#information-for-developers) for more
+[`dev/ci/README.md`](dev/ci/README.md#information-for-developers) for more
information on CI tests, including how to run them on your private branches.
-If your pull request fixes a bug, please consider adding a regression test as well. See [`test-suite/README.md`](/test-suite/README.md) for how to do so.
+If your pull request fixes a bug, please consider adding a regression test as
+well. See [`test-suite/README.md`](test-suite/README.md) for how to do so.
Don't be alarmed if the pull request process takes some time. It can take a few days to get feedback, approval on the final changes, and then a merge. Coq doesn't release new versions very frequently so it can take a few months for your change to land in a released version. That said, you can start using the latest Coq `master` branch to take advantage of all the new features, improvements, and fixes.
@@ -48,7 +57,8 @@ Here are a few tags Coq developers may add to your PR and what they mean. In gen
- [needs: fixing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+fixing%22) indicates the PR needs a fix, as discussed in the comments.
- [needs: benchmarking](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+benchmarking%22) and [needs: testing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+testing%22) indicate the PR needs testing beyond what the test suite can handle. For example, performance benchmarking is currently performed with a different infrastructure. Unless some followup is specifically requested you aren't expected to do this additional testing.
-To learn more about the merging process, you can read the [merging documentation for Coq maintainers](/dev/doc/MERGING.md).
+To learn more about the merging process, you can read the
+[merging documentation for Coq maintainers](dev/doc/MERGING.md).
## Documentation
diff --git a/README.md b/README.md
index 4956da36d..0903abdd4 100644
--- a/README.md
+++ b/README.md
@@ -14,11 +14,11 @@ environment for semi-interactive development of machine-checked proofs.
## Installation
Download the pre-built packages of the [latest release](https://github.com/coq/coq/releases/latest) for Windows and MacOS;
read the [help page](https://coq.inria.fr/opam/www/using.html) on how to install Coq with OPAM;
-or refer to the [`INSTALL` file](/INSTALL) for the procedure to install from source.
+or refer to the [`INSTALL` file](INSTALL) for the procedure to install from source.
## Documentation
-The sources of the documentation can be found in directory [`doc`](/doc). The
+The sources of the documentation can be found in directory [`doc`](doc). The
documentation of the last released version is available on the Coq
web site at [coq.inria.fr/documentation](http://coq.inria.fr/documentation).
See also [Cocorico](https://github.com/coq/coq/wiki) (the Coq wiki),
@@ -26,7 +26,7 @@ and the [Coq FAQ](https://github.com/coq/coq/wiki/The-Coq-FAQ),
for additional user-contributed documentation.
## Changes
-There is a file named [`CHANGES`](/CHANGES) that explains the differences and the
+There is a file named [`CHANGES`](CHANGES) that explains the differences and the
incompatibilities since last versions. If you upgrade Coq, please read
it carefully.
diff --git a/checker/check.mllib b/checker/check.mllib
index f79ba66e3..139fa765b 100644
--- a/checker/check.mllib
+++ b/checker/check.mllib
@@ -3,7 +3,6 @@ Coq_config
Analyze
Hook
Terminal
-Canary
Hashset
Hashcons
CSet
diff --git a/checker/cic.mli b/checker/cic.mli
index 27e2a479f..3304b032e 100644
--- a/checker/cic.mli
+++ b/checker/cic.mli
@@ -128,7 +128,7 @@ type section_context = unit
(** {6 Substitutions} *)
type delta_hint =
- | Inline of int * constr option
+ | Inline of int * (Univ.AUContext.t * constr) option
| Equiv of KerName.t
type delta_resolver = ModPath.t MPmap.t * delta_hint KNmap.t
@@ -211,8 +211,6 @@ type projection_body = {
proj_npars : int;
proj_arg : int;
proj_type : constr; (* Type under params *)
- proj_eta : constr * constr; (* Eta-expanded term and type *)
- proj_body : constr; (* For compatibility, the match version *)
}
type constant_def =
@@ -241,7 +239,6 @@ type constant_body = {
const_type : constr;
const_body_code : to_patch_substituted;
const_universes : constant_universes;
- const_proj : bool;
const_inline_code : bool;
const_typing_flags : typing_flags;
}
diff --git a/checker/declarations.ml b/checker/declarations.ml
index e1d2cf6d1..a744a0227 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -196,7 +196,12 @@ let subst_con0 sub con u =
let dup con = con, Const (con, u) in
let side,con',resolve = gen_subst_mp rebuild_con sub mp1 mp2 in
match constant_of_delta_with_inline resolve con' with
- | Some t -> con', t
+ | Some (ctx, t) ->
+ (** FIXME: we never typecheck the inlined term, so that it could well
+ be garbage. What environment do we type it in though? The substitution
+ code should be moot in the checker but it **is** used nonetheless. *)
+ let () = assert (Univ.AUContext.size ctx == Univ.Instance.length u) in
+ con', subst_instance_constr u t
| None ->
let con'' = match side with
| User -> constant_of_delta resolve con'
@@ -340,7 +345,7 @@ let gen_subst_delta_resolver dom subst resolver =
let kkey' = if dom then subst_kn subst kkey else kkey in
let hint' = match hint with
| Equiv kequ -> Equiv (subst_kn_delta subst kequ)
- | Inline (lev,Some t) -> Inline (lev,Some (subst_mps subst t))
+ | Inline (lev,Some (ctx, t)) -> Inline (lev,Some (ctx, subst_mps subst t))
| Inline (_,None) -> hint
in
Deltamap.add_kn kkey' hint' rslv
diff --git a/checker/environ.ml b/checker/environ.ml
index 809150cea..3d5fac806 100644
--- a/checker/environ.ml
+++ b/checker/environ.ml
@@ -166,9 +166,6 @@ let evaluable_constant cst env =
try let _ = constant_value env (cst, Univ.Instance.empty) in true
with Not_found | NotEvaluableConst _ -> false
-let is_projection cst env =
- (lookup_constant cst env).const_proj
-
let lookup_projection p env =
Cmap_env.find (Projection.constant p) env.env_globals.env_projections
diff --git a/checker/environ.mli b/checker/environ.mli
index 4a7597249..acb29d7d2 100644
--- a/checker/environ.mli
+++ b/checker/environ.mli
@@ -58,7 +58,6 @@ exception NotEvaluableConst of const_evaluation_result
val constant_value : env -> Constant.t puniverses -> constr
val evaluable_constant : Constant.t -> env -> bool
-val is_projection : Constant.t -> env -> bool
val lookup_projection : Projection.t -> env -> projection_body
(* Inductives *)
diff --git a/checker/subtyping.ml b/checker/subtyping.ml
index 5c672d04a..f4ae02084 100644
--- a/checker/subtyping.ml
+++ b/checker/subtyping.ml
@@ -130,9 +130,7 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
check (==) (fun x -> x.proj_npars);
check (==) (fun x -> x.proj_arg);
check (eq_constr) (fun x -> x.proj_type);
- check (eq_constr) (fun x -> fst x.proj_eta);
- check (eq_constr) (fun x -> snd x.proj_eta);
- check (eq_constr) (fun x -> x.proj_body); true
+ true
in
let check_inductive_type t1 t2 =
diff --git a/checker/values.ml b/checker/values.ml
index f7ab95fe2..31e65729b 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -15,7 +15,7 @@
To ensure this file is up-to-date, 'make' now compares the md5 of cic.mli
with a copy we maintain here:
-MD5 92de14d7bf9134532e8a0cff5618bd50 checker/cic.mli
+MD5 07651f61f86d91b22ff7056c6a8d86bc checker/cic.mli
*)
@@ -91,7 +91,7 @@ let rec v_mp = Sum("module_path",0,
[|[|v_dp|];
[|v_uid|];
[|v_mp;v_id|]|])
-let v_kn = v_tuple "kernel_name" [|Any;v_mp;v_dp;v_id;Int|]
+let v_kn = v_tuple "kernel_name" [|v_mp;v_dp;v_id;Int|]
let v_cst = v_sum "cst|mind" 0 [|[|v_kn|];[|v_kn;v_kn|]|]
let v_ind = v_tuple "inductive" [|v_cst;Int|]
let v_cons = v_tuple "constructor" [|v_ind;Int|]
@@ -173,7 +173,7 @@ let v_section_ctxt = v_enum "emptylist" 1
(** kernel/mod_subst *)
let v_delta_hint =
- v_sum "delta_hint" 0 [|[|Int; Opt v_constr|];[|v_kn|]|]
+ v_sum "delta_hint" 0 [|[|Int; Opt (v_pair v_abs_context v_constr)|];[|v_kn|]|]
let v_resolver =
v_tuple "delta_resolver"
@@ -225,9 +225,7 @@ let v_cst_def =
let v_projbody =
v_tuple "projection_body"
- [|v_cst;Int;Int;v_constr;
- v_tuple "proj_eta" [|v_constr;v_constr|];
- v_constr|]
+ [|v_cst;Int;Int;v_constr|]
let v_typing_flags =
v_tuple "typing_flags" [|v_bool; v_bool; v_oracle|]
@@ -241,7 +239,6 @@ let v_cb = v_tuple "constant_body"
Any;
v_const_univs;
v_bool;
- v_bool;
v_typing_flags|]
let v_recarg = v_sum "recarg" 1 (* Norec *)
diff --git a/clib/cArray.ml b/clib/cArray.ml
index b26dae729..fc87a74cf 100644
--- a/clib/cArray.ml
+++ b/clib/cArray.ml
@@ -280,7 +280,7 @@ let fold_left2_i f a v1 v2 =
let rec fold a n =
if n >= lv1 then a else fold (f n a (uget v1 n) (uget v2 n)) (succ n)
in
- if Array.length v2 <> lv1 then invalid_arg "Array.fold_left2";
+ if Array.length v2 <> lv1 then invalid_arg "Array.fold_left2_i";
fold a 0
let fold_left3 f a v1 v2 v3 =
@@ -290,7 +290,7 @@ let fold_left3 f a v1 v2 v3 =
else fold (f a (uget v1 n) (uget v2 n) (uget v3 n)) (succ n)
in
if Array.length v2 <> lv1 || Array.length v3 <> lv1 then
- invalid_arg "Array.fold_left2";
+ invalid_arg "Array.fold_left3";
fold a 0
let fold_left4 f a v1 v2 v3 v4 =
diff --git a/clib/canary.ml b/clib/canary.ml
deleted file mode 100644
index b8b79ed7f..000000000
--- a/clib/canary.ml
+++ /dev/null
@@ -1,28 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-type t = Obj.t
-
-let obj = Obj.new_block Obj.closure_tag 0
- (** This is an empty closure block. In the current implementation, it is
- sufficient to allow marshalling but forbid equality. Sadly still allows
- hash. *)
- (** FIXME : use custom blocks somehow. *)
-
-module type Obj = sig type t end
-
-module Make(M : Obj) =
-struct
- type canary = t
- type t = (canary * M.t)
-
- let prj (_, x) = x
- let inj x = (obj, x)
-end
diff --git a/clib/canary.mli b/clib/canary.mli
deleted file mode 100644
index d993eabcf..000000000
--- a/clib/canary.mli
+++ /dev/null
@@ -1,27 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-type t
-(** Type of canaries. Canaries are used to ensure that an object does not use
- generic operations. *)
-
-val obj : t
-(** Canary. In the current implementation, this object is marshallable,
- forbids generic comparison but still allows generic hashes. *)
-
-module type Obj = sig type t end
-
-module Make(M : Obj) :
-sig
- type t
- val prj : t -> M.t
- val inj : M.t -> t
-end
-(** Adds a canary to any type. *)
diff --git a/clib/clib.mllib b/clib/clib.mllib
index c9b4d72fc..afece4074 100644
--- a/clib/clib.mllib
+++ b/clib/clib.mllib
@@ -1,4 +1,3 @@
-Canary
CObj
CEphemeron
diff --git a/clib/hashcons.ml b/clib/hashcons.ml
index ec73c6d93..39969ebf7 100644
--- a/clib/hashcons.ml
+++ b/clib/hashcons.ml
@@ -10,8 +10,6 @@
(* Hash consing of datastructures *)
-(* The generic hash-consing functions (does not use Obj) *)
-
(* [t] is the type of object to hash-cons
* [u] is the type of hash-cons functions for the sub-structures
* of objects of type t (u usually has the form (t1->t1)*(t2->t2)*...).
@@ -148,41 +146,3 @@ module Hstring = Make(
let len = String.length s in
hash len s 0 0
end)
-
-(* Obj.t *)
-exception NotEq
-
-(* From CAMLLIB/caml/mlvalues.h *)
-let no_scan_tag = 251
-let tuple_p obj = Obj.is_block obj && (Obj.tag obj < no_scan_tag)
-
-let comp_obj o1 o2 =
- if tuple_p o1 && tuple_p o2 then
- let n1 = Obj.size o1 and n2 = Obj.size o2 in
- if n1=n2 then
- try
- for i = 0 to pred n1 do
- if not (Obj.field o1 i == Obj.field o2 i) then raise NotEq
- done; true
- with NotEq -> false
- else false
- else o1=o2
-
-let hash_obj hrec o =
- begin
- if tuple_p o then
- let n = Obj.size o in
- for i = 0 to pred n do
- Obj.set_field o i (hrec (Obj.field o i))
- done
- end;
- o
-
-module Hobj = Make(
- struct
- type t = Obj.t
- type u = (Obj.t -> Obj.t) * unit
- let hashcons (hrec,_) = hash_obj hrec
- let eq = comp_obj
- let hash = Hashtbl.hash
- end)
diff --git a/clib/hashcons.mli b/clib/hashcons.mli
index 3e396ff23..223dd2a4d 100644
--- a/clib/hashcons.mli
+++ b/clib/hashcons.mli
@@ -87,6 +87,3 @@ module Hstring : (S with type t = string and type u = unit)
module Hlist (D:HashedType) :
(S with type t = D.t list and type u = (D.t list -> D.t list)*(D.t->D.t))
(** Hashconsing of lists. *)
-
-module Hobj : (S with type t = Obj.t and type u = (Obj.t -> Obj.t) * unit)
-(** Hashconsing of OCaml values. *)
diff --git a/dev/ci/README.md b/dev/ci/README.md
index dc586c61f..08364c897 100644
--- a/dev/ci/README.md
+++ b/dev/ci/README.md
@@ -47,16 +47,13 @@ CI.
### Add your development by submitting a pull request
-Add a new `ci-mydev.sh` script to [`dev/ci`](/dev/ci) (have a look at
-[`ci-coq-dpdgraph.sh`](/dev/ci/ci-coq-dpdgraph.sh) or
-[`ci-fiat-parsers.sh`](/dev/ci/ci-fiat-parsers.sh) for simple examples);
-set the corresponding variables in
-[`ci-basic-overlay.sh`](/dev/ci/ci-basic-overlay.sh); add the corresponding
-target to [`Makefile.ci`](/Makefile.ci); add new jobs to
-[`.gitlab-ci.yml`](/.gitlab-ci.yml),
-[`.circleci/config.yml`](/.circleci/config.yml) and
-[`.travis.yml`](/.travis.yml) so that this new target is run. **Do not
-hesitate to submit an incomplete pull request if you need help to finish it.**
+Add a new `ci-mydev.sh` script to [`dev/ci`](.); set the corresponding
+variables in [`ci-basic-overlay.sh`](ci-basic-overlay.sh); add the
+corresponding target to [`Makefile.ci`](../../Makefile.ci) and a new job to
+[`.gitlab-ci.yml`](../../.gitlab-ci.yml) so that this new target is run.
+Have a look at [#7656](https://github.com/coq/coq/pull/7656/files) for an
+example. **Do not hesitate to submit an incomplete pull request if you need
+help to finish it.**
You may also be interested in having your development tested in our
performance benchmark. Currently this is done by providing an OPAM package
@@ -83,7 +80,7 @@ We are currently running tests on the following platforms:
- Travis CI is used to test the compilation of Coq and run the test-suite on
macOS. It also runs a linter that checks whitespace discipline. A
- [pre-commit hook](/dev/tools/pre-commit) is automatically installed by
+ [pre-commit hook](../tools/pre-commit) is automatically installed by
`./configure`. It should allow complying with this discipline without pain.
- AppVeyor is used to test the compilation of Coq and run the test-suite on
@@ -92,7 +89,7 @@ We are currently running tests on the following platforms:
GitLab CI and Travis CI and AppVeyor support putting `[ci skip]` in a commit
message to bypass CI. Do not use this unless your commit only changes files
that are not compiled (e.g. Markdown files like this one, or files under
-[`.github/`](/.github/)).
+[`.github/`](../../.github/)).
You can anticipate the results of most of these tests prior to submitting your
PR by running GitLab CI on your private branches. To do so follow these steps:
@@ -112,7 +109,7 @@ there are some.
You can also run one CI target locally (using `make ci-somedev`).
-See also [`test-suite/README.md`](/test-suite/README.md) for information about adding new tests to the test-suite.
+See also [`test-suite/README.md`](../../test-suite/README.md) for information about adding new tests to the test-suite.
### Breaking changes
@@ -123,7 +120,7 @@ patch (or ask someone to prepare a patch) to fix the project:
the project to your changes.
2. Test your pull request with your adapted version of the external project by
adding an overlay file to your pull request (cf.
- [`dev/ci/user-overlays/README.md`](/dev/ci/user-overlays/README.md)).
+ [`dev/ci/user-overlays/README.md`](user-overlays/README.md)).
3. Fixes to external libraries (pure Coq projects) *must* be backward
compatible (i.e. they should also work with the development version of Coq,
and the latest stable version). This will allow you to open a PR on the
@@ -137,7 +134,7 @@ patch (or ask someone to prepare a patch) to fix the project:
developer who merges the PR on Coq. There are plans to improve this, cf.
[#6724](https://github.com/coq/coq/issues/6724).
-Moreover your PR must absolutely update the [`CHANGES`](/CHANGES) file.
+Moreover your PR must absolutely update the [`CHANGES`](../../CHANGES) file.
Advanced GitLab CI information
------------------------------
@@ -173,8 +170,9 @@ automatically built and uploaded to your GitLab registry, and is
loaded by subsequent jobs.
**IMPORTANT**: When updating Coq's CI docker image, you must modify
-the `CACHEKEY` variable in `.gitlab-ci.yml`, `.circleci/config.yml`,
-and `Dockerfile`.
+the `CACHEKEY` variable in [`.gitlab-ci.yml`](../../.gitlab-ci.yml),
+[`.circleci/config.yml`](../../.circleci/config.yml),
+and [`Dockerfile`](docker/bionic_coq/Dockerfile)
The Docker building job reuses the uploaded image if it is available,
but if you wish to save more time you can skip the job by setting
@@ -182,4 +180,6 @@ but if you wish to save more time you can skip the job by setting
This means you will need to change its value when the Docker image
needs to be updated. You can do so for a single pipeline by starting
-it through the web interface.
+it through the web interface..
+
+See also [`docker/README.md`](docker/README.md).
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
index 1a83593f5..52f851917 100644
--- a/dev/ci/docker/bionic_coq/Dockerfile
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -1,4 +1,4 @@
-# CACHEKEY: "bionic_coq-V2018-06-04-V2"
+# CACHEKEY: "bionic_coq-V2018-06-13-V1"
# ^^ Update when modifying this file.
FROM ubuntu:bionic
@@ -27,7 +27,7 @@ RUN opam init -a -y -j $NJOBS --compiler="$COMPILER" default https://opam.ocaml.
# `num` does not have a version number as the right version to install varies
# with the compiler version.
ENV BASE_OPAM="num ocamlfind.1.8.0 jbuilder.1.0+beta20 ounit.2.0.8" \
- CI_OPAM="menhir.20180530 elpi.1.0.3 ocamlgraph.1.8.8"
+ CI_OPAM="menhir.20180530 elpi.1.0.4 ocamlgraph.1.8.8"
# BASE switch; CI_OPAM contains Coq's CI dependencies.
ENV CAMLP5_VER="6.14" \
diff --git a/dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh b/dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh
new file mode 100644
index 000000000..9d96b6d4c
--- /dev/null
+++ b/dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh
@@ -0,0 +1,4 @@
+ if [ "$CI_PULL_REQUEST" = "664" ] || [ "$CI_BRANCH" = "trunk+fix-5500-too-weak-test-return-clause" ]; then
+ fiat_parsers_CI_BRANCH=master+change-for-coq-pr664-compatibility
+ fiat_parsers_CI_GITURL=https://github.com/herbelin/fiat
+fi
diff --git a/dev/ci/user-overlays/README.md b/dev/ci/user-overlays/README.md
index aec2dfe0a..41212568d 100644
--- a/dev/ci/user-overlays/README.md
+++ b/dev/ci/user-overlays/README.md
@@ -6,7 +6,7 @@ request to test it with the adapted version of the external project.
An overlay is a file which defines where to look for the patched version so that
testing is possible. It redefines some variables from
-[`ci-basic-overlay.sh`](/dev/ci/ci-basic-overlay.sh):
+[`ci-basic-overlay.sh`](../ci-basic-overlay.sh):
give the name of your branch using a `_CI_BRANCH` variable and the location of
your fork using a `_CI_GITURL` variable.
@@ -28,4 +28,4 @@ if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
fi
```
-(`CI_PULL_REQUEST` and `CI_BRANCH` are set in [`ci-common.sh`](/dev/ci/ci-common.sh))
+(`CI_PULL_REQUEST` and `CI_BRANCH` are set in [`ci-common.sh`](../ci-common.sh))
diff --git a/dev/doc/MERGING.md b/dev/doc/MERGING.md
index 65457b63a..c0cd9c8cd 100644
--- a/dev/doc/MERGING.md
+++ b/dev/doc/MERGING.md
@@ -6,7 +6,7 @@ This document describes how patches, submitted as pull requests (PRs) on the
## Code owners
-The [CODEOWNERS](/.github/CODEOWNERS) file describes, for each part of the
+The [CODEOWNERS](../../.github/CODEOWNERS) file describes, for each part of the
system, two owners. One is the principal maintainer of the component, the other
is the secondary maintainer.
@@ -51,10 +51,10 @@ say in a comment they think a review is not required and proceed with the merge.
If the PR breaks compatibility of some external projects in CI, then fixes to
those external projects should have been prepared (cf. the relevant sub-section
-in the [CI README](/dev/ci/README.md#Breaking-changes) and the PR can be tested
-with these fixes thanks to ["overlays"](/dev/ci/user-overlays/README.md).
+in the [CI README](../ci/README.md#Breaking-changes) and the PR can be tested
+with these fixes thanks to ["overlays"](../ci/user-overlays/README.md).
-Moreover the PR must absolutely update the [`CHANGES`](/CHANGES) file.
+Moreover the PR must absolutely update the [`CHANGES`](../../CHANGES) file.
If overlays are missing, ask the author to prepare them and label the PR with
the [needs: overlay](https://github.com/coq/coq/labels/needs%3A%20overlay) label.
@@ -74,7 +74,17 @@ Once all reviewers approved the PR, the assignee is expected to check that CI
completed without relevant failures, and that the PR comes with appropriate
documentation and test cases. If not, they should leave a comment on the PR and
put the approriate label. Otherwise, they are expected to merge the PR using the
-[merge script](/dev/tools/merge-pr.sh).
+[merge script](../tools/merge-pr.sh).
+
+When CI has a few failures which look spurious, restarting the corresponding
+jobs is a good way of ensuring this was indeed the case.
+To restart a job on Travis, you should connect using your GitHub account;
+being part of the Coq organization on GitHub should give you the permission
+to do so.
+To restart a job on GitLab CI, you should sign into GitLab (this can be done
+using a GitHub account); if you are part of the
+[Coq organization on GitLab](https://gitlab.com/coq), you should see a "Retry"
+button; otherwise, send a request to join the organization.
When the PR has conflicts, the assignee can either:
- ask the author to rebase the branch, fixing the conflicts
diff --git a/dev/tools/merge-pr.sh b/dev/tools/merge-pr.sh
index 00d04e6b3..320ef6ed0 100755
--- a/dev/tools/merge-pr.sh
+++ b/dev/tools/merge-pr.sh
@@ -140,6 +140,24 @@ if [ "$LOCAL_BRANCH_COMMIT" != "$UPSTREAM_COMMIT" ]; then
fi
fi
+# Sanity check: PR has an outdated version of CI
+
+BASE_COMMIT=$(echo "$PRDATA" | jq -r '.base.sha')
+CI_FILES=(".travis.yml" ".gitlab-ci.yml" "appveyor.yml")
+
+if ! git diff --quiet "$BASE_COMMIT" "$LOCAL_BRANCH_COMMIT" -- "${CI_FILES[@]}"
+then
+ warning "This PR didn't run with the latest version of CI."
+ warning "It is probably a good idea to ask for a rebase."
+ read -p "Do you want to see the diff? [Y/n] " $QUICK_CONF -r
+ echo
+ if [[ ! $REPLY =~ ^[Nn]$ ]]
+ then
+ git diff "$BASE_COMMIT" "$LOCAL_BRANCH_COMMIT" -- "${CI_FILES[@]}"
+ fi
+ ask_confirmation
+fi
+
# Sanity check: CI failed
STATUS=$(curl -s "$API/commits/$COMMIT/status")
diff --git a/doc/sphinx/addendum/generalized-rewriting.rst b/doc/sphinx/addendum/generalized-rewriting.rst
index e10e16c10..e4d24a1f7 100644
--- a/doc/sphinx/addendum/generalized-rewriting.rst
+++ b/doc/sphinx/addendum/generalized-rewriting.rst
@@ -106,7 +106,7 @@ argument.
Morphisms can also be contravariant in one or more of their arguments.
A morphism is contravariant on an argument associated to the relation
-instance :math`R` if it is covariant on the same argument when the inverse
+instance :math:`R` if it is covariant on the same argument when the inverse
relation :math:`R^{−1}` (``inverse R`` in Coq) is considered. The special arrow ``-->``
is used in signatures for contravariant morphisms.
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
index f65400e88..135c24aed 100755
--- a/doc/sphinx/conf.py
+++ b/doc/sphinx/conf.py
@@ -201,9 +201,9 @@ html_static_path = ['_static']
# The empty string is equivalent to '%b %d, %Y'.
#html_last_updated_fmt = None
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-html_use_smartypants = False # FIXME wrap code in <code> tags, otherwise quotesget converted in there
+# FIXME: this could be re-enabled after ensuring that smart quotes are locally
+# disabled for all relevant directives
+smartquotes = False
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index ff5d352c9..c21d8d4ec 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -1925,74 +1925,75 @@ applied to an unknown structure instance (an implicit argument) and a
value. The complete documentation of canonical structures can be found
in :ref:`canonicalstructures`; here only a simple example is given.
-Assume that `qualid` denotes an object ``(Build_struc`` |c_1| … |c_n| ``)`` in the
-structure *struct* of which the fields are |x_1|, …, |x_n|. Assume that
-`qualid` is declared as a canonical structure using the command
-
.. cmd:: Canonical Structure @qualid
-Then, each time an equation of the form ``(``\ |x_i| ``_)`` |eq_beta_delta_iota_zeta| |c_i| has to be
-solved during the type-checking process, `qualid` is used as a solution.
-Otherwise said, `qualid` is canonically used to extend the field |c_i|
-into a complete structure built on |c_i|.
+ This command declares :token:`qualid` as a canonical structure.
-Canonical structures are particularly useful when mixed with coercions
-and strict implicit arguments. Here is an example.
+ Assume that :token:`qualid` denotes an object ``(Build_struct`` |c_1| … |c_n| ``)`` in the
+ structure :g:`struct` of which the fields are |x_1|, …, |x_n|.
+ Then, each time an equation of the form ``(``\ |x_i| ``_)`` |eq_beta_delta_iota_zeta| |c_i| has to be
+ solved during the type-checking process, :token:`qualid` is used as a solution.
+ Otherwise said, :token:`qualid` is canonically used to extend the field |c_i|
+ into a complete structure built on |c_i|.
-.. coqtop:: all
+ Canonical structures are particularly useful when mixed with coercions
+ and strict implicit arguments.
- Require Import Relations.
+ .. example::
- Require Import EqNat.
+ Here is an example.
- Set Implicit Arguments.
+ .. coqtop:: all
- Unset Strict Implicit.
+ Require Import Relations.
- Structure Setoid : Type := {Carrier :> Set; Equal : relation Carrier;
- Prf_equiv : equivalence Carrier Equal}.
+ Require Import EqNat.
- Definition is_law (A B:Setoid) (f:A -> B) := forall x y:A, Equal x y -> Equal (f x) (f y).
+ Set Implicit Arguments.
- Axiom eq_nat_equiv : equivalence nat eq_nat.
+ Unset Strict Implicit.
- Definition nat_setoid : Setoid := Build_Setoid eq_nat_equiv.
+ Structure Setoid : Type := {Carrier :> Set; Equal : relation Carrier;
+ Prf_equiv : equivalence Carrier Equal}.
- Canonical Structure nat_setoid.
+ Definition is_law (A B:Setoid) (f:A -> B) := forall x y:A, Equal x y -> Equal (f x) (f y).
-Thanks to ``nat_setoid`` declared as canonical, the implicit arguments ``A``
-and ``B`` can be synthesized in the next statement.
+ Axiom eq_nat_equiv : equivalence nat eq_nat.
-.. coqtop:: all
+ Definition nat_setoid : Setoid := Build_Setoid eq_nat_equiv.
- Lemma is_law_S : is_law S.
+ Canonical Structure nat_setoid.
-Remark: If a same field occurs in several canonical structure, then
-only the structure declared first as canonical is considered.
+ Thanks to :g:`nat_setoid` declared as canonical, the implicit arguments :g:`A`
+ and :g:`B` can be synthesized in the next statement.
-.. cmdv:: Canonical Structure @ident := @term : @type
+ .. coqtop:: all
-.. cmdv:: Canonical Structure @ident := @term
+ Lemma is_law_S : is_law S.
-.. cmdv:: Canonical Structure @ident : @type := @term
+ .. note::
+ If a same field occurs in several canonical structures, then
+ only the structure declared first as canonical is considered.
-These are equivalent to a regular definition of `ident` followed by the declaration
-``Canonical Structure`` `ident`.
+ .. cmdv:: Canonical Structure @ident {? : @type } := @term
-See also: more examples in user contribution category (Rocq/ALGEBRA).
+ This is equivalent to a regular definition of :token:`ident` followed by the
+ declaration :n:`Canonical Structure @ident`.
-Print Canonical Projections.
-++++++++++++++++++++++++++++
+.. cmd:: Print Canonical Projections
-This displays the list of global names that are components of some
-canonical structure. For each of them, the canonical structure of
-which it is a projection is indicated. For instance, the above example
-gives the following output:
+ This displays the list of global names that are components of some
+ canonical structure. For each of them, the canonical structure of
+ which it is a projection is indicated.
-.. coqtop:: all
+ .. example::
+
+ For instance, the above example gives the following output:
+
+ .. coqtop:: all
- Print Canonical Projections.
+ Print Canonical Projections.
Implicit types of variables
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index 3b2009657..1c554acdb 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -3657,7 +3657,8 @@ selective rewriting, blocking on the fly the reduction in the term ``t``.
.. coqtop:: reset
- From Coq Require Import ssreflect ssrfun ssrbool List.
+ From Coq Require Import ssreflect ssrfun ssrbool.
+ From Coq Require Import List.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index d7345b701..47ae64d47 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -1313,7 +1313,7 @@ let sort_fields ~complete loc fields completer =
first_field_index, (* index of the first field of the record *)
proj_list) (* list of projections *)
=
- (* elimitate the first field from the projections,
+ (* eliminate the first field from the projections,
but keep its index *)
let rec build_proj_list projs proj_kinds idx ~acc_first_idx acc =
match projs with
diff --git a/interp/declare.ml b/interp/declare.ml
index bc2d2068a..aa737239b 100644
--- a/interp/declare.ml
+++ b/interp/declare.ml
@@ -382,17 +382,34 @@ let inInductive : inductive_obj -> obj =
discharge_function = discharge_inductive;
rebuild_function = infer_inductive_subtyping }
-let declare_projections mind =
- let spec,_ = Inductive.lookup_mind_specif (Global.env ()) (mind,0) in
+let declare_projections univs mind =
+ let env = Global.env () in
+ let spec,_ = Inductive.lookup_mind_specif env (mind,0) in
match spec.mind_record with
- | Some (Some (_, kns, pjs)) ->
- Array.iteri (fun i kn ->
+ | Some (Some (_, kns, _)) ->
+ let projs = Inductiveops.compute_projections env (mind, 0) in
+ Array.iter2 (fun kn (term, types) ->
let id = Label.to_id (Constant.label kn) in
- let entry = {proj_entry_ind = mind; proj_entry_arg = i} in
- let kn' = declare_constant id (ProjectionEntry entry,
- IsDefinition StructureComponent)
- in
- assert(Constant.equal kn kn')) kns; true,true
+ let univs = match univs with
+ | Monomorphic_ind_entry _ ->
+ (** Global constraints already defined through the inductive *)
+ Monomorphic_const_entry Univ.ContextSet.empty
+ | Polymorphic_ind_entry ctx ->
+ Polymorphic_const_entry ctx
+ | Cumulative_ind_entry ctx ->
+ Polymorphic_const_entry (Univ.CumulativityInfo.univ_context ctx)
+ in
+ let term, types = match univs with
+ | Monomorphic_const_entry _ -> term, types
+ | Polymorphic_const_entry ctx ->
+ let u = Univ.UContext.instance ctx in
+ Vars.subst_instance_constr u term, Vars.subst_instance_constr u types
+ in
+ let entry = definition_entry ~types ~univs term in
+ let kn' = declare_constant id (DefinitionEntry entry, IsDefinition StructureComponent) in
+ assert (Constant.equal kn kn')
+ ) kns projs;
+ true, true
| Some None -> true,false
| None -> false,false
@@ -403,7 +420,7 @@ let declare_mind mie =
| [] -> anomaly (Pp.str "cannot declare an empty list of inductives.") in
let (sp,kn as oname) = add_leaf id (inInductive ([],mie)) in
let mind = Global.mind_of_delta_kn kn in
- let isrecord,isprim = declare_projections mind in
+ let isrecord,isprim = declare_projections mie.mind_entry_universes mind in
declare_mib_implicits mind;
declare_inductive_argument_scopes mind mie;
oname, isprim
diff --git a/kernel/constr.ml b/kernel/constr.ml
index c11b9ebf4..418229330 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -107,21 +107,13 @@ type t = (t, t, Sorts.t, Instance.t) kind_of_term
type constr = t
type existential = existential_key * constr array
-type rec_declaration = Name.t array * constr array * constr array
-type fixpoint = (int array * int) * rec_declaration
- (* The array of [int]'s tells for each component of the array of
- mutual fixpoints the number of lambdas to skip before finding the
- recursive argument (e.g., value is 2 in "fix f (x:A) (y:=t) (z:B)
- (v:=u) (w:I) {struct w}"), telling to skip x and z and that w is
- the recursive argument);
- The second component [int] tells which component of the block is
- returned *)
-type cofixpoint = int * rec_declaration
- (* The component [int] tells which component of the block of
- cofixpoint is returned *)
type types = constr
+type rec_declaration = (constr, types) prec_declaration
+type fixpoint = (constr, types) pfixpoint
+type cofixpoint = (constr, types) pcofixpoint
+
(*********************)
(* Term constructors *)
(*********************)
diff --git a/kernel/constr.mli b/kernel/constr.mli
index 742a13919..bf7b5e87b 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -161,8 +161,26 @@ val mkCase : case_info * constr * constr * constr array -> constr
where the length of the {% $ %}j{% $ %}th context is {% $ %}ij{% $ %}.
*)
-type rec_declaration = Name.t array * types array * constr array
-type fixpoint = (int array * int) * rec_declaration
+type ('constr, 'types) prec_declaration =
+ Name.t array * 'types array * 'constr array
+type ('constr, 'types) pfixpoint =
+ (int array * int) * ('constr, 'types) prec_declaration
+ (* The array of [int]'s tells for each component of the array of
+ mutual fixpoints the number of lambdas to skip before finding the
+ recursive argument (e.g., value is 2 in "fix f (x:A) (y:=t) (z:B)
+ (v:=u) (w:I) {struct w}"), telling to skip x and z and that w is
+ the recursive argument);
+ The second component [int] tells which component of the block is
+ returned *)
+
+type ('constr, 'types) pcofixpoint =
+ int * ('constr, 'types) prec_declaration
+ (* The component [int] tells which component of the block of
+ cofixpoint is returned *)
+
+type rec_declaration = (constr, types) prec_declaration
+
+type fixpoint = (constr, types) pfixpoint
val mkFix : fixpoint -> constr
(** If [funnames = [|f1,.....fn|]]
@@ -176,7 +194,7 @@ val mkFix : fixpoint -> constr
...
with fn = bn.]
*)
-type cofixpoint = int * rec_declaration
+type cofixpoint = (constr, types) pcofixpoint
val mkCoFix : cofixpoint -> constr
@@ -185,12 +203,6 @@ val mkCoFix : cofixpoint -> constr
(** [constr array] is an instance matching definitional [named_context] in
the same order (i.e. last argument first) *)
type 'constr pexistential = Evar.t * 'constr array
-type ('constr, 'types) prec_declaration =
- Name.t array * 'types array * 'constr array
-type ('constr, 'types) pfixpoint =
- (int array * int) * ('constr, 'types) prec_declaration
-type ('constr, 'types) pcofixpoint =
- int * ('constr, 'types) prec_declaration
type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Rel of int (** Gallina-variable introduced by [forall], [fun], [let-in], [fix], or [cofix]. *)
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 5783453e6..68057b389 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -156,7 +156,6 @@ type inline = bool
type result = {
cook_body : constant_def;
cook_type : types;
- cook_proj : bool;
cook_universes : constant_universes;
cook_inline : inline;
cook_context : Context.Named.t option;
@@ -230,7 +229,6 @@ let cook_constant ~hcons env { from = cb; info } =
{
cook_body = body;
cook_type = typ;
- cook_proj = cb.const_proj;
cook_universes = univs;
cook_inline = cb.const_inline_code;
cook_context = Some const_hyps;
diff --git a/kernel/cooking.mli b/kernel/cooking.mli
index 0d907f3de..76c79335f 100644
--- a/kernel/cooking.mli
+++ b/kernel/cooking.mli
@@ -21,7 +21,6 @@ type inline = bool
type result = {
cook_body : constant_def;
cook_type : types;
- cook_proj : bool;
cook_universes : constant_universes;
cook_inline : inline;
cook_context : Context.Named.t option;
diff --git a/kernel/declarations.ml b/kernel/declarations.ml
index 7bd70c050..7bd7d6c9c 100644
--- a/kernel/declarations.ml
+++ b/kernel/declarations.ml
@@ -54,8 +54,6 @@ type projection_body = {
proj_npars : int;
proj_arg : int; (** Projection index, starting from 0 *)
proj_type : types; (* Type under params *)
- proj_eta : constr * types; (* Eta-expanded term and type *)
- proj_body : constr; (* For compatibility with VMs only, the match version *)
}
(* Global declarations (i.e. constants) can be either: *)
@@ -87,7 +85,6 @@ type constant_body = {
const_type : types;
const_body_code : Cemitcodes.to_patch_substituted option;
const_universes : constant_universes;
- const_proj : bool;
const_inline_code : bool;
const_typing_flags : typing_flags; (** The typing options which
were used for
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index 75c0e5b4c..1b73096f7 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -86,7 +86,7 @@ let subst_const_def sub def = match def with
let subst_const_proj sub pb =
{ pb with proj_ind = subst_mind sub pb.proj_ind;
proj_type = subst_mps sub pb.proj_type;
- proj_body = subst_const_type sub pb.proj_body }
+ }
let subst_const_body sub cb =
assert (List.is_empty cb.const_hyps); (* we're outside sections *)
@@ -100,7 +100,6 @@ let subst_const_body sub cb =
{ const_hyps = [];
const_body = body';
const_type = type';
- const_proj = cb.const_proj;
const_body_code =
Option.map (Cemitcodes.subst_to_patch_subst sub) cb.const_body_code;
const_universes = cb.const_universes;
diff --git a/kernel/entries.ml b/kernel/entries.ml
index 94da00c7e..3c555f8c7 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -95,14 +95,9 @@ type inline = int option (* inlining level, None for no inlining *)
type parameter_entry =
Context.Named.t option * types in_constant_universes_entry * inline
-type projection_entry = {
- proj_entry_ind : MutInd.t;
- proj_entry_arg : int }
-
type 'a constant_entry =
| DefinitionEntry of 'a definition_entry
| ParameterEntry of parameter_entry
- | ProjectionEntry of projection_entry
(** {6 Modules } *)
diff --git a/kernel/environ.ml b/kernel/environ.ml
index fb89576dd..2d6c9117b 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -490,7 +490,7 @@ let lookup_projection cst env =
Cmap_env.find (Projection.constant cst) env.env_globals.env_projections
let is_projection cst env =
- (lookup_constant cst env).const_proj
+ Cmap_env.mem cst env.env_globals.env_projections
(* Mutual Inductives *)
let polymorphic_ind (mind,i) env =
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 439acd15b..14f2a3d8f 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -797,16 +797,13 @@ exception UndefinableExpansion
build an expansion function.
The term built is expecting to be substituted first by
a substitution of the form [params, x : ind params] *)
-let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
+let compute_projections ((kn, _ as ind), u) nparamargs params
mind_consnrealdecls mind_consnrealargs paramslet ctx =
let mp, dp, l = MutInd.repr3 kn in
(** We build a substitution smashing the lets in the record parameters so
that typechecking projections requires just a substitution and not
matching with a parameter context. *)
- let indty, paramsletsubst =
- (* [ty] = [Ind inst] is typed in context [params] *)
- let inst = Context.Rel.to_extended_vect mkRel 0 paramslet in
- let ty = mkApp (mkIndU indu, inst) in
+ let paramsletsubst =
(* [Ind inst] is typed in context [params-wo-let] *)
let inst' = rel_list 0 nparamargs in
(* {params-wo-let |- subst:params] *)
@@ -814,48 +811,21 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
(* {params-wo-let, x:Ind inst' |- subst':(params,x:Ind inst)] *)
let subst = (* For the record parameter: *)
mkRel 1 :: List.map (lift 1) subst in
- ty, subst
+ subst
in
- let ci =
- let print_info =
- { ind_tags = []; cstr_tags = [|Context.Rel.to_tags ctx|]; style = LetStyle } in
- { ci_ind = ind;
- ci_npar = nparamargs;
- ci_cstr_ndecls = mind_consnrealdecls;
- ci_cstr_nargs = mind_consnrealargs;
- ci_pp_info = print_info }
- in
- let len = List.length ctx in
- let x = Name x in
- let compat_body ccl i =
- (* [ccl] is defined in context [params;x:indty] *)
- (* [ccl'] is defined in context [params;x:indty;x:indty] *)
- let ccl' = liftn 1 2 ccl in
- let p = mkLambda (x, lift 1 indty, ccl') in
- let branch = it_mkLambda_or_LetIn (mkRel (len - i)) ctx in
- let body = mkCase (ci, p, mkRel 1, [|lift 1 branch|]) in
- it_mkLambda_or_LetIn (mkLambda (x,indty,body)) params
- in
- let projections decl (i, j, kns, pbs, subst, letsubst) =
+ let projections decl (i, j, kns, pbs, letsubst) =
match decl with
| LocalDef (na,c,t) ->
(* From [params, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)] *)
let c = liftn 1 j c in
(* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
- to [params, x:I |- c(params,proj1 x,..,projj x)] *)
- let c1 = substl subst c in
- (* From [params, x:I |- subst:field1,..,fieldj]
- to [params, x:I |- subst:field1,..,fieldj+1] where [subst]
- is represented with instance of field1 last *)
- let subst = c1 :: subst in
- (* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params-wo-let, x:I |- c(params,proj1 x,..,projj x)] *)
let c2 = substl letsubst c in
(* From [params-wo-let, x:I |- subst:(params, x:I, field1,..,fieldj)]
to [params-wo-let, x:I |- subst:(params, x:I, field1,..,fieldj+1)] *)
let letsubst = c2 :: letsubst in
- (i, j+1, kns, pbs, subst, letsubst)
+ (i, j+1, kns, pbs, letsubst)
| LocalAssum (na,t) ->
match na with
| Name id ->
@@ -868,21 +838,14 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
let projty = substl letsubst t in
(* from [params, x:I, field1,..,fieldj |- t(field1,..,fieldj)]
to [params, x:I |- t(proj1 x,..,projj x)] *)
- let ty = substl subst t in
- let term = mkProj (Projection.make kn true, mkRel 1) in
let fterm = mkProj (Projection.make kn false, mkRel 1) in
- let compat = compat_body ty (j - 1) in
- let etab = it_mkLambda_or_LetIn (mkLambda (x, indty, term)) params in
- let etat = it_mkProd_or_LetIn (mkProd (x, indty, ty)) params in
let body = { proj_ind = fst ind; proj_npars = nparamargs;
- proj_arg = i; proj_type = projty; proj_eta = etab, etat;
- proj_body = compat } in
- (i + 1, j + 1, kn :: kns, body :: pbs,
- fterm :: subst, fterm :: letsubst)
+ proj_arg = i; proj_type = projty; } in
+ (i + 1, j + 1, kn :: kns, body :: pbs, fterm :: letsubst)
| Anonymous -> raise UndefinableExpansion
in
- let (_, _, kns, pbs, subst, letsubst) =
- List.fold_right projections ctx (0, 1, [], [], [], paramsletsubst)
+ let (_, _, kns, pbs, letsubst) =
+ List.fold_right projections ctx (0, 1, [], [], paramsletsubst)
in
Array.of_list (List.rev kns),
Array.of_list (List.rev pbs)
@@ -987,7 +950,7 @@ let build_inductive env prv iu env_ar paramsctxt kn isrecord isfinite inds nmr r
(try
let fields, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
let kns, projs =
- compute_projections indsp pkt.mind_typename rid nparamargs paramsctxt
+ compute_projections indsp nparamargs paramsctxt
pkt.mind_consnrealdecls pkt.mind_consnrealargs paramslet fields
in Some (Some (rid, kns, projs))
with UndefinableExpansion -> Some None)
diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli
index 5a38172c2..45228e35e 100644
--- a/kernel/indtypes.mli
+++ b/kernel/indtypes.mli
@@ -43,7 +43,7 @@ val check_inductive : env -> MutInd.t -> mutual_inductive_entry -> mutual_induct
val enforce_indices_matter : unit -> unit
val is_indices_matter : unit -> bool
-val compute_projections : pinductive -> Id.t -> Id.t ->
+val compute_projections : pinductive ->
int -> Context.Rel.t -> int array -> int array ->
Context.Rel.t -> Context.Rel.t ->
(Constant.t array * projection_body array)
diff --git a/kernel/mod_subst.ml b/kernel/mod_subst.ml
index 0027ebecf..a47af56ca 100644
--- a/kernel/mod_subst.ml
+++ b/kernel/mod_subst.ml
@@ -24,7 +24,7 @@ open Constr
is the term into which we should inline. *)
type delta_hint =
- | Inline of int * constr option
+ | Inline of int * (Univ.AUContext.t * constr) option
| Equiv of KerName.t
(* NB: earlier constructor Prefix_equiv of ModPath.t
@@ -158,7 +158,7 @@ let find_prefix resolve mp =
(** Applying a resolver to a kernel name *)
-exception Change_equiv_to_inline of (int * constr)
+exception Change_equiv_to_inline of (int * (Univ.AUContext.t * constr))
let solve_delta_kn resolve kn =
try
@@ -300,9 +300,10 @@ let subst_con0 sub (cst,u) =
let knu = KerName.make mpu dir l in
let knc = if mpu == mpc then knu else KerName.make mpc dir l in
match search_delta_inline resolve knu knc with
- | Some t ->
+ | Some (ctx, t) ->
(* In case of inlining, discard the canonical part (cf #2608) *)
- Constant.make1 knu, t
+ let () = assert (Int.equal (Univ.AUContext.size ctx) (Univ.Instance.length u)) in
+ Constant.make1 knu, Vars.subst_instance_constr u t
| None ->
let knc' =
progress (kn_of_delta resolve) (if user then knu else knc) ~orelse:knc
@@ -482,7 +483,7 @@ let gen_subst_delta_resolver dom subst resolver =
| Equiv kequ ->
(try Equiv (subst_kn_delta subst kequ)
with Change_equiv_to_inline (lev,c) -> Inline (lev,Some c))
- | Inline (lev,Some t) -> Inline (lev,Some (subst_mps subst t))
+ | Inline (lev,Some (ctx, t)) -> Inline (lev,Some (ctx, subst_mps subst t))
| Inline (_,None) -> hint
in
Deltamap.add_kn kkey' hint' rslv
diff --git a/kernel/mod_subst.mli b/kernel/mod_subst.mli
index b14d39207..76a1d173b 100644
--- a/kernel/mod_subst.mli
+++ b/kernel/mod_subst.mli
@@ -28,7 +28,7 @@ val add_kn_delta_resolver :
KerName.t -> KerName.t -> delta_resolver -> delta_resolver
val add_inline_delta_resolver :
- KerName.t -> (int * constr option) -> delta_resolver -> delta_resolver
+ KerName.t -> (int * (Univ.AUContext.t * constr) option) -> delta_resolver -> delta_resolver
val add_delta_resolver : delta_resolver -> delta_resolver -> delta_resolver
diff --git a/kernel/modops.ml b/kernel/modops.ml
index 203817118..22f523a9a 100644
--- a/kernel/modops.ml
+++ b/kernel/modops.ml
@@ -403,7 +403,8 @@ let inline_delta_resolver env inl mp mbid mtb delta =
| Undef _ | OpaqueDef _ -> l
| Def body ->
let constr = Mod_subst.force_constr body in
- add_inline_delta_resolver kn (lev, Some constr) l
+ let ctx = Declareops.constant_polymorphic_context constant in
+ add_inline_delta_resolver kn (lev, Some (ctx, constr)) l
with Not_found ->
error_no_such_label_sub (Constant.label con)
(ModPath.to_string (Constant.modpath con))
diff --git a/kernel/names.ml b/kernel/names.ml
index 597061278..1d2a7c4ce 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -17,7 +17,7 @@
the module system, Aug 2002 *)
(* Abstraction over the type of constant for module inlining by Claudio
Sacerdoti, Nov 2004 *)
-(* Miscellaneous features or improvements by Hugo Herbelin,
+(* Miscellaneous features or improvements by Hugo Herbelin,
Élie Soubiran, ... *)
open Pp
@@ -364,7 +364,6 @@ module MPmap = CMap.Make(ModPath)
module KerName = struct
type t = {
- canary : Canary.t;
modpath : ModPath.t;
dirpath : DirPath.t;
knlabel : Label.t;
@@ -372,16 +371,14 @@ module KerName = struct
(** Lazily computed hash. If unset, it is set to negative values. *)
}
- let canary = Canary.obj
-
type kernel_name = t
let make modpath dirpath knlabel =
- { modpath; dirpath; knlabel; refhash = -1; canary; }
+ { modpath; dirpath; knlabel; refhash = -1; }
let repr kn = (kn.modpath, kn.dirpath, kn.knlabel)
let make2 modpath knlabel =
- { modpath; dirpath = DirPath.empty; knlabel; refhash = -1; canary; }
+ { modpath; dirpath = DirPath.empty; knlabel; refhash = -1; }
let modpath kn = kn.modpath
let label kn = kn.knlabel
@@ -437,7 +434,7 @@ module KerName = struct
* (string -> string)
let hashcons (hmod,hdir,hstr) kn =
let { modpath = mp; dirpath = dp; knlabel = l; refhash; } = kn in
- { modpath = hmod mp; dirpath = hdir dp; knlabel = hstr l; refhash; canary; }
+ { modpath = hmod mp; dirpath = hdir dp; knlabel = hstr l; refhash; }
let eq kn1 kn2 =
kn1.modpath == kn2.modpath && kn1.dirpath == kn2.dirpath &&
kn1.knlabel == kn2.knlabel
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index db1109e75..37bf679c5 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -250,7 +250,6 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
{
Cooking.cook_body = Undef nl;
cook_type = t;
- cook_proj = false;
cook_universes = univs;
cook_inline = false;
cook_context = ctx;
@@ -291,7 +290,6 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
{
Cooking.cook_body = def;
cook_type = typ;
- cook_proj = false;
cook_universes = Monomorphic_const univs;
cook_inline = c.const_entry_inline_code;
cook_context = c.const_entry_secctx;
@@ -343,39 +341,11 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
{
Cooking.cook_body = def;
cook_type = typ;
- cook_proj = false;
cook_universes = univs;
cook_inline = c.const_entry_inline_code;
cook_context = c.const_entry_secctx;
}
- | ProjectionEntry {proj_entry_ind = ind; proj_entry_arg = i} ->
- let mib, _ = Inductive.lookup_mind_specif env (ind,0) in
- let kn, pb =
- match mib.mind_record with
- | Some (Some (id, kns, pbs)) ->
- if i < Array.length pbs then
- kns.(i), pbs.(i)
- else assert false
- | _ -> assert false
- in
- let univs =
- match mib.mind_universes with
- | Monomorphic_ind ctx -> Monomorphic_const ctx
- | Polymorphic_ind auctx -> Polymorphic_const auctx
- | Cumulative_ind acumi ->
- Polymorphic_const (Univ.ACumulativityInfo.univ_context acumi)
- in
- let term, typ = pb.proj_eta in
- {
- Cooking.cook_body = Def (Mod_subst.from_val (Constr.hcons term));
- cook_type = typ;
- cook_proj = true;
- cook_universes = univs;
- cook_inline = false;
- cook_context = None;
- }
-
let record_aux env s_ty s_bo =
let in_ty = keep_hyps env s_ty in
let v =
@@ -464,7 +434,6 @@ let build_constant_declaration kn env result =
{ const_hyps = hyps;
const_body = def;
const_type = typ;
- const_proj = result.cook_proj;
const_body_code = tps;
const_universes = univs;
const_inline_code = result.cook_inline;
diff --git a/lib/spawn.ml b/lib/spawn.ml
index 63e9e452c..0652623b7 100644
--- a/lib/spawn.ml
+++ b/lib/spawn.ml
@@ -15,14 +15,12 @@ let accept_timeout = 10.0
let pr_err s = Printf.eprintf "(Spawn ,%d) %s\n%!" (Unix.getpid ()) s
let prerr_endline s = if !Flags.debug then begin pr_err s end else ()
-type req = ReqDie | ReqStats | Hello of int * int
-type resp = RespStats of Gc.stat
+type req = ReqDie | Hello of int * int
module type Control = sig
type handle
val kill : handle -> unit
- val stats : handle -> Gc.stat
val wait : handle -> Unix.process_status
val unixpid : handle -> int
val uid : handle -> string
@@ -43,7 +41,6 @@ module type MainLoopModel = sig
end
(* Common code *)
-let assert_ b s = if not b then CErrors.anomaly (Pp.str s)
(* According to http://caml.inria.fr/mantis/view.php?id=5325
* you can't use the same socket for both writing and reading (may change
@@ -125,14 +122,26 @@ let filter_args args =
Array.of_list (aux (Array.to_list args))
let spawn_with_control prefer_sock env prog args =
- let control_sock, control_sock_name = mk_socket_channel () in
- let extra = [| "-control-channel"; control_sock_name |] in
- let args = Array.append extra (filter_args args) in
+ (* on non-Unix systems we create a control channel *)
+ let not_Unix = Sys.os_type <> "Unix" in
+ let args = filter_args args in
+ let args, control_sock =
+ if not_Unix then
+ let control_sock, control_sock_name = mk_socket_channel () in
+ let extra = [| "-control-channel"; control_sock_name |] in
+ Array.append extra args, Some control_sock
+ else
+ args, None in
let (pid, cin, cout, s), is_sock =
- if Sys.os_type <> "Unix" || prefer_sock
+ if not_Unix (* pipes only work well on Unix *) || prefer_sock
then spawn_sock env prog args, true
else spawn_pipe env prog args, false in
- let _, oob_resp, oob_req = accept control_sock in
+ let oob_resp, oob_req =
+ if not_Unix then
+ let _, oob_resp, oob_req = accept (Option.get control_sock) in
+ Some oob_resp, Some oob_req
+ else
+ None, None in
pid, oob_resp, oob_req, cin, cout, s, is_sock
let output_death_sentence pid oob_req =
@@ -146,8 +155,8 @@ module Async(ML : MainLoopModel) = struct
type process = {
cin : in_channel;
cout : out_channel;
- oob_resp : in_channel;
- oob_req : out_channel;
+ oob_resp : in_channel option;
+ oob_req : out_channel option;
gchan : ML.async_chan;
pid : int;
mutable watch : ML.watch_id option;
@@ -166,11 +175,11 @@ let kill ({ pid = unixpid; oob_resp; oob_req; cin; cout; alive; watch } as p) =
if not alive then prerr_endline "This process is already dead"
else begin try
Option.iter ML.remove_watch watch;
- output_death_sentence (uid p) oob_req;
+ Option.iter (output_death_sentence (uid p)) oob_req;
close_in_noerr cin;
close_out_noerr cout;
- close_in_noerr oob_resp;
- close_out_noerr oob_req;
+ Option.iter close_in_noerr oob_resp;
+ Option.iter close_out_noerr oob_req;
if Sys.os_type = "Unix" then Unix.kill unixpid 9;
p.watch <- None
with e -> prerr_endline ("kill: "^Printexc.to_string e) end
@@ -199,12 +208,6 @@ let spawn ?(prefer_sock=prefer_sock) ?(env=Unix.environment ())
);
p, cout
-let stats { oob_req; oob_resp; alive } =
- assert_ alive "This process is dead.";
- output_value oob_req ReqStats;
- flush oob_req;
- input_value oob_resp
-
let rec wait p =
(* On windows kill is not reliable, so wait may never return. *)
if Sys.os_type = "Unix" then
@@ -221,8 +224,8 @@ module Sync () = struct
type process = {
cin : in_channel;
cout : out_channel;
- oob_resp : in_channel;
- oob_req : out_channel;
+ oob_resp : in_channel option;
+ oob_req : out_channel option;
pid : int;
mutable alive : bool;
}
@@ -242,20 +245,14 @@ let kill ({ pid = unixpid; oob_req; oob_resp; cin; cout; alive } as p) =
p.alive <- false;
if not alive then prerr_endline "This process is already dead"
else begin try
- output_death_sentence (uid p) oob_req;
+ Option.iter (output_death_sentence (uid p)) oob_req;
close_in_noerr cin;
close_out_noerr cout;
- close_in_noerr oob_resp;
- close_out_noerr oob_req;
+ Option.iter close_in_noerr oob_resp;
+ Option.iter close_out_noerr oob_req;
if Sys.os_type = "Unix" then Unix.kill unixpid 9;
with e -> prerr_endline ("kill: "^Printexc.to_string e) end
-let stats { oob_req; oob_resp; alive } =
- assert_ alive "This process is dead.";
- output_value oob_req ReqStats;
- flush oob_req;
- let RespStats g = input_value oob_resp in g
-
let rec wait p =
(* On windows kill is not reliable, so wait may never return. *)
if Sys.os_type = "Unix" then
diff --git a/lib/spawn.mli b/lib/spawn.mli
index c7a56349c..944aa27a7 100644
--- a/lib/spawn.mli
+++ b/lib/spawn.mli
@@ -25,7 +25,6 @@ module type Control = sig
type handle
val kill : handle -> unit
- val stats : handle -> Gc.stat
val wait : handle -> Unix.process_status
val unixpid : handle -> int
@@ -76,6 +75,5 @@ end
(* This is exported to separate the Spawned module, that for simplicity assumes
* Threads so it is in a separate file *)
-type req = ReqDie | ReqStats | Hello of int * int
+type req = ReqDie | Hello of int * int
val proto_version : int
-type resp = RespStats of Gc.stat
diff --git a/library/global.ml b/library/global.ml
index 6083c4079..dcb20a280 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -259,6 +259,9 @@ let is_type_in_type r =
| IndRef ind -> Environ.type_in_type_ind ind env
| ConstructRef cstr -> Environ.type_in_type_ind (inductive_of_constructor cstr) env
+let current_modpath () =
+ Safe_typing.current_modpath (safe_env ())
+
let current_dirpath () =
Safe_typing.current_dirpath (safe_env ())
diff --git a/library/global.mli b/library/global.mli
index 906d246ee..57e173cb9 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -157,6 +157,8 @@ val set_strategy : Constant.t Names.tableKey -> Conv_oracle.level -> unit
(* Modifies the global state, registering new universes *)
+val current_modpath : unit -> ModPath.t
+
val current_dirpath : unit -> DirPath.t
val with_global : (Environ.env -> DirPath.t -> 'a Univ.in_universe_context_set) -> 'a
diff --git a/library/heads.ml b/library/heads.ml
index 3d5f6a6ff..d9d650ac0 100644
--- a/library/heads.ml
+++ b/library/heads.ml
@@ -129,7 +129,7 @@ let compute_head = function
let cb = Environ.lookup_constant cst env in
let is_Def = function Declarations.Def _ -> true | _ -> false in
let body =
- if not cb.Declarations.const_proj && is_Def cb.Declarations.const_body
+ if not (Environ.is_projection cst env) && is_Def cb.Declarations.const_body
then Global.body_of_constant cst else None
in
(match body with
diff --git a/plugins/extraction/extraction.ml b/plugins/extraction/extraction.ml
index 5aee70194..3a61c7747 100644
--- a/plugins/extraction/extraction.ml
+++ b/plugins/extraction/extraction.ml
@@ -1065,11 +1065,15 @@ let extract_constant env kn cb =
(match cb.const_body with
| Undef _ -> warn_info (); mk_typ_ax ()
| Def c ->
- (match cb.const_proj with
+ (match Environ.is_projection kn env with
| false -> mk_typ (get_body c)
| true ->
let pb = lookup_projection (Projection.make kn false) env in
- mk_typ (EConstr.of_constr pb.proj_body))
+ (** FIXME: handle mutual records *)
+ let ind = (pb.Declarations.proj_ind, 0) in
+ let bodies = Inductiveops.legacy_match_projection env ind in
+ let body = bodies.(pb.Declarations.proj_arg) in
+ mk_typ (EConstr.of_constr body))
| OpaqueDef c ->
add_opaque r;
if access_opaque () then mk_typ (get_opaque env c)
@@ -1078,11 +1082,15 @@ let extract_constant env kn cb =
(match cb.const_body with
| Undef _ -> warn_info (); mk_ax ()
| Def c ->
- (match cb.const_proj with
+ (match Environ.is_projection kn env with
| false -> mk_def (get_body c)
| true ->
let pb = lookup_projection (Projection.make kn false) env in
- mk_def (EConstr.of_constr pb.proj_body))
+ (** FIXME: handle mutual records *)
+ let ind = (pb.Declarations.proj_ind, 0) in
+ let bodies = Inductiveops.legacy_match_projection env ind in
+ let body = bodies.(pb.Declarations.proj_arg) in
+ mk_def (EConstr.of_constr body))
| OpaqueDef c ->
add_opaque r;
if access_opaque () then mk_def (get_opaque env c)
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index 8a8f9e71a..04dd7d6e9 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -1049,8 +1049,7 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
push_trace(loc,call) ist >>= fun trace ->
Profile_ltac.do_profile "eval_tactic:2" trace
(catch_error_tac trace (interp_atomic ist t))
- | TacFun _ | TacLetIn _ -> assert false
- | TacMatchGoal _ | TacMatch _ -> assert false
+ | TacFun _ | TacLetIn _ | TacMatchGoal _ | TacMatch _ -> interp_tactic ist tac
| TacId [] -> Proofview.tclLIFT (db_breakpoint (curr_debug ist) [])
| TacId s ->
let msgnl =
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index aa1c23f52..0dd3c5944 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -1427,6 +1427,7 @@ and match_current pb (initial,tomatch) =
let case =
make_case_or_project pb.env !(pb.evdref) indf ci pred current brvals
in
+ let _ = Evarutil.evd_comb1 (Typing.type_of pb.env) pb.evdref pred in
Typing.check_allowed_sort pb.env !(pb.evdref) mind current pred;
{ uj_val = applist (case, inst);
uj_type = prod_applist !(pb.evdref) typ inst }
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index df89d9eac..5a54c6f05 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -690,7 +690,10 @@ and detype_r d flags avoid env sigma t =
let c' =
try
let pb = Environ.lookup_projection p (snd env) in
- let body = pb.Declarations.proj_body in
+ (** FIXME: handle mutual records *)
+ let ind = (pb.Declarations.proj_ind, 0) in
+ let bodies = Inductiveops.legacy_match_projection (snd env) ind in
+ let body = bodies.(pb.Declarations.proj_arg) in
let ty = Retyping.get_type_of (snd env) sigma c in
let ((ind,u), args) = Inductiveops.find_mrectype (snd env) sigma ty in
let body' = strip_lam_assum body in
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index aefae1ecc..8afb9b942 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -929,7 +929,7 @@ let invert_arg_from_subst evd aliases k0 subst_in_env_extended_with_k_binders c_
with Not_found ->
match expand_alias_once evd aliases t with
| None -> raise Not_found
- | Some c -> aux k c in
+ | Some c -> aux k (lift k c) in
try
let c = aux 0 c_in_env_extended_with_k_binders in
Invertible (UniqueProjection (c,!effects))
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 71a457280..11cfd2040 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -269,8 +269,9 @@ let fold_glob_constr_with_binders g f v acc = DAst.(with_val (function
| GCases (_,rtntypopt,tml,pl) ->
let fold_pattern acc {v=(idl,p,c)} = f (List.fold_right g idl v) acc c in
let fold_tomatch (v',acc) (tm,(na,onal)) =
- (Option.fold_left (fun v'' {v=(_,nal)} -> List.fold_right (Name.fold_right g) nal v'')
- (Name.fold_right g na v') onal,
+ ((if rtntypopt = None then v' else
+ Option.fold_left (fun v'' {v=(_,nal)} -> List.fold_right (Name.fold_right g) nal v'')
+ (Name.fold_right g na v') onal),
f v acc tm) in
let (v',acc) = List.fold_left fold_tomatch (v,acc) tml in
let acc = Option.fold_left (f v') acc rtntypopt in
@@ -281,6 +282,7 @@ let fold_glob_constr_with_binders g f v acc = DAst.(with_val (function
| GIf (c,rtntyp,b1,b2) ->
f v (f v (f v (fold_return_type_with_binders f g v acc rtntyp) c) b1) b2
| GRec (_,idl,bll,tyl,bv) ->
+ let v' = Array.fold_right g idl v in
let f' i acc fid =
let v,acc =
List.fold_left
@@ -288,7 +290,7 @@ let fold_glob_constr_with_binders g f v acc = DAst.(with_val (function
(Name.fold_right g na v, f v (Option.fold_left (f v) acc bbd) bty))
(v,acc)
bll.(i) in
- f (Array.fold_right g idl v) (f v acc tyl.(i)) (bv.(i)) in
+ f v' (f v acc tyl.(i)) (bv.(i)) in
Array.fold_left_i f' acc idl
| GCast (c,k) ->
let acc = match k with
@@ -412,8 +414,10 @@ let loc_of_glob_constr c = c.CAst.loc
(**********************************************************************)
(* Alpha-renaming *)
+exception UnsoundRenaming
+
let collide_id l id = List.exists (fun (id',id'') -> Id.equal id id' || Id.equal id id'') l
-let test_id l id = if collide_id l id then raise Not_found
+let test_id l id = if collide_id l id then raise UnsoundRenaming
let test_na l na = Name.iter (test_id l) na
let update_subst na l =
@@ -427,8 +431,6 @@ let update_subst na l =
else na,l)
na (na,l)
-exception UnsoundRenaming
-
let rename_var l id =
try
let id' = Id.List.assoc id l in
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index b1ab2d2b7..1a790be64 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -454,6 +454,110 @@ let build_branch_type env sigma dep p cs =
(**************************************************)
+(** From a rel context describing the constructor arguments,
+ build an expansion function.
+ The term built is expecting to be substituted first by
+ a substitution of the form [params, x : ind params] *)
+let compute_projections env (kn, _ as ind) =
+ let open Term in
+ let mib = Environ.lookup_mind kn env in
+ let indu = match mib.mind_universes with
+ | Monomorphic_ind _ -> mkInd ind
+ | Polymorphic_ind ctx -> mkIndU (ind, make_abstract_instance ctx)
+ | Cumulative_ind ctx ->
+ mkIndU (ind, make_abstract_instance (ACumulativityInfo.univ_context ctx))
+ in
+ let x = match mib.mind_record with
+ | None | Some None ->
+ anomaly Pp.(str "Trying to build primitive projections for a non-primitive record")
+ | Some (Some (id, _, _)) -> Name id
+ in
+ (** FIXME: handle mutual records *)
+ let pkt = mib.mind_packets.(0) in
+ let { mind_consnrealargs; mind_consnrealdecls } = pkt in
+ let { mind_nparams = nparamargs; mind_params_ctxt = params } = mib in
+ let rctx, _ = decompose_prod_assum (subst1 indu pkt.mind_nf_lc.(0)) in
+ let ctx, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
+ let mp, dp, l = MutInd.repr3 kn in
+ (** We build a substitution smashing the lets in the record parameters so
+ that typechecking projections requires just a substitution and not
+ matching with a parameter context. *)
+ let indty =
+ (* [ty] = [Ind inst] is typed in context [params] *)
+ let inst = Context.Rel.to_extended_vect mkRel 0 paramslet in
+ let ty = mkApp (indu, inst) in
+ (* [Ind inst] is typed in context [params-wo-let] *)
+ ty
+ in
+ let ci =
+ let print_info =
+ { ind_tags = []; cstr_tags = [|Context.Rel.to_tags ctx|]; style = LetStyle } in
+ { ci_ind = ind;
+ ci_npar = nparamargs;
+ ci_cstr_ndecls = mind_consnrealdecls;
+ ci_cstr_nargs = mind_consnrealargs;
+ ci_pp_info = print_info }
+ in
+ let len = List.length ctx in
+ let compat_body ccl i =
+ (* [ccl] is defined in context [params;x:indty] *)
+ (* [ccl'] is defined in context [params;x:indty;x:indty] *)
+ let ccl' = liftn 1 2 ccl in
+ let p = mkLambda (x, lift 1 indty, ccl') in
+ let branch = it_mkLambda_or_LetIn (mkRel (len - i)) ctx in
+ let body = mkCase (ci, p, mkRel 1, [|lift 1 branch|]) in
+ it_mkLambda_or_LetIn (mkLambda (x,indty,body)) params
+ in
+ let projections decl (j, pbs, subst) =
+ match decl with
+ | LocalDef (na,c,t) ->
+ (* From [params, field1,..,fieldj |- c(params,field1,..,fieldj)]
+ to [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)] *)
+ let c = liftn 1 j c in
+ (* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
+ to [params, x:I |- c(params,proj1 x,..,projj x)] *)
+ let c1 = substl subst c in
+ (* From [params, x:I |- subst:field1,..,fieldj]
+ to [params, x:I |- subst:field1,..,fieldj+1] where [subst]
+ is represented with instance of field1 last *)
+ let subst = c1 :: subst in
+ (j+1, pbs, subst)
+ | LocalAssum (na,t) ->
+ match na with
+ | Name id ->
+ let kn = Constant.make1 (KerName.make mp dp (Label.of_id id)) in
+ (* from [params, field1,..,fieldj |- t(params,field1,..,fieldj)]
+ to [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj] *)
+ let t = liftn 1 j t in
+ (* from [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj)]
+ to [params-wo-let, x:I |- t(params,proj1 x,..,projj x)] *)
+ (* from [params, x:I, field1,..,fieldj |- t(field1,..,fieldj)]
+ to [params, x:I |- t(proj1 x,..,projj x)] *)
+ let ty = substl subst t in
+ let term = mkProj (Projection.make kn true, mkRel 1) in
+ let fterm = mkProj (Projection.make kn false, mkRel 1) in
+ let compat = compat_body ty (j - 1) in
+ let etab = it_mkLambda_or_LetIn (mkLambda (x, indty, term)) params in
+ let etat = it_mkProd_or_LetIn (mkProd (x, indty, ty)) params in
+ let body = (etab, etat, compat) in
+ (j + 1, body :: pbs, fterm :: subst)
+ | Anonymous ->
+ anomaly Pp.(str "Trying to build primitive projections for a non-primitive record")
+ in
+ let (_, pbs, subst) =
+ List.fold_right projections ctx (1, [], [])
+ in
+ Array.rev_of_list pbs
+
+let legacy_match_projection env ind =
+ Array.map pi3 (compute_projections env ind)
+
+let compute_projections ind mib =
+ let ans = compute_projections ind mib in
+ Array.map (fun (prj, ty, _) -> (prj, ty)) ans
+
+(**************************************************)
+
let extract_mrectype sigma t =
let open EConstr in
let (t, l) = decompose_app sigma t in
diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli
index b0d714b03..aa53f7e67 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -194,6 +194,18 @@ val make_case_or_project :
val make_default_case_info : env -> case_style -> inductive -> case_info
i*)
+val compute_projections : Environ.env -> inductive -> (constr * types) array
+(** Given a primitive record type, for every field computes the eta-expanded
+ projection and its type. *)
+
+val legacy_match_projection : Environ.env -> inductive -> constr array
+(** Given a record type, computes the legacy match-based projection of the
+ projections.
+
+ BEWARE: such terms are ill-typed, and should thus only be used in upper
+ layers. The kernel will probably badly fail if presented with one of
+ those. *)
+
(********************)
val type_of_inductive_knowing_conclusion :
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index bffe36eea..cf34ac016 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -197,10 +197,13 @@ let check_type_fixpoint ?loc env sigma lna lar vdefj =
(* FIXME: might depend on the level of actual parameters!*)
let check_allowed_sort env sigma ind c p =
- let pj = Retyping.get_judgment_of env sigma p in
- let ksort = Sorts.family (ESorts.kind sigma (sort_of_arity env sigma pj.uj_type)) in
let specif = Global.lookup_inductive (fst ind) in
let sorts = elim_sorts specif in
+ let pj = Retyping.get_judgment_of env sigma p in
+ let _, s = splay_prod env sigma pj.uj_type in
+ let ksort = match EConstr.kind sigma s with
+ | Sort s -> Sorts.family (ESorts.kind sigma s)
+ | _ -> error_elim_arity env sigma ind sorts c pj None in
if not (List.exists ((==) ksort) sorts) then
let s = inductive_sort_family (snd specif) in
error_elim_arity env sigma ind sorts c pj
diff --git a/proofs/clenvtac.ml b/proofs/clenvtac.ml
index 544175c6d..ba4cde6d6 100644
--- a/proofs/clenvtac.ml
+++ b/proofs/clenvtac.ml
@@ -87,7 +87,7 @@ let clenv_refine ?(with_evars=false) ?(with_classes=true) clenv =
let evd' =
if has_typeclass then
Typeclasses.resolve_typeclasses ~fast_path:false ~filter:Typeclasses.all_evars
- ~fail:(not with_evars) clenv.env clenv.evd
+ ~fail:(not with_evars) ~split:false clenv.env clenv.evd
else clenv.evd
in
if has_resolvable then
diff --git a/stm/spawned.ml b/stm/spawned.ml
index 3833c8026..a5d6ea96f 100644
--- a/stm/spawned.ml
+++ b/stm/spawned.ml
@@ -28,13 +28,11 @@ let controller h pr pw =
prerr_endline "starting controller thread";
let main () =
let ic, oc = open_bin_connection h pr pw in
- let rec loop () =
+ let loop () =
try
match CThread.thread_friendly_input_value ic with
| Hello _ -> prerr_endline "internal protocol error"; exit 1
| ReqDie -> prerr_endline "death sentence received"; exit 0
- | ReqStats ->
- output_value oc (RespStats (Gc.quick_stat ())); flush oc; loop ()
with
| e ->
prerr_endline ("control channel broken: " ^ Printexc.to_string e);
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 67170d2cf..770e31fea 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -2650,6 +2650,15 @@ let insert_before decls lasthyp env =
push_named d env)
~init:(reset_context env) env
+let mk_eq_name env id {CAst.loc;v=ido} =
+ match ido with
+ | IntroAnonymous -> fresh_id_in_env (Id.Set.singleton id) (add_prefix "Heq" id) env
+ | IntroFresh heq_base -> fresh_id_in_env (Id.Set.singleton id) heq_base env
+ | IntroIdentifier id ->
+ if List.mem id (ids_of_named_context (named_context env)) then
+ user_err ?loc (Id.print id ++ str" is already used.");
+ id
+
(* unsafe *)
let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
@@ -2659,14 +2668,7 @@ let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
else LocalAssum (id,t)
in
match with_eq with
- | Some (lr,{CAst.loc;v=ido}) ->
- let heq = match ido with
- | IntroAnonymous -> fresh_id_in_env (Id.Set.singleton id) (add_prefix "Heq" id) env
- | IntroFresh heq_base -> fresh_id_in_env (Id.Set.singleton id) heq_base env
- | IntroIdentifier id ->
- if List.mem id (ids_of_named_context (named_context env)) then
- user_err ?loc (Id.print id ++ str" is already used.");
- id in
+ | Some (lr,heq) ->
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
let (sigma, eq) = Evd.fresh_global env sigma eqdata.eq in
@@ -4401,7 +4403,8 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
match res with
| None ->
(* pattern not found *)
- let with_eq = Option.map (fun eq -> (false,eq)) eqname in
+ let with_eq = Option.map (fun eq -> (false,mk_eq_name env id eq)) eqname in
+ let inhyps = if List.is_empty inhyps then inhyps else Option.fold_left (fun inhyps (_,heq) -> heq::inhyps) inhyps with_eq in
(* we restart using bindings after having tried type-class
resolution etc. on the term given by the user *)
let flags = tactic_infer_flags (with_evars && (* do not give a success semantics to edestruct on an open term yet *) false) in
@@ -4426,21 +4429,22 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
else Proofview.tclUNIT ();
if isrec then Proofview.cycle (-1) else Proofview.tclUNIT ()
])
- tac
+ (tac inhyps)
in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma) tac
| Some (sigma', c) ->
(* pattern found *)
- let with_eq = Option.map (fun eq -> (false,eq)) eqname in
(* TODO: if ind has predicate parameters, use JMeq instead of eq *)
let env = reset_with_named_context sign env in
+ let with_eq = Option.map (fun eq -> (false,mk_eq_name env id eq)) eqname in
+ let inhyps = if List.is_empty inhyps then inhyps else Option.fold_left (fun inhyps (_,heq) -> heq::inhyps) inhyps with_eq in
let tac =
Tacticals.New.tclTHENLIST [
Refine.refine ~typecheck:false begin fun sigma ->
mkletin_goal env sigma store with_eq true (id,lastlhyp,ccl,c) None
end;
- tac
+ (tac inhyps)
]
in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma') tac
@@ -4490,7 +4494,7 @@ let induction_gen clear_flag isrec with_evars elim
pose_induction_arg_then
isrec with_evars info_arg elim id arg t inhyps cls
(induction_with_atomization_of_ind_arg
- isrec with_evars elim names id inhyps)
+ isrec with_evars elim names id)
end
(* Induction on a list of arguments. First make induction arguments
diff --git a/test-suite/README.md b/test-suite/README.md
index ef2e574ec..e81da0830 100644
--- a/test-suite/README.md
+++ b/test-suite/README.md
@@ -62,20 +62,26 @@ BUILDING SUMMARY FILE
NO FAILURES
```
-See [`test-suite/Makefile`](/test-suite/Makefile) for more information.
+See [`test-suite/Makefile`](Makefile) for more information.
## Adding a test
-Regression tests for closed bugs should be added to `test-suite/bugs/closed`, as `1234.v` where `1234` is the bug number.
+Regression tests for closed bugs should be added to
+[`bugs/closed`](bugs/closed), as `1234.v` where `1234` is the bug number.
Files in this directory are tested for successful compilation.
When you fix a bug, you should usually add a regression test here as well.
-The error "(bug seems to be opened, please check)" when running `make test-suite` means that a test in `bugs/closed` failed to compile.
+The error "(bug seems to be opened, please check)" when running
+`make test-suite` means that a test in [`bugs/closed`](bugs/closed) failed to
+compile.
-There are also output tests in `test-suite/output` which consist of a `.v` file and a `.out` file with the expected output.
+There are also output tests in [`output`](output) which consist of a `.v` file
+and a `.out` file with the expected output.
-There are unit tests of OCaml code in `test-suite/unit-tests`. These tests are contained in `.ml` files, and rely on the `OUnit`
-unit-test framework, as described at http://ounit.forge.ocamlcore.org/. Use `make unit-tests' in the unit-tests directory to run them.
+There are unit tests of OCaml code in [`unit-tests`](unit-tests). These tests
+are contained in `.ml` files, and rely on the `OUnit` unit-test framework, as
+described at <http://ounit.forge.ocamlcore.org/>. Use `make unit-tests` in the
+[`unit-tests`](unit-tests) directory to run them.
## Fixing output tests
@@ -88,5 +94,5 @@ automatically.
Don't forget to check the updated `.out` files into git!
Note that `output/MExtraction.out` is special: it is copied from
-`micromega/micromega.ml` in the plugin source directory. Automatic
-approval will incorrectly update the copy.
+[`micromega/micromega.ml`](../plugins/micromega/micromega.ml) in the plugin
+source directory. Automatic approval will incorrectly update the copy.
diff --git a/test-suite/bugs/closed/2800.v b/test-suite/bugs/closed/2800.v
index 2ee438934..54c75e344 100644
--- a/test-suite/bugs/closed/2800.v
+++ b/test-suite/bugs/closed/2800.v
@@ -4,3 +4,16 @@ intuition
match goal with
| |- _ => idtac " foo"
end.
+
+ lazymatch goal with _ => idtac end.
+ match goal with _ => idtac end.
+ unshelve lazymatch goal with _ => idtac end.
+ unshelve match goal with _ => idtac end.
+ unshelve (let x := I in idtac).
+Abort.
+
+Require Import ssreflect.
+
+Goal True.
+match goal with _ => idtac end => //.
+Qed.
diff --git a/test-suite/bugs/closed/5500.v b/test-suite/bugs/closed/5500.v
new file mode 100644
index 000000000..aa63e2ab0
--- /dev/null
+++ b/test-suite/bugs/closed/5500.v
@@ -0,0 +1,35 @@
+(* Too weak check on the correctness of return clause was leading to an anomaly *)
+
+Inductive Vector A: nat -> Type :=
+ nil: Vector A O
+| cons: forall n, A -> Vector A n -> Vector A (S n).
+
+(* This could be made working with a better inference of inner return
+ predicates from the return predicate at the higher level of the
+ nested matching. Currently, we only check that it does not raise an
+ anomaly, but eventually, the "Fail" could be removed. *)
+
+Fail Definition hd_fst A x n (v: A * Vector A (S n)) :=
+ match v as v0 return match v0 with
+ (l, r) =>
+ match r in Vector _ n return match n with 0 => Type | S _ => Type end with
+ nil _ => A
+ | cons _ _ _ _ => A
+ end
+ end with
+ (_, nil _) => x
+ | (_, cons _ n hd tl) => hd
+ end.
+
+(* This is another example of failure but involving beta-reduction and
+ not iota-reduction. Thus, for this one, I don't see how it could be
+ solved by small inversion, whatever smart is small inversion. *)
+
+Inductive A : (Type->Type) -> Type := J : A (fun x => x).
+
+Fail Check fun x : nat * A (fun x => x) =>
+ match x return match x with
+ (y,z) => match z in A f return f Type with J => bool end
+ end with
+ (y,J) => true
+ end.
diff --git a/test-suite/bugs/closed/5547.v b/test-suite/bugs/closed/5547.v
new file mode 100644
index 000000000..79633f489
--- /dev/null
+++ b/test-suite/bugs/closed/5547.v
@@ -0,0 +1,16 @@
+(* Checking typability of intermediate return predicates in nested pattern-matching *)
+
+Inductive A : (Type->Type) -> Type := J : A (fun x => x).
+Definition ret (x : nat * A (fun x => x))
+ := match x return Type with
+ | (y,z) => match z in A f return f Type with
+ | J => bool
+ end
+ end.
+Definition foo : forall x, ret x.
+Proof.
+Fail refine (fun x
+ => match x return ret x with
+ | (y,J) => true
+ end
+ ).
diff --git a/test-suite/bugs/closed/7615.v b/test-suite/bugs/closed/7615.v
new file mode 100644
index 000000000..cd8c4ad7d
--- /dev/null
+++ b/test-suite/bugs/closed/7615.v
@@ -0,0 +1,19 @@
+Set Universe Polymorphism.
+
+Module Type S.
+Parameter Inline T@{i} : Type@{i+1}.
+End S.
+
+Module F (X : S).
+Definition X@{j i} : Type@{j} := X.T@{i}.
+End F.
+
+Module M.
+Definition T@{i} := Type@{i}.
+End M.
+
+Module N := F(M).
+
+Require Import Hurkens.
+
+Fail Definition eqU@{i j} : @eq Type@{j} N.X@{i Set} Type@{i} := eq_refl.
diff --git a/test-suite/bugs/closed/7779.v b/test-suite/bugs/closed/7779.v
new file mode 100644
index 000000000..78936b595
--- /dev/null
+++ b/test-suite/bugs/closed/7779.v
@@ -0,0 +1,15 @@
+(* Checking that the "in" clause takes the "eqn" clause into account *)
+
+Definition test (x: nat): {y: nat | False }. Admitted.
+
+Parameter x: nat.
+Parameter z: nat.
+
+Goal
+ proj1_sig (test x) = z ->
+ False.
+Proof.
+ intro H.
+ destruct (test x) eqn:Heqs in H.
+ change (test x = exist (fun _ : nat => False) x0 f) in Heqs. (* Check it has the expected statement *)
+Abort.
diff --git a/test-suite/bugs/closed/7780.v b/test-suite/bugs/closed/7780.v
new file mode 100644
index 000000000..2318f4d6e
--- /dev/null
+++ b/test-suite/bugs/closed/7780.v
@@ -0,0 +1,16 @@
+(* A lift was missing in expanding aliases under binders for unification *)
+
+(* Below, the lift was missing while expanding the reference to
+ [mkcons] in [?N] which was under binder [arg] *)
+
+Goal forall T (t : T) (P P0 : T -> Set), option (option (list (P0 t)) -> option (list (P t))).
+ intros ????.
+ refine (Some
+ (fun rls
+ => let mkcons := ?[M] in
+ let default arg := ?[N] in
+ match rls as rls (* 2 *) return option (list (P ?[O])) with
+ | Some _ => None
+ | None => None
+ end)).
+Abort.
diff --git a/test-suite/bugs/closed/7811.v b/test-suite/bugs/closed/7811.v
new file mode 100644
index 000000000..fee330f22
--- /dev/null
+++ b/test-suite/bugs/closed/7811.v
@@ -0,0 +1,114 @@
+(* -*- mode: coq; coq-prog-args: ("-emacs" "-top" "atomic" "-Q" "." "iris" "-R" "." "stdpp") -*- *)
+(* File reduced by coq-bug-finder from original input, then from 140 lines to 26 lines, then from 141 lines to 27 lines, then from 142 lines to 27 lines, then from 272 lines to 61 lines, then from 291 lines to 94 lines, then from 678 lines to 142 lines, then from 418 lines to 161 lines, then from 538 lines to 189 lines, then from 840 lines to 493 lines, then from 751 lines to 567 lines, then from 913 lines to 649 lines, then from 875 lines to 666 lines, then from 784 lines to 568 lines, then from 655 lines to 173 lines, then from 317 lines to 94 lines, then from 172 lines to 86 lines, then from 102 lines to 86 lines, then from 130 lines to 86 lines, then from 332 lines to 112 lines, then from 279 lines to 111 lines, then from 3996 lines to 5697 lines, then from 153 lines to 117 lines, then from 146 lines to 108 lines, then from 124 lines to 108 lines *)
+(* coqc version 8.8.0 (May 2018) compiled on May 2 2018 16:49:46 with OCaml 4.02.3
+ coqtop version 8.8.0 (May 2018) *)
+
+(* This was triggering a "Not_found" at the time of printing/showing the goal *)
+
+Require Coq.Unicode.Utf8.
+
+Notation "t $ r" := (t r)
+ (at level 65, right associativity, only parsing).
+
+Inductive tele : Type :=
+ | TeleO : tele
+ | TeleS {X} (binder : X -> tele) : tele.
+
+Fixpoint tele_fun (TT : tele) (T : Type) : Type :=
+ match TT with
+ | TeleO => T
+ | TeleS b => forall x, tele_fun (b x) T
+ end.
+
+Inductive tele_arg : tele -> Type :=
+| TargO : tele_arg TeleO
+| TargS {X} {binder} (x : X) : tele_arg (binder x) -> tele_arg (TeleS binder).
+
+Axiom tele_app : forall {TT : tele} {T} (f : tele_fun TT T), tele_arg TT -> T.
+
+Coercion tele_arg : tele >-> Sortclass.
+
+Inductive val :=
+ | LitV
+ | PairV (v1 v2 : val)
+ | InjLV (v : val)
+ | InjRV (v : val).
+Axiom coPset : Set.
+Axiom atomic_update : forall {PROP : Type} {TA TB : tele}, coPset -> coPset -> (TA -> PROP) -> (TA -> TB -> PROP) -> (TA -> TB -> PROP) -> PROP.
+Import Coq.Unicode.Utf8.
+Notation "'AU' '<<' ∀ x1 .. xn , α '>>' @ Eo , Ei '<<' β , 'COMM' Φ '>>'" :=
+ (atomic_update (TA:=TeleS (λ x1, .. (TeleS (λ xn, TeleO)) .. ))
+ (TB:=TeleO)
+ Eo Ei
+ (tele_app (TT:=TeleS (λ x1, .. (TeleS (λ xn, TeleO)) .. )) $
+ λ x1, .. (λ xn, α) ..)
+ (tele_app (TT:=TeleS (λ x1, .. (TeleS (λ xn, TeleO)) .. )) $
+ λ x1, .. (λ xn, tele_app (TT:=TeleO) β) .. )
+ (tele_app (TT:=TeleS (λ x1, .. (TeleS (λ xn, TeleO)) .. )) $
+ λ x1, .. (λ xn, tele_app (TT:=TeleO) Φ) .. )
+ )
+ (at level 20, Eo, Ei, α, β, Φ at level 200, x1 binder, xn binder,
+ format "'[ ' 'AU' '<<' ∀ x1 .. xn , α '>>' '/' @ Eo , Ei '/' '[ ' '<<' β , '/' COMM Φ '>>' ']' ']'") : bi_scope.
+
+Axiom ident : Set.
+Inductive env (A : Type) : Type := Enil : env A | Esnoc : env A → ident → A → env A.
+Record envs (PROP : Type) : Type
+ := Envs { env_spatial : env PROP }.
+Axiom positive : Set.
+Axiom Qp : Set.
+Axiom one : positive.
+Goal forall (T : Type) (T0 : forall _ : T, Type) (P : Set)
+ (u : T) (γs : P) (Q : T0 u) (Φ o : forall _ : val, T0 u)
+ (stack_content0 : forall (_ : P) (_ : list val), T0 u)
+ (c c0 : coPset) (l : forall (A : Type) (_ : list A), list A)
+ (e0 : forall (_ : env (T0 u)) (_ : positive), envs (T0 u))
+ (i0 : ident) (o1 : forall (_ : Qp) (_ : val), T0 u)
+ (b0 : forall _ : env (T0 u), T0 u) (P0 : forall _ : T0 u, Type)
+ (u0 : forall (_ : T0 u) (_ : T0 u), T0 u),
+ P0
+ (@atomic_update (T0 u)
+ (@TeleS val (fun _ : val => @TeleS Qp (fun _ : Qp => TeleO))) TeleO c c0
+ (@tele_app (@TeleS val (fun _ : val => @TeleS Qp (fun _ : Qp => TeleO)))
+ (T0 u) (fun (v : val) (q : Qp) => o1 q v))
+ (@tele_app (@TeleS val (fun _ : val => @TeleS Qp (fun _ : Qp => TeleO)))
+ (forall _ : tele_arg TeleO, T0 u)
+ (fun (v : val) (q : Qp) => @tele_app TeleO (T0 u) (o1 q v)))
+ (@tele_app (@TeleS val (fun _ : val => @TeleS Qp (fun _ : Qp => TeleO)))
+ (forall _ : tele_arg TeleO, T0 u)
+ (fun (x : val) (_ : Qp) =>
+ @tele_app TeleO (T0 u)
+ (u0
+ (b0
+ match
+ e0
+ (@Esnoc (T0 u) (@Enil (T0 u)) i0
+ (@atomic_update (T0 u)
+ (@TeleS (list val) (fun _ : list val => TeleO)) TeleO
+ c c0
+ (@tele_app
+ (@TeleS (list val) (fun _ : list val => TeleO))
+ (T0 u) (fun l0 : list val => stack_content0 γs l0))
+ (@tele_app
+ (@TeleS (list val) (fun _ : list val => TeleO))
+ (forall _ : tele_arg TeleO, T0 u)
+ (fun l0 : list val =>
+ @tele_app TeleO (T0 u)
+ (stack_content0 γs (l val l0))))
+ (@tele_app
+ (@TeleS (list val) (fun _ : list val => TeleO))
+ (forall _ : tele_arg TeleO, T0 u)
+ (fun x1 : list val =>
+ @tele_app TeleO (T0 u)
+ (u0 Q
+ (Φ
+ match x1 return val with
+ | nil => InjLV LitV
+ | cons v _ => InjRV v
+ end)))))) one
+ return (env (T0 u))
+ with
+ | Envs _ env_spatial0 => env_spatial0
+ end) (o x)))))
+.
+ Show.
+Abort.
diff --git a/test-suite/output/PrintAssumptions.out b/test-suite/output/PrintAssumptions.out
index 66458543a..34f44cd24 100644
--- a/test-suite/output/PrintAssumptions.out
+++ b/test-suite/output/PrintAssumptions.out
@@ -18,3 +18,5 @@ Closed under the global context
Closed under the global context
Axioms:
M.foo : False
+Closed under the global context
+Closed under the global context
diff --git a/test-suite/output/PrintAssumptions.v b/test-suite/output/PrintAssumptions.v
index c2003816c..ea1ab6378 100644
--- a/test-suite/output/PrintAssumptions.v
+++ b/test-suite/output/PrintAssumptions.v
@@ -110,3 +110,30 @@ End N.
Print Assumptions N.foo.
End INCLUDE.
+
+(* Print Assumptions did not enter implementation of submodules (#7192) *)
+
+Module SUBMODULES.
+
+Definition a := True.
+Module Type B. Axiom f : Prop. End B.
+Module Type C. Declare Module D : B. End C.
+Module E: C.
+ Module D <: B. Definition f := a. End D.
+End E.
+Print Assumptions E.D.f.
+
+(* Idem in the scope of a functor *)
+
+Module Type T. End T.
+Module F (X : T).
+ Definition a := True.
+ Module Type B. Axiom f : Prop. End B.
+ Module Type C. Declare Module D : B. End C.
+ Module E: C.
+ Module D <: B. Definition f := a. End D.
+ End E.
+ Print Assumptions E.D.f.
+End F.
+
+End SUBMODULES.
diff --git a/test-suite/output/Unicode.out b/test-suite/output/Unicode.out
new file mode 100644
index 000000000..a57b3bbad
--- /dev/null
+++ b/test-suite/output/Unicode.out
@@ -0,0 +1,41 @@
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∀ (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∀ (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2), f y x ∧ f y z
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∀ (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2),
+ f y x ∧ f y z ∧ f y x ∧ f y z ∧ f y x ∧ f y z
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∃ (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y
diff --git a/test-suite/output/Unicode.v b/test-suite/output/Unicode.v
new file mode 100644
index 000000000..42b07e5a0
--- /dev/null
+++ b/test-suite/output/Unicode.v
@@ -0,0 +1,28 @@
+Require Import Coq.Unicode.Utf8.
+
+Section test.
+Context (very_very_long_type_name1 : Type) (very_very_long_type_name2 : Type).
+Context (f : very_very_long_type_name1 -> very_very_long_type_name2 -> Prop).
+
+Lemma test : True -> True ->
+ forall (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y /\ f x y /\ f x y /\ f x y /\ f x y /\ f x y.
+Proof. Show. Abort.
+
+Lemma test : True -> True ->
+ forall (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2),
+ f y x /\ f y z.
+Proof. Show. Abort.
+
+Lemma test : True -> True ->
+ forall (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2),
+ f y x /\ f y z /\ f y x /\ f y z /\ f y x /\ f y z.
+Proof. Show. Abort.
+
+Lemma test : True -> True ->
+ exists (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y /\ f x y /\ f x y /\ f x y /\ f x y /\ f x y.
+Proof. Show. Abort.
+End test.
diff --git a/test-suite/success/Hints.v b/test-suite/success/Hints.v
index 8d08f5975..717dc0deb 100644
--- a/test-suite/success/Hints.v
+++ b/test-suite/success/Hints.v
@@ -169,7 +169,7 @@ Proof.
Hint Cut [_* (a_is_b | b_is_c | c_is_d | d_is_e)
(a_compose | b_compose | c_compose | d_compose | e_compose)] : typeclass_instances.
- Timeout 1 Fail apply _. (* 0.06s *)
+Timeout 1 Fail apply _. (* 0.06s *)
Abort.
End HintCut.
diff --git a/theories/Unicode/Utf8_core.v b/theories/Unicode/Utf8_core.v
index 5a8931a8c..d4cdb064f 100644
--- a/theories/Unicode/Utf8_core.v
+++ b/theories/Unicode/Utf8_core.v
@@ -14,10 +14,10 @@
(* Logic *)
Notation "∀ x .. y , P" := (forall x, .. (forall y, P) ..)
(at level 200, x binder, y binder, right associativity,
- format "'[ ' ∀ x .. y ']' , P") : type_scope.
+ format "'[ ' '[ ' ∀ x .. y ']' , '/' P ']'") : type_scope.
Notation "∃ x .. y , P" := (exists x, .. (exists y, P) ..)
(at level 200, x binder, y binder, right associativity,
- format "'[ ' ∃ x .. y ']' , P") : type_scope.
+ format "'[ ' '[ ' ∃ x .. y ']' , '/' P ']'") : type_scope.
Notation "x ∨ y" := (x \/ y) (at level 85, right associativity) : type_scope.
Notation "x ∧ y" := (x /\ y) (at level 80, right associativity) : type_scope.
@@ -31,4 +31,4 @@ Notation "x ≠ y" := (x <> y) (at level 70) : type_scope.
(* Abstraction *)
Notation "'λ' x .. y , t" := (fun x => .. (fun y => t) ..)
(at level 200, x binder, y binder, right associativity,
- format "'[ ' 'λ' x .. y ']' , t").
+ format "'[ ' '[ ' 'λ' x .. y ']' , '/' t ']'").
diff --git a/tools/CoqMakefile.in b/tools/CoqMakefile.in
index e5f22f25e..8e60d3932 100644
--- a/tools/CoqMakefile.in
+++ b/tools/CoqMakefile.in
@@ -227,7 +227,7 @@ ifdef DSTROOT
DESTDIR := $(DSTROOT)
endif
-concat_path = $(if $(1),$(1)/$(subst $(COQMF_WINDRIVE),/,$(2)),$(2))
+concat_path = $(if $(1),$(1)/$(if $(COQMF_WINDRIVE),$(subst $(COQMF_WINDRIVE),/,$(2)),$(2)),$(2))
COQLIBINSTALL = $(call concat_path,$(DESTDIR),$(COQLIB)user-contrib)
COQDOCINSTALL = $(call concat_path,$(DESTDIR),$(DOCDIR)user-contrib)
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 6cd520d60..6f11ee397 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -215,7 +215,7 @@ let generate_conf_includes oc { ml_includes; r_includes; q_includes } =
let windrive s =
if Coq_config.arch_is_win32 && Str.(string_match (regexp "^[a-zA-Z]:") s 0)
then Str.matched_string s
- else s
+ else ""
;;
let generate_conf_coq_config oc args =
diff --git a/vernac/assumptions.ml b/vernac/assumptions.ml
index 45ccf7276..765f962e9 100644
--- a/vernac/assumptions.ml
+++ b/vernac/assumptions.ml
@@ -69,16 +69,15 @@ let rec fields_of_functor f subs mp0 args = function
fields_of_functor f subs mp0 args e
let rec lookup_module_in_impl mp =
- try Global.lookup_module mp
- with Not_found ->
- (* The module we search might not be exported by its englobing module(s).
- We access the upper layer, and then do a manual search *)
match mp with
- | MPfile _ -> raise Not_found (* can happen if mp is an open module *)
+ | MPfile _ -> raise Not_found
| MPbound _ -> assert false
| MPdot (mp',lab') ->
- let fields = memoize_fields_of_mp mp' in
- search_mod_label lab' fields
+ if ModPath.equal mp' (Global.current_modpath ()) then
+ Global.lookup_module mp
+ else
+ let fields = memoize_fields_of_mp mp' in
+ search_mod_label lab' fields
and memoize_fields_of_mp mp =
try MPmap.find mp !modcache