diff options
Diffstat (limited to 'interp')
| -rw-r--r-- | interp/constrextern.ml | 10 | ||||
| -rw-r--r-- | interp/constrintern.ml | 26 | ||||
| -rw-r--r-- | interp/constrintern.mli | 7 | ||||
| -rw-r--r-- | interp/declare.mli | 5 | ||||
| -rw-r--r-- | interp/genintern.ml | 15 | ||||
| -rw-r--r-- | interp/genintern.mli | 9 | ||||
| -rw-r--r-- | interp/interp.mllib | 2 | ||||
| -rw-r--r-- | interp/modintern.ml | 60 |
8 files changed, 112 insertions, 22 deletions
diff --git a/interp/constrextern.ml b/interp/constrextern.ml index 601099c6ff..838ef40545 100644 --- a/interp/constrextern.ml +++ b/interp/constrextern.ml @@ -480,6 +480,9 @@ and apply_notation_to_pattern ?loc gr ((subst,substlist),(nb_to_drop,more_args)) (make_pat_notation ?loc ntn (l,ll) l2') key) end | SynDefRule kn -> + match availability_of_entry_coercion custom InConstrEntrySomeLevel with + | None -> raise No_match + | Some coercion -> let qid = Nametab.shortest_qualid_of_syndef ?loc vars kn in let l1 = List.rev_map (fun (c,(subentry,(scopt,scl))) -> @@ -493,7 +496,7 @@ and apply_notation_to_pattern ?loc gr ((subst,substlist),(nb_to_drop,more_args)) |None -> raise No_match in assert (List.is_empty substlist); - mkPat ?loc qid (List.rev_append l1 l2') + insert_pat_coercion ?loc coercion (mkPat ?loc qid (List.rev_append l1 l2')) and extern_notation_pattern allscopes vars t = function | [] -> raise No_match | (keyrule,pat,n as _rule)::rules -> @@ -1131,12 +1134,15 @@ and extern_notation (custom,scopes as allscopes) vars t = function binderlists in insert_coercion coercion (insert_delimiters (make_notation loc ntn (l,ll,bl,bll)) key)) | SynDefRule kn -> + match availability_of_entry_coercion custom InConstrEntrySomeLevel with + | None -> raise No_match + | Some coercion -> let l = List.map (fun (c,(subentry,(scopt,scl))) -> extern true (subentry,(scopt,scl@snd scopes)) vars c, None) terms in let a = CRef (Nametab.shortest_qualid_of_syndef ?loc vars kn,None) in - CAst.make ?loc @@ if List.is_empty l then a else CApp ((None, CAst.make a),l) in + insert_coercion coercion (CAst.make ?loc @@ if List.is_empty l then a else CApp ((None, CAst.make a),l)) in if List.is_empty args then e else let args = fill_arg_scopes args argsscopes allscopes in diff --git a/interp/constrintern.ml b/interp/constrintern.ml index c03a5fee90..02db8f6aab 100644 --- a/interp/constrintern.ml +++ b/interp/constrintern.ml @@ -737,7 +737,7 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c = let nenv = {env with tmp_scope; scopes = subscopes @ env.scopes} in try let gc = intern nenv c in - Id.Map.add id (gc, Some c) map + Id.Map.add id (gc, None) map with Nametab.GlobalizationError _ -> map in let mk_env' (c, (onlyident,(tmp_scope,subscopes))) = @@ -2051,15 +2051,22 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c = let (ltacvars, ntnvars) = lvar in (* Preventively declare notation variables in ltac as non-bindings *) Id.Map.iter (fun x (used_as_binder,_,_) -> used_as_binder := false) ntnvars; - let ntnvars = Id.Map.domain ntnvars in let extra = ltacvars.ltac_extra in + (* We inform ltac that the interning vars and the notation vars are bound *) + (* but we could instead rely on the "intern_sign" *) let lvars = Id.Set.union ltacvars.ltac_bound ltacvars.ltac_vars in - let lvars = Id.Set.union lvars ntnvars in + let lvars = Id.Set.union lvars (Id.Map.domain ntnvars) in let ltacvars = Id.Set.union lvars env.ids in + (* Propagating enough information for mutual interning with tac-in-term *) + let intern_sign = { + Genintern.intern_ids = env.ids; + Genintern.notation_variable_status = ntnvars + } in let ist = { Genintern.genv = globalenv; ltacvars; extra; + intern_sign; } in let (_, glb) = Genintern.generic_intern ist gen in Some glb @@ -2344,16 +2351,23 @@ let intern_constr_pattern env sigma ?(as_type=false) ?(ltacvars=empty_ltac_sign) ~pattern_mode:true ~ltacvars env sigma c in pattern_of_glob_constr c +let intern_core kind env sigma ?(pattern_mode=false) ?(ltacvars=empty_ltac_sign) + { Genintern.intern_ids = ids; Genintern.notation_variable_status = vl } c = + let tmp_scope = scope_of_type_kind sigma kind in + let impls = empty_internalization_env in + internalize env {ids; unb = false; tmp_scope; scopes = []; impls} + pattern_mode (ltacvars, vl) c + let interp_notation_constr env ?(impls=empty_internalization_env) nenv a = + let ids = extract_ids env in (* [vl] is intended to remember the scope of the free variables of [a] *) let vl = Id.Map.map (fun typ -> (ref false, ref None, typ)) nenv.ninterp_var_type in let impls = Id.Map.fold (fun id _ impls -> Id.Map.remove id impls) nenv.ninterp_var_type impls in - let c = internalize (Global.env()) {ids = extract_ids env; unb = false; - tmp_scope = None; scopes = []; impls = impls} + let c = internalize env {ids; unb = false; tmp_scope = None; scopes = []; impls} false (empty_ltac_sign, vl) a in + (* Splits variables into those that are binding, bound, or both *) (* Translate and check that [c] has all its free variables bound in [vars] *) let a, reversible = notation_constr_of_glob_constr nenv c in - (* Splits variables into those that are binding, bound, or both *) (* binding and bound *) let out_scope = function None -> None,[] | Some (a,l) -> a,l in let unused = match reversible with NonInjective ids -> ids | _ -> [] in diff --git a/interp/constrintern.mli b/interp/constrintern.mli index dd0944cc48..147a903fe2 100644 --- a/interp/constrintern.mli +++ b/interp/constrintern.mli @@ -185,6 +185,13 @@ val interp_notation_constr : env -> ?impls:internalization_env -> notation_interp_env -> constr_expr -> (bool * subscopes) Id.Map.t * notation_constr * reversibility_status +(** Idem but to glob_constr (weaker check of binders) *) + +val intern_core : typing_constraint -> + env -> evar_map -> ?pattern_mode:bool -> ?ltacvars:ltac_sign -> + Genintern.intern_variable_status -> constr_expr -> + glob_constr + (** Globalization options *) val parsing_explicit : bool ref diff --git a/interp/declare.mli b/interp/declare.mli index 02e73cd66c..468e056909 100644 --- a/interp/declare.mli +++ b/interp/declare.mli @@ -9,7 +9,6 @@ (************************************************************************) open Names -open Libnames open Constr open Entries open Decl_kinds @@ -29,7 +28,7 @@ type section_variable_entry = type variable_declaration = DirPath.t * section_variable_entry * logical_kind -val declare_variable : variable -> variable_declaration -> object_name +val declare_variable : variable -> variable_declaration -> Libobject.object_name (** Declaration of global constructions i.e. Definition/Theorem/Axiom/Parameter/... *) @@ -69,7 +68,7 @@ val set_declare_scheme : (** [declare_mind me] declares a block of inductive types with their constructors in the current section; it returns the path of the whole block and a boolean indicating if it is a primitive record. *) -val declare_mind : mutual_inductive_entry -> object_name * bool +val declare_mind : mutual_inductive_entry -> Libobject.object_name * bool (** Declaration messages *) diff --git a/interp/genintern.ml b/interp/genintern.ml index d9a0db040a..1b736b7977 100644 --- a/interp/genintern.ml +++ b/interp/genintern.ml @@ -14,16 +14,31 @@ open Genarg module Store = Store.Make () +type intern_variable_status = { + intern_ids : Id.Set.t; + notation_variable_status : + (bool ref * Notation_term.subscopes option ref * + Notation_term.notation_var_internalization_type) + Id.Map.t +} + type glob_sign = { ltacvars : Id.Set.t; genv : Environ.env; extra : Store.t; + intern_sign : intern_variable_status; +} + +let empty_intern_sign = { + intern_ids = Id.Set.empty; + notation_variable_status = Id.Map.empty; } let empty_glob_sign env = { ltacvars = Id.Set.empty; genv = env; extra = Store.empty; + intern_sign = empty_intern_sign; } (** In globalize tactics, we need to keep the initial [constr_expr] to recompute diff --git a/interp/genintern.mli b/interp/genintern.mli index f4f064bcac..4100f39029 100644 --- a/interp/genintern.mli +++ b/interp/genintern.mli @@ -14,10 +14,19 @@ open Genarg module Store : Store.S +type intern_variable_status = { + intern_ids : Id.Set.t; + notation_variable_status : + (bool ref * Notation_term.subscopes option ref * + Notation_term.notation_var_internalization_type) + Id.Map.t +} + type glob_sign = { ltacvars : Id.Set.t; genv : Environ.env; extra : Store.t; + intern_sign : intern_variable_status; } val empty_glob_sign : Environ.env -> glob_sign diff --git a/interp/interp.mllib b/interp/interp.mllib index 3668455aeb..aa20bda705 100644 --- a/interp/interp.mllib +++ b/interp/interp.mllib @@ -3,8 +3,8 @@ Genredexpr Redops Tactypes Stdarg -Genintern Notation_term +Genintern Notation_ops Notation Syntax_def diff --git a/interp/modintern.ml b/interp/modintern.ml index c27cc9cc07..51e27299e3 100644 --- a/interp/modintern.ml +++ b/interp/modintern.ml @@ -61,13 +61,52 @@ let lookup_module_or_modtype kind qid = let lookup_module lqid = fst (lookup_module_or_modtype Module lqid) -let transl_with_decl env = function +let lookup_polymorphism env base kind fqid = + let m = match kind with + | Module -> (Environ.lookup_module base env).mod_type + | ModType -> (Environ.lookup_modtype base env).mod_type + | ModAny -> assert false + in + let rec defunctor = function + | NoFunctor m -> m + | MoreFunctor (_,_,m) -> defunctor m + in + let rec aux m fqid = + let open Names in + match fqid with + | [] -> assert false + | [id] -> + let test (lab,obj) = + match Id.equal (Label.to_id lab) id, obj with + | false, _ | _, (SFBmodule _ | SFBmodtype _) -> None + | true, SFBmind mind -> Some (Declareops.inductive_is_polymorphic mind) + | true, SFBconst const -> Some (Declareops.constant_is_polymorphic const) + in + (try CList.find_map test m with Not_found -> false (* error later *)) + | id::rem -> + let next = function + | MoreFunctor _ -> false (* error later *) + | NoFunctor body -> aux body rem + in + let test (lab,obj) = + match Id.equal (Label.to_id lab) id, obj with + | false, _ | _, (SFBconst _ | SFBmind _) -> None + | true, SFBmodule body -> Some (next body.mod_type) + | true, SFBmodtype body -> (* XXX is this valid? If not error later *) + Some (next body.mod_type) + in + (try CList.find_map test m with Not_found -> false (* error later *)) + in + aux (defunctor m) fqid + +let transl_with_decl env base kind = function | CWith_Module ({CAst.v=fqid},qid) -> WithMod (fqid,lookup_module qid), Univ.ContextSet.empty | CWith_Definition ({CAst.v=fqid},udecl,c) -> let sigma, udecl = Constrexpr_ops.interp_univ_decl_opt env udecl in let c, ectx = interp_constr env sigma c in - begin match UState.check_univ_decl ~poly:(Flags.is_universe_polymorphism()) ectx udecl with + let poly = lookup_polymorphism env base kind fqid in + begin match UState.check_univ_decl ~poly ectx udecl with | Entries.Polymorphic_const_entry ctx -> let inst, ctx = Univ.abstract_universes ctx in let c = EConstr.Vars.subst_univs_level_constr (Univ.make_instance_subst inst) c in @@ -86,23 +125,24 @@ let loc_of_module l = l.CAst.loc let rec interp_module_ast env kind m cst = match m with | {CAst.loc;v=CMident qid} -> let (mp,kind) = lookup_module_or_modtype kind qid in - (MEident mp, kind, cst) + (MEident mp, mp, kind, cst) | {CAst.loc;v=CMapply (me1,me2)} -> - let me1',kind1, cst = interp_module_ast env kind me1 cst in - let me2',kind2, cst = interp_module_ast env ModAny me2 cst in + let me1', base, kind1, cst = interp_module_ast env kind me1 cst in + let me2', _, kind2, cst = interp_module_ast env ModAny me2 cst in let mp2 = match me2' with | MEident mp -> mp | _ -> error_application_to_not_path (loc_of_module me2) me2' in if kind2 == ModType then error_application_to_module_type (loc_of_module me2); - (MEapply (me1',mp2), kind1, cst) + (MEapply (me1',mp2), base, kind1, cst) | {CAst.loc;v=CMwith (me,decl)} -> - let me,kind,cst = interp_module_ast env kind me cst in + let me,base,kind,cst = interp_module_ast env kind me cst in if kind == Module then error_incorrect_with_in_module m.CAst.loc; - let decl, cst' = transl_with_decl env decl in + let decl, cst' = transl_with_decl env base kind decl in let cst = Univ.ContextSet.union cst cst' in - (MEwith(me,decl), kind, cst) + (MEwith(me,decl), base, kind, cst) let interp_module_ast env kind m = - interp_module_ast env kind m Univ.ContextSet.empty + let me, _, kind, cst = interp_module_ast env kind m Univ.ContextSet.empty in + me, kind, cst |
