Skip to content

Commit 5645bee

Browse files
committed
Move the responsibility of type-checking to the caller for tactic-in-terms.
Instead of taking a type and checking that the inferred type for the expression is correct, we simply pick an optional constraint and return the type directly in the callback. This prevents having to compute type conversion twice in the special case of Ltac2 variable quotations. This should be 1:1 equivalent to the previous code, we are just moving code around.
1 parent 50654a3 commit 5645bee

File tree

5 files changed

+51
-29
lines changed

5 files changed

+51
-29
lines changed

plugins/ltac/tacinterp.ml

+9-3
Original file line numberDiff line numberDiff line change
@@ -2148,16 +2148,22 @@ let interp_redexp env sigma r =
21482148
(* Backwarding recursive needs of tactic glob/interp/eval functions *)
21492149

21502150
let _ =
2151-
let eval lfun poly env sigma ty tac =
2151+
let eval ?loc ~poly env sigma tycon tac =
2152+
let lfun = GlobEnv.lfun env in
21522153
let extra = TacStore.set TacStore.empty f_debug (get_debug ()) in
21532154
let ist = { lfun; poly; extra; } in
21542155
let tac = eval_tactic_ist ist tac in
21552156
(* EJGA: We should also pass the proof name if desired, for now
21562157
poly seems like enough to get reasonable behavior in practice
21572158
*)
21582159
let name = Id.of_string "ltac_gen" in
2159-
let (c, sigma) = Proof.refine_by_tactic ~name ~poly env sigma ty tac in
2160-
(EConstr.of_constr c, sigma)
2160+
let sigma, ty = match tycon with
2161+
| Some ty -> sigma, ty
2162+
| None -> GlobEnv.new_type_evar env sigma ~src:(loc,Evar_kinds.InternalHole)
2163+
in
2164+
let (c, sigma) = Proof.refine_by_tactic ~name ~poly (GlobEnv.renamed_env env) sigma ty tac in
2165+
let j = { Environ.uj_val = EConstr.of_constr c; uj_type = ty } in
2166+
(j, sigma)
21612167
in
21622168
GlobEnv.register_constr_interp0 wit_tactic eval
21632169

pretyping/globEnv.ml

+9-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ let make ~hypnaming env sigma lvar =
5151
}
5252

5353
let env env = env.static_env
54+
let renamed_env env = env.renamed_env
55+
let lfun env = env.lvar.ltac_genargs
5456

5557
let vars_of_env env =
5658
Id.Set.union (Id.Map.domain env.lvar.ltac_genargs) (vars_of_env env.static_env)
@@ -183,10 +185,13 @@ let interp_ltac_variable ?loc typing_fun env sigma id : Evd.evar_map * unsafe_ju
183185

184186
let interp_ltac_id env id = ltac_interp_id env.lvar id
185187

