aboutsummaryrefslogtreecommitdiffhomepage
path: root/interp
diff options
context:
space:
mode:
Diffstat (limited to 'interp')
-rw-r--r--interp/notation_ops.ml31
1 files changed, 24 insertions, 7 deletions
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 0480a93e2..5fe12e570 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -988,10 +988,18 @@ let add_ldots_var metas = (ldots_var,((None,[]),NtnTypeConstr))::metas
let add_meta_bindinglist x metas = (x,((None,[]),NtnTypeBinderList))::metas
-let glue_letin_with_decls = true
+(* This tells if letins in the middle of binders should be included in
+ the sequence of binders *)
+let glue_inner_letin_with_decls = true
+
+(* This tells if trailing letins (with no further proper binders)
+ should be included in sequence of binders *)
+let glue_trailing_letin_with_decls = false
+
+exception OnlyTrailingLetIns
let match_binderlist match_fun alp metas sigma rest x y iter termin revert =
- let rec aux sigma bl rest =
+ let rec aux trailing_letins sigma bl rest =
try
let metas = add_ldots_var (add_meta_bindinglist y metas) in
let (terms,_,_,binderlists as sigma) = match_fun alp metas sigma rest iter in
@@ -1002,14 +1010,23 @@ let match_binderlist match_fun alp metas sigma rest x y iter termin revert =
let sigma = remove_bindinglist_sigma y (remove_sigma ldots_var sigma) in
(* In case y is bound not only to a binder but also to a term *)
let sigma = remove_sigma y sigma in
- aux sigma (b::bl) rest
+ aux false sigma (b::bl) rest
with No_match ->
match DAst.get rest with
- | GLetIn (na,c,t,rest) when glue_letin_with_decls ->
+ | GLetIn (na,c,t,rest') when glue_inner_letin_with_decls ->
let b = DAst.make ?loc:rest.CAst.loc @@ GLocalDef (na,Explicit (*?*), c,t) in
- aux sigma (b::bl) rest
- | _ -> if not (List.is_empty bl) then bl, rest, sigma else raise No_match in
- let bl,rest,sigma = aux sigma [] rest in
+ (* collect let-in *)
+ (try aux true sigma (b::bl) rest'
+ with OnlyTrailingLetIns
+ when not (trailing_letins && not glue_trailing_letin_with_decls) ->
+ (* renounce to take into account trailing let-ins *)
+ if not (List.is_empty bl) then bl, rest, sigma else raise No_match)
+ | _ ->
+ if trailing_letins && not glue_trailing_letin_with_decls then
+ (* Backtrack to when we tried to glue letins *)
+ raise OnlyTrailingLetIns;
+ if not (List.is_empty bl) then bl, rest, sigma else raise No_match in
+ let bl,rest,sigma = aux false sigma [] rest in
let bl = if revert then List.rev bl else bl in
let alp,sigma = bind_bindinglist_env alp sigma x bl in
match_fun alp metas sigma rest termin