aboutsummaryrefslogtreecommitdiffhomepage
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/declare.ml5
-rw-r--r--library/global.ml24
-rw-r--r--library/global.mli3
-rw-r--r--library/universes.ml19
-rw-r--r--library/universes.mli13
5 files changed, 56 insertions, 8 deletions
diff --git a/library/declare.ml b/library/declare.ml
index 41f50753f..820e72369 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -253,7 +253,10 @@ let declare_constant ?(internal = UserVerbose) ?(local = false) id (cd, kind) =
let cd = (* We deal with side effects of non-opaque constants *)
match cd with
| Entries.DefinitionEntry ({
- const_entry_opaque = false; const_entry_body = bo } as de) ->
+ const_entry_opaque = false; const_entry_body = bo } as de)
+ | Entries.DefinitionEntry ({
+ const_entry_polymorphic = true; const_entry_body = bo } as de)
+ ->
let pt, seff = Future.force bo in
if Declareops.side_effects_is_empty seff then cd
else begin
diff --git a/library/global.ml b/library/global.ml
index c56bc9e77..16b07db25 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -160,6 +160,30 @@ let type_of_global_unsafe r =
let inst = Univ.UContext.instance mib.Declarations.mind_universes in
Inductive.type_of_constructor (cstr,inst) specif
+let type_of_global_in_context env r =
+ let open Declarations in
+ match r with
+ | VarRef id -> Environ.named_type id env, Univ.UContext.empty
+ | ConstRef c ->
+ let cb = Environ.lookup_constant c env in
+ let univs =
+ if cb.const_polymorphic then Future.force cb.const_universes
+ else Univ.UContext.empty
+ in cb.Declarations.const_type, univs
+ | IndRef ind ->
+ let (mib, oib) = Inductive.lookup_mind_specif env ind in
+ let univs =
+ if mib.mind_polymorphic then mib.mind_universes
+ else Univ.UContext.empty
+ in oib.Declarations.mind_arity.Declarations.mind_user_arity, univs
+ | ConstructRef cstr ->
+ let (mib,oib as specif) = Inductive.lookup_mind_specif env (inductive_of_constructor cstr) in
+ let univs =
+ if mib.mind_polymorphic then mib.mind_universes
+ else Univ.UContext.empty
+ in
+ let inst = Univ.UContext.instance univs in
+ Inductive.type_of_constructor (cstr,inst) specif, univs
let is_polymorphic r =
let env = env() in
diff --git a/library/global.mli b/library/global.mli
index b6825ffa5..410be961b 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -108,7 +108,8 @@ val join_safe_environment : unit -> unit
val is_polymorphic : Globnames.global_reference -> bool
-(* val type_of_global : Globnames.global_reference -> types Univ.in_universe_context_set *)
+val type_of_global_in_context : Environ.env ->
+ Globnames.global_reference -> Constr.types Univ.in_universe_context
val type_of_global_unsafe : Globnames.global_reference -> Constr.types
(** {6 Retroknowledge } *)
diff --git a/library/universes.ml b/library/universes.ml
index 79286792d..c7009b400 100644
--- a/library/universes.ml
+++ b/library/universes.ml
@@ -60,7 +60,7 @@ let fresh_instance_from ctx =
let fresh_constant_instance env c =
let cb = lookup_constant c env in
if cb.Declarations.const_polymorphic then
- let (inst,_), ctx = fresh_instance_from (Future.join cb.Declarations.const_universes) in
+ let (inst,_), ctx = fresh_instance_from (Future.force cb.Declarations.const_universes) in
((c, inst), ctx)
else ((c,Instance.empty), ContextSet.empty)
@@ -94,7 +94,20 @@ let fresh_global_instance env gr =
let constr_of_global gr =
let c, ctx = fresh_global_instance (Global.env ()) gr in
- Global.push_context_set ctx; c
+ if not (Univ.ContextSet.is_empty ctx) then
+ if Univ.LSet.is_empty (Univ.ContextSet.levels ctx) then
+ (* Should be an error as we might forget constraints, allow for now
+ to make firstorder work with "using" clauses *)
+ c
+ else raise (Invalid_argument
+ ("constr_of_global: globalization of polymorphic reference " ^
+ Pp.string_of_ppcmds (Nametab.pr_global_env Id.Set.empty gr) ^
+ " would forget universes."))
+ else c
+
+let unsafe_constr_of_global gr =
+ let c, ctx = fresh_global_instance (Global.env ()) gr in
+ c
let constr_of_global_univ (gr,u) =
match gr with
@@ -132,7 +145,7 @@ let type_of_reference env r =
| ConstRef c ->
let cb = Environ.lookup_constant c env in
if cb.const_polymorphic then
- let (inst, subst), ctx = fresh_instance_from (Future.join cb.const_universes) in
+ let (inst, subst), ctx = fresh_instance_from (Future.force cb.const_universes) in
Vars.subst_univs_constr subst cb.const_type, ctx
else cb.const_type, ContextSet.empty
diff --git a/library/universes.mli b/library/universes.mli
index 47876269a..fb662d7a3 100644
--- a/library/universes.mli
+++ b/library/universes.mli
@@ -136,12 +136,19 @@ val normalize_universe_opt_subst : universe_opt_subst ref ->
val normalize_universe_subst : universe_subst ref ->
(universe -> universe)
-(** Create a fresh global in the global environment, shouldn't be done while
- building polymorphic values as the constraints are added to the global
- environment already. *)
+(** Create a fresh global in the global environment, without side effects.
+ BEWARE: this raises an ANOMALY on polymorphic constants/inductives:
+ the constraints should be properly added to an evd.
+ See Evd.fresh_global, Evarutil.new_global, and pf_constr_of_global for
+ the proper way to get a fresh copy of a global reference. *)
val constr_of_global : Globnames.global_reference -> constr
+(** [unsafe_constr_of_global gr] turns [gr] into a constr, works on polymorphic
+ reference by building a "dummy" universe instance that is not recorded
+ anywhere. The constraints are forgotten as well. DO NOT USE in new code. *)
+val unsafe_constr_of_global : Globnames.global_reference -> constr
+
val type_of_global : Globnames.global_reference -> types in_universe_context_set
(** Full universes substitutions into terms *)