@@ -48,10 +48,10 @@ match_unify ctxt env topx topy dont holes =
4848 where
4949 un names (P _ x _) tm
5050 | holeIn env x || x `elem` holes
51− = do sc 1; checkCycle (x, tm)
51+ = do sc 1; checkCycle names (x, tm)
5252 un names tm (P _ y _)
5353 | holeIn env y || y `elem` holes
54− = do sc 1; checkCycle (y, tm)
54+ = do sc 1; checkCycle names (y, tm)
5555 un bnames (V i) (P _ x _)
5656 | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
5757 un bnames (P _ x _) (V i)
@@ -93,11 +93,19 @@ match_unify ctxt env topx topy dont holes =
9393 sc 1
9494 combine bnames as (ns' ++ bs)
9595
96− checkCycle p@(x, P _ _ _) = return [p]
97− checkCycle (x, tm)
98− | not (x `elem` freeNames tm) = return [(x, tm)]
96+ checkCycle ns p@(x, P _ _ _) = return [p]
97+ checkCycle ns (x, tm)
98+ | not (x `elem` freeNames tm) = checkScope ns (x, tm)
9999 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
100100
101+ checkScope ns (x, tm) =
102+ case boundVs (envPos x 0 env) tm of
103+ [] -> return [(x, tm)]
104+ (i:_) -> lift $ tfail (UnifyScope x (fst (ns!!i))
105+ (inst ns tm) (errEnv env))
106+ where inst [] tm = tm
107+ inst ((n, _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
108+
101109notTrivial (x, P _ x' _) = x /= x'
102110notTrivial _ = True
103111
@@ -195,7 +203,7 @@ unify ctxt env topx topy dont holes =
195203-- put (UI s ((tm, topx, topy) : i) f)
196204 then unifyTmpFail xtm tm
197205 else do sc 1
198− checkCycle (x, tm)
206+ checkCycle bnames (x, tm)
199207 | not (injective xtm) && injective tm = unifyFail xtm tm
200208 un' fn bnames tm ytm@(P _ y _)
201209 | holeIn env y || y `elem` holes
@@ -206,7 +214,7 @@ unify ctxt env topx topy dont holes =
206214-- put (UI s ((tm, topx, topy) : i) f)
207215 then unifyTmpFail tm ytm
208216 else do sc 1
209− checkCycle (y, tm)
217+ checkCycle bnames (y, tm)
210218 | not (injective ytm) && injective tm = unifyFail ytm tm
211219 un' fn bnames (V i) (P _ x _)
212220 | fst (bnames!!i) == x || snd (bnames!!i) == x = do sc 1; return []
@@ -398,11 +406,18 @@ unify ctxt env topx topy dont holes =
398406 put (UI s ((binderTy x, binderTy y, env, err) : f))
399407 return [] -- lift $ tfail err
400408
401− checkCycle p@(x, P _ _ _) = return [p]
402− checkCycle (x, tm)
403− | not (x `elem` freeNames tm) = return [(x, tm)]
409+ checkCycle ns p@(x, P _ _ _) = return [p]
410+ checkCycle ns (x, tm)
411+ | not (x `elem` freeNames tm) = checkScope ns (x, tm)
404412 | otherwise = lift $ tfail (InfiniteUnify x tm (errEnv env))
405413
414+ checkScope ns (x, tm) =
415+ case boundVs (envPos x 0 env) tm of
416+ [] -> return [(x, tm)]
417+ (i:_) -> lift $ tfail (UnifyScope x (fst (ns!!i))
418+ (inst ns tm) (errEnv env))
419+ where inst [] tm = tm
420+ inst ((n, _) : ns) tm = inst ns (substV (P Bound n Erased) tm)
406421
407422 combineArgs bnames args = ca [] args where
408423 ca acc [] = return acc
@@ -419,6 +434,20 @@ unify ctxt env topx topy dont holes =
419434 sc 1
420435 combine bnames as (ns' ++ bs)
421436
437+boundVs :: Int -> Term -> [Int]
438+boundVs i (V j) | j <= i = []
439+ | otherwise = [j]
440+boundVs i (Bind n b sc) = boundVs (i + 1) sc
441+boundVs i (App f x) = let fs = boundVs i f
442+ xs = boundVs i x in
443+ nub (fs ++ xs)
444+boundVs i _ = []
445+
446+envPos x i [] = 0
447+envPos x i ((y, _) : ys) | x == y = i
448+ | otherwise = envPos x (i + 1) ys
449+
450+
422451-- If there are any clashes of constructors, deem it unrecoverable, otherwise some
423452-- more work may help.
424453-- FIXME: Depending on how overloading gets used, this may cause problems. Better