Skip to content

Commit 8eeb7cd

Browse files
committed
fix missing occur check (fix #218)
1 parent e067f06 commit 8eeb7cd

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

src/runtime.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,17 @@ exception RestrictionFailure
745745
let occurr_check r1 r2 =
746746
match r1 with
747747
| None -> ()
748-
| Some r1 -> if r1 == r2 then raise RestrictionFailure
748+
| Some r1 ->
749+
(* It may be the case that in `X = Y` where `Y = f X` the term Y has to be
750+
moved/derefd in two steps, eg:
751+
752+
else maux empty_env depth (deref_uv ~from:vardepth ~to_:(from+depth) args t)
753+
754+
here maux carries the r1 = X (the ?avoid), while deref_uv does not, to avoid
755+
occur checking things twice. But deref_uv, if Y contains X, may assign
756+
X to X' (or a x..\ X' x..). If this happend, then r1 is no more a dummy
757+
(unassigned variable) *)
758+
if !!r1 != C.dummy || r1 == r2 then raise RestrictionFailure
749759

750760
let rec make_lambdas destdepth args =
751761
if args = 0 then let x = UVar(oref C.dummy,destdepth,0) in x,x

tests/sources/oc_eta.elpi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
main :-
2+
pi w \ f (y\ X y) w = X w, print X.
3+
4+
type f (A -> A) -> A -> A.

tests/suite/correctness_HO.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,11 @@ let () = declare "hdclause"
299299
~description:"hdclause unification"
300300
~typecheck:false
301301
()
302-
302+
303+
304+
let () = declare "oc_eta"
305+
~source_elpi:"oc_eta.elpi"
306+
~description:"eta expansion and occur check"
307+
~typecheck:true
308+
~expectation:Failure
309+
()

0 commit comments

Comments
 (0)