[project @ 1999-07-16 14:06:57 by simonpj]
authorsimonpj <unknown>
Fri, 16 Jul 1999 14:06:57 +0000 (14:06 +0000)
committersimonpj <unknown>
Fri, 16 Jul 1999 14:06:57 +0000 (14:06 +0000)
* Fix a bug in the unifier that made the typechecker
  loop on a 5-line program from Sigbjorn.  The bug is
  documented near the fix, in

TcUnify.uUnboundVar

ghc/compiler/typecheck/TcUnify.lhs

index 0f037f6..09695e7 100644 (file)
@@ -300,7 +300,26 @@ uUnboundVar swapped tv1 maybe_ty1 ps_ty2 non_var_ty2
     ASSERT( isNotUsgTy ps_ty2 )
     checkTcM (not (isSigTyVar tv1))
             (failWithTcM (unifyWithSigErr tv1 ps_ty2)) `thenTc_`
-    tcPutTyVar tv1 ps_ty2                              `thenNF_Tc_`
+
+    tcPutTyVar tv1 non_var_ty2                         `thenNF_Tc_`
+       -- This used to say "ps_ty2" instead of "non_var_ty2"
+
+       -- But that led to an infinite loop in the type checker!
+       -- Consider 
+       --      type A a = ()
+       --
+       --      f :: (A a -> a -> ()) -> ()
+       --      f = \ _ -> ()
+       --
+       --      x :: ()
+       --      x = f (\ x p -> p x)
+       --
+       -- Here, we try to match "t" with "A t", and succeed
+       -- because the unifier looks through synonyms.  The occurs
+       -- check doesn't kick in because we are "really" binding "t" to "()",
+       -- but we *actually* bind "t" to "A t" if we store ps_ty2.
+       -- That leads the typechecker into an infinite loop later.
+
     returnTc ()
   where
     occur_check ty = mapTc occur_check_tv (varSetElems (tyVarsOfType ty))      `thenTc_`