[commit: ghc] master: Fix canIrredPred again (1e0ef82)

git at git.haskell.org git at git.haskell.org
Fri Nov 15 18:49:38 UTC 2013


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/1e0ef8265d67d05e5114310311804b6d51bec7dd/ghc

>---------------------------------------------------------------

commit 1e0ef8265d67d05e5114310311804b6d51bec7dd
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Fri Nov 15 18:47:38 2013 +0000

    Fix canIrredPred again
    
    This follows up the earlier patch to Trac #6068, which I
    obviously hadn't validated properly.


>---------------------------------------------------------------

1e0ef8265d67d05e5114310311804b6d51bec7dd
 compiler/typecheck/TcCanonical.lhs |   33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs
index cc3c042..1850fdf 100644
--- a/compiler/typecheck/TcCanonical.lhs
+++ b/compiler/typecheck/TcCanonical.lhs
@@ -377,22 +377,35 @@ is_improvement_pty ty = go (classifyPredType ty)
 \begin{code}
 canIrred :: CtLoc -> CtEvidence -> TcS StopOrContinue
 -- Precondition: ty not a tuple and no other evidence form
-canIrred d ev
-  = do { let ty = ctEvPred ev
-       ; traceTcS "can_pred" (text "IrredPred = " <+> ppr ty)
-       ; (xi,co) <- flatten d FMFullFlatten ev ty -- co :: xi ~ ty
-       ; mb <- rewriteCtFlavor ev xi co
+canIrred d old_ev
+  = do { let old_ty = ctEvPred old_ev
+       ; traceTcS "can_pred" (text "IrredPred = " <+> ppr old_ty)
+       ; (xi,co) <- flatten d FMFullFlatten old_ev old_ty -- co :: xi ~ old_ty
+       ; mb <- rewriteCtFlavor old_ev xi co
        ; case mb of {
              Nothing     -> return Stop ;
              Just new_ev ->
 
     do { -- Re-classify, in case flattening has improved its shape
        ; case classifyPredType (ctEvPred new_ev) of
-           ClassPred cls tys -> canClassNC d ev cls tys
-           EqPred ty1 ty2    -> canEqNC    d ev ty1 ty2
-           TuplePred tys     -> canTuple   d ev tys
-           IrredPred {}      -> continueWith $
-                                CIrredEvCan { cc_ev = new_ev, cc_loc = d } } } }
+           ClassPred cls tys -> canClassNC d new_ev cls tys
+           TuplePred tys     -> canTuple   d new_ev tys
+           EqPred ty1 ty2
+              | something_changed old_ty ty1 ty2 -> canEqNC d new_ev ty1 ty2
+           _  -> continueWith $
+                 CIrredEvCan { cc_ev = new_ev, cc_loc = d } } } }
+  where
+    -- If the constraint was a kind-mis-matched equality, we must
+    -- retry canEqNC only if something has changed, otherwise we
+    -- get an infinite loop
+    something_changed old_ty new_ty1 new_ty2
+       | EqPred old_ty1 old_ty2 <- classifyPredType old_ty
+       = not (            new_ty1 `eqType`          old_ty1
+              && typeKind new_ty1 `eqKind` typeKind old_ty1
+              &&          new_ty2 `eqType`          old_ty2
+              && typeKind new_ty2 `eqKind` typeKind old_ty2)
+       | otherwise
+       = True
 
 canHole :: CtLoc -> CtEvidence -> OccName -> TcS StopOrContinue
 canHole d ev occ



More information about the ghc-commits mailing list