X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcSMonad.lhs;h=5f555c5b3290fc6efd41814d3c53021a4db0cdc1;hb=8657bb00544468adc7ad63e962af71674c3b4500;hp=592009fc2f2217a7ae516615c7641ffe1358f21a;hpb=daa3fb945909feb28d7623aa2a075663d31076f0;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs index 592009f..5f555c5 100644 --- a/compiler/typecheck/TcSMonad.lhs +++ b/compiler/typecheck/TcSMonad.lhs @@ -4,12 +4,14 @@ module TcSMonad ( -- Canonical constraints CanonicalCts, emptyCCan, andCCan, andCCans, - singleCCan, extendCCans, isEmptyCCan, - 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 @@ -43,6 +45,7 @@ module TcSMonad ( isGoodRecEv, isTouchableMetaTyVar, + isTouchableMetaTyVar_InRange, getDefaultInfo, getDynFlags, @@ -169,12 +172,12 @@ makeGivens = mapBag (\ct -> ct { cc_flavor = mkGivenFlavor (cc_flavor ct) UnkSko -- 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 +196,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 @@ -254,6 +264,12 @@ emptyCCan = emptyBag isEmptyCCan :: CanonicalCts -> Bool isEmptyCCan = isEmptyBag + +isTyEqCCan :: CanonicalCt -> Bool +isTyEqCCan (CTyEqCan {}) = True +isTyEqCCan (CFunEqCan {}) = False +isTyEqCCan _ = False + \end{code} %************************************************************************ @@ -266,16 +282,21 @@ isEmptyCCan = isEmptyBag \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 @@ -289,9 +310,23 @@ 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 +-- "to solve" means a reaction where the active parts of the two constraints match. +-- active(F xis ~ xi) = F xis +-- active(tv ~ xi) = tv +-- active(D xis) = D xis +-- active(IP nm ty) = nm +----------------------------------------- canSolve (Given {}) _ = True canSolve (Derived {}) (Wanted {}) = True canSolve (Derived {}) (Derived {}) = True @@ -300,26 +335,21 @@ canSolve _ _ = False canRewrite :: CtFlavor -> CtFlavor -> Bool -- canRewrite ctid1 ctid2 --- The *equality* constraint ctid1 can be used to rewrite inside ctid2 -canRewrite (Given {}) _ = True -canRewrite (Derived {}) (Wanted {}) = True -canRewrite (Derived {}) (Derived {}) = True - -- Never use a wanted to rewrite anything! -canRewrite (Wanted {}) (Wanted {}) = False -canRewrite _ _ = False +-- The *equality_constraint* ctid1 can be used to rewrite inside ctid2 +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} @@ -578,13 +608,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 @@ -624,11 +661,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 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -652,8 +713,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