aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Herbelin2014-09-19 10:23:46 +0200
committerHugo Herbelin2014-09-19 10:38:43 +0200
commit0d90ab680abd1f558f1c20b79b66ca6b71864fbf (patch)
tree5fa2cb4c3770ecd802b85cfa9c82c54508d6915a
parent07e4438bd758c2ced8caf09a6961ccd77d84e42b (diff)
Fixing #3641 (loop in e_contextually, introduced in r16525).
-rw-r--r--pretyping/tacred.ml6
-rw-r--r--test-suite/success/change.v7
2 files changed, 12 insertions, 1 deletions
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 39015d89a9..f0d0d45267 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -943,6 +943,8 @@ let matches_head env sigma c t =
| Proj (p, _) -> ConstrMatching.matches env sigma c (mkConst p)
| _ -> raise ConstrMatching.PatternMatchingFailure
+let is_pattern_meta = function Pattern.PMeta _ -> true | _ -> false
+
let e_contextually byhead (occs,c) f env sigma t =
let (nowhere_except_in,locs) = Locusops.convert_occs occs in
let maxocc = List.fold_right max locs 0 in
@@ -960,7 +962,9 @@ let e_contextually byhead (occs,c) f env sigma t =
else not (Int.List.mem !pos locs) in
incr pos;
if ok then
- let subst' = Id.Map.map (traverse envc) subst in
+ let subst' =
+ if is_pattern_meta c then subst
+ else (* progress is ensured *) Id.Map.map (traverse envc) subst in
let evm, t = f subst' env !evd t in
(evd := evm; t)
else if byhead then
diff --git a/test-suite/success/change.v b/test-suite/success/change.v
index 7bed7ecb15..f775f818ab 100644
--- a/test-suite/success/change.v
+++ b/test-suite/success/change.v
@@ -38,3 +38,10 @@ Fail change True with (let (x,a) := ex_intro _ True (eq_refl True) in x).
Fail change True with
match ex_intro _ True (eq_refl True) with ex_intro x _ => x end.
Abort.
+
+(* Check absence of loop in identity substitution (was failing up to
+ Sep 2014, see #3641) *)
+
+Goal True.
+change ?x with x.
+Abort.