Midstream changes to deal with spontaneous solving and flatten skolem equivalence...
[ghc-hetmet.git] / compiler / typecheck / TcSMonad.lhs
index 240abc9..a487fe0 100644 (file)
@@ -4,16 +4,18 @@ module TcSMonad (
 
        -- Canonical constraints
     CanonicalCts, emptyCCan, andCCan, andCCans, 
-    singleCCan, extendCCans, isEmptyCCan, isEqCCan, 
-    CanonicalCt(..), Xi, tyVarsOfCanonical, tyVarsOfCanonicals,
+    singleCCan, extendCCans, isEmptyCCan, isTyEqCCan, 
+    CanonicalCt(..), Xi, tyVarsOfCanonical, tyVarsOfCanonicals, tyVarsOfCDicts, 
     mkWantedConstraints, deCanonicaliseWanted, 
-    makeGivens, makeSolved,
+    makeGivens, makeSolvedByInst,
 
-    CtFlavor (..), isWanted, isGiven, isDerived, canRewrite, canSolve,
+    CtFlavor (..), isWanted, isGiven, isDerived, isDerivedSC, isDerivedByInst, 
+    DerivedOrig (..), 
+    canRewrite, canSolve,
     combineCtLoc, mkGivenFlavor,
 
     TcS, runTcS, failTcS, panicTcS, traceTcS, traceTcS0,  -- Basic functionality 
-    tryTcS, nestImplicTcS, wrapErrTcS, wrapWarnTcS,
+    tryTcS, nestImplicTcS, recoverTcS, wrapErrTcS, wrapWarnTcS,
     SimplContext(..), isInteractive, simplEqsOnly, performDefaulting,
        
        -- Creation of evidence variables
@@ -42,7 +44,12 @@ module TcSMonad (
 
     isGoodRecEv,
 
+    zonkTcTypeTcS,                              -- Zonk through the TyBinds of the Tcs Monad
+    compatKind,
+
+
     isTouchableMetaTyVar,
+    isTouchableMetaTyVar_InRange, 
 
     getDefaultInfo, getDynFlags,
 
@@ -141,12 +148,16 @@ data CanonicalCt
   | CTyEqCan {  -- tv ~ xi     (recall xi means function free)
        -- Invariant: 
        --   * tv not in tvs(xi)   (occurs check)
-       --   * If constraint is given then typeKind xi ==  typeKind tv 
+       --   * If constraint is given then typeKind xi `compatKind` typeKind tv 
        --                See Note [Spontaneous solving and kind compatibility] 
+       --   * if xi is a flatten skolem then tv must be a flatten skolem
+       --     i.e. equalities prefer flatten skolems in their LHS. 
+       --                See Note [Loopy Spontaneous Solving, Example 4]
+       --                Also related to [Flatten Skolem Equivalence Classes]
       cc_id     :: EvVar, 
       cc_flavor :: CtFlavor, 
-      cc_tyvar :: TcTyVar, 
-      cc_rhs   :: Xi
+      cc_tyvar  :: TcTyVar, 
+      cc_rhs    :: Xi
     }
 
   | CFunEqCan {  -- F xis ~ xi  
@@ -154,7 +165,7 @@ data CanonicalCt
                  --            * cc_rhs is not a touchable unification variable 
                  --                   See Note [No touchables as FunEq RHS]
                  --            * If constraint is given then 
-                 --                 typeKind (TyConApp cc_fun cc_tyargs) == typeKind cc_rhs
+                 --                 typeKind (TyConApp cc_fun cc_tyargs) `compatKind` typeKind cc_rhs
       cc_id     :: EvVar,
       cc_flavor :: CtFlavor, 
       cc_fun    :: TyCon,      -- A type function
@@ -164,17 +175,20 @@ data CanonicalCt
                    
     }
 
+compatKind :: Kind -> Kind -> Bool 
+compatKind k1 k2 = k1 `isSubKind` k2 || k2 `isSubKind` k1 
+
 makeGivens :: CanonicalCts -> CanonicalCts
 makeGivens = mapBag (\ct -> ct { cc_flavor = mkGivenFlavor (cc_flavor ct) UnkSkol })
           -- The UnkSkol doesn't matter because these givens are
           -- not contradictory (else we'd have rejected them already)
 
-makeSolved :: CanonicalCt -> CanonicalCt
+makeSolvedByInst :: CanonicalCt -> CanonicalCt
 -- Record that a constraint is now solved
 --       Wanted         -> Derived
 --       Given, Derived -> no-op
-makeSolved ct 
-  | Wanted loc <- cc_flavor ct = ct { cc_flavor = Derived loc }
+makeSolvedByInst ct 
+  | Wanted loc <- cc_flavor ct = ct { cc_flavor = Derived loc DerInst }
   | otherwise                  = ct
 
 mkWantedConstraints :: CanonicalCts -> Bag Implication -> WantedConstraints
@@ -193,6 +207,13 @@ tyVarsOfCanonical (CFunEqCan { cc_tyargs = tys, cc_rhs = xi }) = tyVarsOfTypes (
 tyVarsOfCanonical (CDictCan { cc_tyargs = tys })              = tyVarsOfTypes tys
 tyVarsOfCanonical (CIPCan { cc_ip_ty = ty })                  = tyVarsOfType ty
 
+tyVarsOfCDict :: CanonicalCt -> TcTyVarSet 
+tyVarsOfCDict (CDictCan { cc_tyargs = tys }) = tyVarsOfTypes tys
+tyVarsOfCDict _ct                            = emptyVarSet 
+
+tyVarsOfCDicts :: CanonicalCts -> TcTyVarSet 
+tyVarsOfCDicts = foldrBag (unionVarSet . tyVarsOfCDict) emptyVarSet
+
 tyVarsOfCanonicals :: CanonicalCts -> TcTyVarSet
 tyVarsOfCanonicals = foldrBag (unionVarSet . tyVarsOfCanonical) emptyVarSet
 
@@ -225,6 +246,8 @@ variable, is not canonical.  Why?
 
 Hence the invariant.
 
+The invariant is 
+
 Note [Canonical implicit parameter constraints]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The type in a canonical implicit parameter constraint doesn't need to
@@ -255,10 +278,10 @@ emptyCCan = emptyBag
 isEmptyCCan :: CanonicalCts -> Bool
 isEmptyCCan = isEmptyBag
 
-isEqCCan :: CanonicalCt -> Bool 
-isEqCCan (CTyEqCan {})  = True 
-isEqCCan (CFunEqCan {}) = True 
-isEqCCan _              = False 
+isTyEqCCan :: CanonicalCt -> Bool 
+isTyEqCCan (CTyEqCan {})  = True 
+isTyEqCCan (CFunEqCan {}) = False
+isTyEqCCan _              = False 
 
 \end{code}
 
@@ -272,16 +295,21 @@ isEqCCan _              = False
 \begin{code}
 data CtFlavor 
   = Given   GivenLoc  -- We have evidence for this constraint in TcEvBinds
-  | Derived WantedLoc -- We have evidence for this constraint in TcEvBinds;
+  | Derived WantedLoc DerivedOrig
+                      -- We have evidence for this constraint in TcEvBinds;
                       --   *however* this evidence can contain wanteds, so 
                       --   it's valid only provisionally to the solution of
                       --   these wanteds 
   | Wanted WantedLoc  -- We have no evidence bindings for this constraint. 
 
+data DerivedOrig = DerSC | DerInst 
+-- Deriveds are either superclasses of other wanteds or deriveds, or partially 
+-- solved wanteds from instances. 
+
 instance Outputable CtFlavor where 
-  ppr (Given _)   = ptext (sLit "[Given]")
-  ppr (Wanted _)  = ptext (sLit "[Wanted]")
-  ppr (Derived _) = ptext (sLit "[Derived]") 
+  ppr (Given _)    = ptext (sLit "[Given]")
+  ppr (Wanted _)   = ptext (sLit "[Wanted]")
+  ppr (Derived {}) = ptext (sLit "[Derived]") 
 
 isWanted :: CtFlavor -> Bool 
 isWanted (Wanted {}) = True
@@ -295,6 +323,14 @@ isDerived :: CtFlavor -> Bool
 isDerived (Derived {}) = True
 isDerived _            = False
 
+isDerivedSC :: CtFlavor -> Bool 
+isDerivedSC (Derived _ DerSC) = True 
+isDerivedSC _                 = False 
+
+isDerivedByInst :: CtFlavor -> Bool 
+isDerivedByInst (Derived _ DerInst) = True 
+isDerivedByInst _                   = False 
+
 canSolve :: CtFlavor -> CtFlavor -> Bool 
 -- canSolve ctid1 ctid2 
 -- The constraint ctid1 can be used to solve ctid2 
@@ -317,16 +353,16 @@ canRewrite = canSolve
 
 combineCtLoc :: CtFlavor -> CtFlavor -> WantedLoc
 -- Precondition: At least one of them should be wanted 
-combineCtLoc (Wanted loc) _ = loc 
-combineCtLoc _ (Wanted loc) = loc 
-combineCtLoc (Derived loc) _ = loc 
-combineCtLoc _ (Derived loc) = loc 
+combineCtLoc (Wanted loc) _    = loc 
+combineCtLoc _ (Wanted loc)    = loc 
+combineCtLoc (Derived loc _) _ = loc 
+combineCtLoc _ (Derived loc _) = loc 
 combineCtLoc _ _ = panic "combineCtLoc: both given"
 
 mkGivenFlavor :: CtFlavor -> SkolemInfo -> CtFlavor
-mkGivenFlavor (Wanted  loc) sk = Given (setCtLocOrigin loc sk)
-mkGivenFlavor (Derived loc) sk = Given (setCtLocOrigin loc sk)
-mkGivenFlavor (Given   loc) sk = Given (setCtLocOrigin loc sk)
+mkGivenFlavor (Wanted  loc)   sk = Given (setCtLocOrigin loc sk)
+mkGivenFlavor (Derived loc _) sk = Given (setCtLocOrigin loc sk)
+mkGivenFlavor (Given   loc)   sk = Given (setCtLocOrigin loc sk)
 \end{code}
 
 
@@ -468,6 +504,11 @@ nestImplicTcS ref untch (TcS thing_inside)
     in 
     thing_inside nest_env
 
+recoverTcS :: TcS a -> TcS a -> TcS a
+recoverTcS (TcS recovery_code) (TcS thing_inside)
+  = TcS $ \ env ->
+    TcM.recoverM (recovery_code env) (thing_inside env)
+
 ctxtUnderImplic :: SimplContext -> SimplContext
 -- See Note [Simplifying RULE lhs constraints] in TcSimplify
 ctxtUnderImplic SimplRuleLhs = SimplCheck
@@ -585,13 +626,20 @@ pprEq ty1 ty2 = pprPred $ mkEqPred (ty1,ty2)
 
 isTouchableMetaTyVar :: TcTyVar -> TcS Bool
 isTouchableMetaTyVar tv 
-  = case tcTyVarDetails tv of
-      MetaTv TcsTv _ -> return True    -- See Note [Touchable meta type variables]
-      MetaTv {}      -> do { untch <- getUntouchables
-                           ; return (inTouchableRange untch tv) }
-      _              -> return False
+  = do { untch <- getUntouchables
+       ; return $ isTouchableMetaTyVar_InRange untch tv } 
+
+isTouchableMetaTyVar_InRange :: Untouchables -> TcTyVar -> Bool 
+isTouchableMetaTyVar_InRange untch tv 
+  = case tcTyVarDetails tv of 
+      MetaTv TcsTv _ -> True    -- See Note [Touchable meta type variables] 
+      MetaTv {}      -> inTouchableRange untch tv 
+      _              -> False 
+
+
 \end{code}
 
+
 Note [Touchable meta type variables]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Meta type variables allocated *by the constraint solver itself* are always
@@ -631,11 +679,35 @@ instDFunTypes mb_inst_tys
 instDFunConstraints :: TcThetaType -> TcS [EvVar] 
 instDFunConstraints preds = wrapTcS $ TcM.newWantedEvVars preds 
 
-newFlexiTcS :: TyVar -> TcS TcTyVar
--- Make a TcsTv meta tyvar; it is always touchable,
--- but we are supposed to guess its instantiation
--- See Note [Touchable meta type variables]
-newFlexiTcS tv = wrapTcS $ TcM.instMetaTyVar TcsTv tv
+
+-- newFlexiTcS :: TyVar -> TcS TcTyVar
+-- -- Make a TcsTv meta tyvar; it is always touchable,
+-- -- but we are supposed to guess its instantiation
+-- -- See Note [Touchable meta type variables]
+-- newFlexiTcS tv = wrapTcS $ TcM.instMetaTyVar TcsTv tv
+
+newFlexiTcS :: TyVar -> TcS TcTyVar 
+-- Like TcM.instMetaTyVar but the variable that is created is always
+-- touchable; we are supposed to guess its instantiation. 
+-- See Note [Touchable meta type variables] 
+newFlexiTcS tv = newFlexiTcSHelper (tyVarName tv) (tyVarKind tv) 
+
+newKindConstraint :: TcTyVar -> Kind -> TcS (CoVar, Type)  
+-- Create new wanted CoVar that constrains the type to have the specified kind. 
+newKindConstraint tv knd 
+  = do { tv_k <- newFlexiTcSHelper (tyVarName tv) knd 
+       ; let ty_k = mkTyVarTy tv_k
+       ; co_var <- newWantedCoVar (mkTyVarTy tv) ty_k
+       ; return (co_var, ty_k) }
+
+newFlexiTcSHelper :: Name -> Kind -> TcS TcTyVar
+newFlexiTcSHelper tvname tvkind
+  = wrapTcS $ 
+    do { uniq <- TcM.newUnique 
+       ; ref  <- TcM.newMutVar  Flexi 
+       ; let name = setNameUnique tvname uniq 
+             kind = tvkind 
+       ; return (mkTcTyVar name kind (MetaTv TcsTv ref)) }
 
 -- Superclasses and recursive dictionaries 
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -659,8 +731,6 @@ newGivOrDerCoVar ty1 ty2 co
 newWantedCoVar :: TcType -> TcType -> TcS EvVar 
 newWantedCoVar ty1 ty2 =  wrapTcS $ TcM.newWantedCoVar ty1 ty2 
 
-newKindConstraint :: TcType -> Kind -> TcS (CoVar, TcType)
-newKindConstraint ty kind =  wrapTcS $ TcM.newKindConstraint ty kind
 
 newCoVar :: TcType -> TcType -> TcS EvVar 
 newCoVar ty1 ty2 = wrapTcS $ TcM.newCoVar ty1 ty2 
@@ -823,6 +893,20 @@ matchFam tycon args
        }
 
 
+zonkTcTypeTcS :: TcType -> TcS TcType
+-- Zonk through the TyBinds of the Tcs Monad
+zonkTcTypeTcS ty 
+  = do { subst <- getTcSTyBindsMap >>= return . varEnvElts 
+       ; let (dom,rng)  = unzip subst 
+             apply_once = substTyWith dom rng 
+       ; let rng_idemp = [ substTyWith dom rng_idemp (apply_once t) | t <- rng ]
+       ; return (substTyWith dom rng_idemp ty) }
+
+                        
+
+
+
+
 -- Functional dependencies, instantiation of equations
 -------------------------------------------------------