188+
type 'a obj_interp_fun =
189+
?loc:Loc.t -> poly:bool -> t -> Evd.evar_map -> Evardefine.type_constraint ->
190+
'a -> unsafe_judgment * Evd.evar_map
191+
186192
module ConstrInterpObj =
187193
struct
188-
type ('r, 'g, 't) obj =
189-
unbound_ltac_var_map -> bool -> env -> Evd.evar_map -> types -> 'g -> constr * Evd.evar_map
194+
type ('r, 'g, 't) obj = 'g obj_interp_fun
190195
let name = "constr_interp"
191196
let default _ = None
192197
end
@@ -195,8 +200,8 @@ module ConstrInterp = Genarg.Register(ConstrInterpObj)
195200

196201
let register_constr_interp0 = ConstrInterp.register0
197202

198-
let interp_glob_genarg env poly sigma ty arg =
203+
let interp_glob_genarg ?loc ~poly env sigma ty arg =
199204
let open Genarg in
200205
let GenArg (Glbwit tag, arg) = arg in
201206
let interp = ConstrInterp.obj tag in
202-
interp env.lvar.ltac_genargs poly env.renamed_env sigma ty arg
207+
interp ?loc ~poly env sigma ty arg

pretyping/globEnv.mli

+13-8
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,18 @@ open EConstr
1515
open Ltac_pretype
1616
open Evarutil
1717

18+
(** Type of environment extended with naming and ltac interpretation data *)
19+
20+
type t
21+
1822
(** To embed constr in glob_constr *)
1923

24+
type 'a obj_interp_fun =
25+
?loc:Loc.t -> poly:bool -> t -> Evd.evar_map -> Evardefine.type_constraint ->
26+
'a -> unsafe_judgment * Evd.evar_map
27+
2028
val register_constr_interp0 :
21-
('r, 'g, 't) Genarg.genarg_type ->
22-
(unbound_ltac_var_map -> bool -> env -> evar_map -> types -> 'g -> constr * evar_map) -> unit
29+
('r, 'g, 't) Genarg.genarg_type -> 'g obj_interp_fun -> unit
2330

2431
(** {6 Pretyping name management} *)
2532

@@ -32,17 +39,15 @@ val register_constr_interp0 :
3239
variables used to build purely-named evar contexts
3340
*)
3441

35-
(** Type of environment extended with naming and ltac interpretation data *)
36-
37-
type t
38-
3942
(** Build a pretyping environment from an ltac environment *)
4043

4144
val make : hypnaming:naming_mode -> env -> evar_map -> ltac_var_map -> t
4245

4346
(** Export the underlying environment *)
4447

4548
val env : t -> env
49+
val renamed_env : t -> env
50+
val lfun : t -> unbound_ltac_var_map
4651

4752
val vars_of_env : t -> Id.Set.t
4853

@@ -85,5 +90,5 @@ val interp_ltac_id : t -> Id.t -> Id.t
8590
(** Interpreting a generic argument, typically a "ltac:(...)", taking
8691
into account the possible renaming *)
8792

88-
val interp_glob_genarg : t -> bool -> evar_map -> constr ->
89-
Genarg.glob_generic_argument -> constr * evar_map
93+
val interp_glob_genarg : ?loc:Loc.t -> poly:bool -> t -> evar_map -> Evardefine.type_constraint ->
94+
Genarg.glob_generic_argument -> unsafe_judgment * evar_map

pretyping/pretyping.ml

+2-6
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,8 @@ struct
653653
sigma, { uj_val; uj_type }
654654

655655
| Some arg ->
656-
let sigma, ty =
657-
match tycon with
658-
| Some ty -> sigma, ty
659-
| None -> new_type_evar env sigma ~src:(loc,Evar_kinds.InternalHole) in
660-
let c, sigma = GlobEnv.interp_glob_genarg env poly sigma ty arg in
661-
sigma, { uj_val = c; uj_type = ty }
656+
let j, sigma = GlobEnv.interp_glob_genarg ?loc ~poly env sigma tycon arg in
657+
sigma, j
662658

663659
let pretype_rec self (fixkind, names, bl, lar, vdef) =
664660
fun ?loc ~program_mode ~poly resolve_tc tycon env sigma ->

user-contrib/Ltac2/tac2core.ml

+18-8
Original file line numberDiff line numberDiff line change
@@ -1388,24 +1388,34 @@ let () =
13881388
(** Ltac2 in terms *)
13891389

13901390
let () =
1391-
let interp ist poly env sigma concl (ids, tac) =
1391+
let interp ?loc ~poly env sigma tycon (ids, tac) =
13921392
(* Syntax prevents bound notation variables in constr quotations *)
13931393
let () = assert (Id.Set.is_empty ids) in
1394-
let ist = Tac2interp.get_env ist in
1394+
let ist = Tac2interp.get_env @@ GlobEnv.lfun env in
13951395
let tac = Proofview.tclIGNORE (Tac2interp.interp ist tac) in
13961396
let name, poly = Id.of_string "ltac2", poly in
1397-
let c, sigma = Proof.refine_by_tactic ~name ~poly env sigma concl tac in
1398-
(EConstr.of_constr c, sigma)
1397+
let sigma, concl = match tycon with
1398+
| Some ty -> sigma, ty
1399+
| None -> GlobEnv.new_type_evar env sigma ~src:(loc,Evar_kinds.InternalHole)
1400+
in
1401+
let c, sigma = Proof.refine_by_tactic ~name ~poly (GlobEnv.renamed_env env) sigma concl tac in
1402+
let j = { Environ.uj_val = EConstr.of_constr c; Environ.uj_type = concl } in
1403+
(j, sigma)
13991404
in
14001405
GlobEnv.register_constr_interp0 wit_ltac2_constr interp
14011406

14021407
let () =
1403-
let interp ist poly env sigma concl id =
1404-
let ist = Tac2interp.get_env ist in
1408+
let interp ?loc ~poly env sigma tycon id =
1409+
let ist = Tac2interp.get_env @@ GlobEnv.lfun env in
14051410
let c = Id.Map.find id ist.env_ist in
14061411
let c = Value.to_constr c in
1407-
let sigma = Typing.check env sigma c concl in
1408-
(c, sigma)
1412+
let sigma, concl = match tycon with
1413+
| Some ty -> sigma, ty
1414+
| None -> GlobEnv.new_type_evar env sigma ~src:(loc,Evar_kinds.InternalHole)
1415+
in
1416+
let sigma = Typing.check (GlobEnv.renamed_env env) sigma c concl in
1417+
let j = { Environ.uj_val = c; Environ.uj_type = concl } in
1418+
(j, sigma)
14091419
in
14101420
GlobEnv.register_constr_interp0 wit_ltac2_quotation interp
14111421

0 commit comments

Comments
 (0)