summaryrefslogtreecommitdiff
path: root/compiler/typecheck/TcCanonical.hs
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2014-12-03 12:46:17 -0600
committerAustin Seipp <austin@well-typed.com>2014-12-03 13:52:28 -0600
commitb57ff272257bba8945b4c9409585b6a1d3bed21b (patch)
tree6325a00222ce1254a3f29c6df3768c63fdf34404 /compiler/typecheck/TcCanonical.hs
parentbafba119387cdba1a84a45b6a4fe616792c94271 (diff)
downloadhaskell-b57ff272257bba8945b4c9409585b6a1d3bed21b.tar.gz
compiler: de-lhs typecheck/
Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'compiler/typecheck/TcCanonical.hs')
-rw-r--r--compiler/typecheck/TcCanonical.hs1027
1 files changed, 1027 insertions, 0 deletions
diff --git a/compiler/typecheck/TcCanonical.hs b/compiler/typecheck/TcCanonical.hs
new file mode 100644
index 0000000000..dc782c124b
--- /dev/null
+++ b/compiler/typecheck/TcCanonical.hs
@@ -0,0 +1,1027 @@
+{-# LANGUAGE CPP #-}
+
+module TcCanonical( canonicalize ) where
+
+#include "HsVersions.h"
+
+import TcRnTypes
+import TcType
+import Type
+import Kind
+import TcFlatten
+import TcSMonad
+import TcEvidence
+import Class
+import TyCon
+import TypeRep
+import Var
+import Name( isSystemName )
+import OccName( OccName )
+import Outputable
+import Control.Monad ( when )
+import DynFlags( DynFlags )
+import VarSet
+
+import Util
+import BasicTypes
+
+{-
+************************************************************************
+* *
+* The Canonicaliser *
+* *
+************************************************************************
+
+Note [Canonicalization]
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Canonicalization converts a flat constraint to a canonical form. It is
+unary (i.e. treats individual constraints one at a time), does not do
+any zonking, but lives in TcS monad because it needs to create fresh
+variables (for flattening) and consult the inerts (for efficiency).
+
+The execution plan for canonicalization is the following:
+
+ 1) Decomposition of equalities happens as necessary until we reach a
+ variable or type family in one side. There is no decomposition step
+ for other forms of constraints.
+
+ 2) If, when we decompose, we discover a variable on the head then we
+ look at inert_eqs from the current inert for a substitution for this
+ variable and contine decomposing. Hence we lazily apply the inert
+ substitution if it is needed.
+
+ 3) If no more decomposition is possible, we deeply apply the substitution
+ from the inert_eqs and continue with flattening.
+
+ 4) During flattening, we examine whether we have already flattened some
+ function application by looking at all the CTyFunEqs with the same
+ function in the inert set. The reason for deeply applying the inert
+ substitution at step (3) is to maximise our chances of matching an
+ already flattened family application in the inert.
+
+The net result is that a constraint coming out of the canonicalization
+phase cannot be rewritten any further from the inerts (but maybe /it/ can
+rewrite an inert or still interact with an inert in a further phase in the
+simplifier.
+
+Note [Caching for canonicals]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Our plan with pre-canonicalization is to be able to solve a constraint
+really fast from existing bindings in TcEvBinds. So one may think that
+the condition (isCNonCanonical) is not necessary. However consider
+the following setup:
+
+InertSet = { [W] d1 : Num t }
+WorkList = { [W] d2 : Num t, [W] c : t ~ Int}
+
+Now, we prioritize equalities, but in our concrete example
+(should_run/mc17.hs) the first (d2) constraint is dealt with first,
+because (t ~ Int) is an equality that only later appears in the
+worklist since it is pulled out from a nested implication
+constraint. So, let's examine what happens:
+
+ - We encounter work item (d2 : Num t)
+
+ - Nothing is yet in EvBinds, so we reach the interaction with inerts
+ and set:
+ d2 := d1
+ and we discard d2 from the worklist. The inert set remains unaffected.
+
+ - Now the equation ([W] c : t ~ Int) is encountered and kicks-out
+ (d1 : Num t) from the inerts. Then that equation gets
+ spontaneously solved, perhaps. We end up with:
+ InertSet : { [G] c : t ~ Int }
+ WorkList : { [W] d1 : Num t}
+
+ - Now we examine (d1), we observe that there is a binding for (Num
+ t) in the evidence binds and we set:
+ d1 := d2
+ and end up in a loop!
+
+Now, the constraints that get kicked out from the inert set are always
+Canonical, so by restricting the use of the pre-canonicalizer to
+NonCanonical constraints we eliminate this danger. Moreover, for
+canonical constraints we already have good caching mechanisms
+(effectively the interaction solver) and we are interested in reducing
+things like superclasses of the same non-canonical constraint being
+generated hence I don't expect us to lose a lot by introducing the
+(isCNonCanonical) restriction.
+
+A similar situation can arise in TcSimplify, at the end of the
+solve_wanteds function, where constraints from the inert set are
+returned as new work -- our substCt ensures however that if they are
+not rewritten by subst, they remain canonical and hence we will not
+attempt to solve them from the EvBinds. If on the other hand they did
+get rewritten and are now non-canonical they will still not match the
+EvBinds, so we are again good.
+-}
+
+-- Top-level canonicalization
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+canonicalize :: Ct -> TcS (StopOrContinue Ct)
+canonicalize ct@(CNonCanonical { cc_ev = ev })
+ = do { traceTcS "canonicalize (non-canonical)" (ppr ct)
+ ; {-# SCC "canEvVar" #-}
+ canEvNC ev }
+
+canonicalize (CDictCan { cc_ev = ev
+ , cc_class = cls
+ , cc_tyargs = xis })
+ = {-# SCC "canClass" #-}
+ canClass ev cls xis -- Do not add any superclasses
+canonicalize (CTyEqCan { cc_ev = ev
+ , cc_tyvar = tv
+ , cc_rhs = xi })
+ = {-# SCC "canEqLeafTyVarEq" #-}
+ canEqTyVar ev NotSwapped tv xi xi
+
+canonicalize (CFunEqCan { cc_ev = ev
+ , cc_fun = fn
+ , cc_tyargs = xis1
+ , cc_fsk = fsk })
+ = {-# SCC "canEqLeafFunEq" #-}
+ canCFunEqCan ev fn xis1 fsk
+
+canonicalize (CIrredEvCan { cc_ev = ev })
+ = canIrred ev
+canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole })
+ = canHole ev occ hole
+
+canEvNC :: CtEvidence -> TcS (StopOrContinue Ct)
+-- Called only for non-canonical EvVars
+canEvNC ev
+ = case classifyPredType (ctEvPred ev) of
+ ClassPred cls tys -> traceTcS "canEvNC:cls" (ppr cls <+> ppr tys) >> canClassNC ev cls tys
+ EqPred ty1 ty2 -> traceTcS "canEvNC:eq" (ppr ty1 $$ ppr ty2) >> canEqNC ev ty1 ty2
+ TuplePred tys -> traceTcS "canEvNC:tup" (ppr tys) >> canTuple ev tys
+ IrredPred {} -> traceTcS "canEvNC:irred" (ppr (ctEvPred ev)) >> canIrred ev
+
+{-
+************************************************************************
+* *
+* Tuple Canonicalization
+* *
+************************************************************************
+-}
+
+canTuple :: CtEvidence -> [PredType] -> TcS (StopOrContinue Ct)
+canTuple ev tys
+ = do { traceTcS "can_pred" (text "TuplePred!")
+ ; let xcomp = EvTupleMk
+ xdecomp x = zipWith (\_ i -> EvTupleSel x i) tys [0..]
+ ; xCtEvidence ev (XEvTerm tys xcomp xdecomp)
+ ; stopWith ev "Decomposed tuple constraint" }
+
+{-
+************************************************************************
+* *
+* Class Canonicalization
+* *
+************************************************************************
+-}
+
+canClass, canClassNC
+ :: CtEvidence
+ -> Class -> [Type] -> TcS (StopOrContinue Ct)
+-- Precondition: EvVar is class evidence
+
+-- The canClassNC version is used on non-canonical constraints
+-- and adds superclasses. The plain canClass version is used
+-- for already-canonical class constraints (but which might have
+-- been subsituted or somthing), and hence do not need superclasses
+
+canClassNC ev cls tys
+ = canClass ev cls tys
+ `andWhenContinue` emitSuperclasses
+
+canClass ev cls tys
+ = do { let fmode = FE { fe_ev = ev, fe_mode = FM_FlattenAll }
+ ; (xis, cos) <- flattenMany fmode tys
+ ; let co = mkTcTyConAppCo Nominal (classTyCon cls) cos
+ xi = mkClassPred cls xis
+ mk_ct new_ev = CDictCan { cc_ev = new_ev
+ , cc_tyargs = xis, cc_class = cls }
+ ; mb <- rewriteEvidence ev xi co
+ ; traceTcS "canClass" (vcat [ ppr ev <+> ppr cls <+> ppr tys
+ , ppr xi, ppr mb ])
+ ; return (fmap mk_ct mb) }
+
+emitSuperclasses :: Ct -> TcS (StopOrContinue Ct)
+emitSuperclasses ct@(CDictCan { cc_ev = ev , cc_tyargs = xis_new, cc_class = cls })
+ -- Add superclasses of this one here, See Note [Adding superclasses].
+ -- But only if we are not simplifying the LHS of a rule.
+ = do { newSCWorkFromFlavored ev cls xis_new
+ -- Arguably we should "seq" the coercions if they are derived,
+ -- as we do below for emit_kind_constraint, to allow errors in
+ -- superclasses to be executed if deferred to runtime!
+ ; continueWith ct }
+emitSuperclasses _ = panic "emit_superclasses of non-class!"
+
+{-
+Note [Adding superclasses]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Since dictionaries are canonicalized only once in their lifetime, the
+place to add their superclasses is canonicalisation (The alternative
+would be to do it during constraint solving, but we'd have to be
+extremely careful to not repeatedly introduced the same superclass in
+our worklist). Here is what we do:
+
+For Givens:
+ We add all their superclasses as Givens.
+
+For Wanteds:
+ Generally speaking we want to be able to add superclasses of
+ wanteds for two reasons:
+
+ (1) Oportunities for improvement. Example:
+ class (a ~ b) => C a b
+ Wanted constraint is: C alpha beta
+ We'd like to simply have C alpha alpha. Similar
+ situations arise in relation to functional dependencies.
+
+ (2) To have minimal constraints to quantify over:
+ For instance, if our wanted constraint is (Eq a, Ord a)
+ we'd only like to quantify over Ord a.
+
+ To deal with (1) above we only add the superclasses of wanteds
+ which may lead to improvement, that is: equality superclasses or
+ superclasses with functional dependencies.
+
+ We deal with (2) completely independently in TcSimplify. See
+ Note [Minimize by SuperClasses] in TcSimplify.
+
+
+ Moreover, in all cases the extra improvement constraints are
+ Derived. Derived constraints have an identity (for now), but
+ we don't do anything with their evidence. For instance they
+ are never used to rewrite other constraints.
+
+ See also [New Wanted Superclass Work] in TcInteract.
+
+
+For Deriveds:
+ We do nothing.
+
+Here's an example that demonstrates why we chose to NOT add
+superclasses during simplification: [Comes from ticket #4497]
+
+ class Num (RealOf t) => Normed t
+ type family RealOf x
+
+Assume the generated wanted constraint is:
+ RealOf e ~ e, Normed e
+If we were to be adding the superclasses during simplification we'd get:
+ Num uf, Normed e, RealOf e ~ e, RealOf e ~ uf
+==>
+ e ~ uf, Num uf, Normed e, RealOf e ~ e
+==> [Spontaneous solve]
+ Num uf, Normed uf, RealOf uf ~ uf
+
+While looks exactly like our original constraint. If we add the superclass again we'd loop.
+By adding superclasses definitely only once, during canonicalisation, this situation can't
+happen.
+-}
+
+newSCWorkFromFlavored :: CtEvidence -> Class -> [Xi] -> TcS ()
+-- Returns superclasses, see Note [Adding superclasses]
+newSCWorkFromFlavored flavor cls xis
+ | isDerived flavor
+ = return () -- Deriveds don't yield more superclasses because we will
+ -- add them transitively in the case of wanteds.
+
+ | isGiven flavor
+ = do { let sc_theta = immSuperClasses cls xis
+ xev_decomp x = zipWith (\_ i -> EvSuperClass x i) sc_theta [0..]
+ xev = XEvTerm { ev_preds = sc_theta
+ , ev_comp = panic "Can't compose for given!"
+ , ev_decomp = xev_decomp }
+ ; xCtEvidence flavor xev }
+
+ | isEmptyVarSet (tyVarsOfTypes xis)
+ = return () -- Wanteds with no variables yield no deriveds.
+ -- See Note [Improvement from Ground Wanteds]
+
+ | otherwise -- Wanted case, just add those SC that can lead to improvement.
+ = do { let sc_rec_theta = transSuperClasses cls xis
+ impr_theta = filter is_improvement_pty sc_rec_theta
+ loc = ctEvLoc flavor
+ ; traceTcS "newSCWork/Derived" $ text "impr_theta =" <+> ppr impr_theta
+ ; mapM_ (emitNewDerived loc) impr_theta }
+
+is_improvement_pty :: PredType -> Bool
+-- Either it's an equality, or has some functional dependency
+is_improvement_pty ty = go (classifyPredType ty)
+ where
+ go (EqPred t1 t2) = not (t1 `tcEqType` t2)
+ go (ClassPred cls _tys) = not $ null fundeps
+ where (_,fundeps) = classTvsFds cls
+ go (TuplePred ts) = any is_improvement_pty ts
+ go (IrredPred {}) = True -- Might have equalities after reduction?
+
+{-
+************************************************************************
+* *
+* Irreducibles canonicalization
+* *
+************************************************************************
+-}
+
+canIrred :: CtEvidence -> TcS (StopOrContinue Ct)
+-- Precondition: ty not a tuple and no other evidence form
+canIrred old_ev
+ = do { let old_ty = ctEvPred old_ev
+ fmode = FE { fe_ev = old_ev, fe_mode = FM_FlattenAll }
+ -- Flatten (F [a]), say, so that it can reduce to Eq a
+ ; traceTcS "can_pred" (text "IrredPred = " <+> ppr old_ty)
+ ; (xi,co) <- flatten fmode old_ty -- co :: xi ~ old_ty
+ ; mb <- rewriteEvidence old_ev xi co
+ ; case mb of {
+ Stop ev s -> return (Stop ev s) ;
+ ContinueWith new_ev ->
+
+ do { -- Re-classify, in case flattening has improved its shape
+ ; case classifyPredType (ctEvPred new_ev) of
+ ClassPred cls tys -> canClassNC new_ev cls tys
+ TuplePred tys -> canTuple new_ev tys
+ EqPred ty1 ty2 -> canEqNC new_ev ty1 ty2
+ _ -> continueWith $
+ CIrredEvCan { cc_ev = new_ev } } } }
+
+canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct)
+canHole ev occ hole_sort
+ = do { let ty = ctEvPred ev
+ fmode = FE { fe_ev = ev, fe_mode = FM_SubstOnly }
+ ; (xi,co) <- flatten fmode ty -- co :: xi ~ ty
+ ; mb <- rewriteEvidence ev xi co
+ ; case mb of
+ ContinueWith new_ev -> do { emitInsoluble (CHoleCan { cc_ev = new_ev
+ , cc_occ = occ
+ , cc_hole = hole_sort })
+ ; stopWith new_ev "Emit insoluble hole" }
+ Stop ev s -> return (Stop ev s) } -- Found a cached copy; won't happen
+
+{-
+************************************************************************
+* *
+* Equalities
+* *
+************************************************************************
+-}
+
+canEqNC :: CtEvidence -> Type -> Type -> TcS (StopOrContinue Ct)
+canEqNC ev ty1 ty2 = can_eq_nc ev ty1 ty1 ty2 ty2
+
+can_eq_nc, can_eq_nc'
+ :: CtEvidence
+ -> Type -> Type -- LHS, after and before type-synonym expansion, resp
+ -> Type -> Type -- RHS, after and before type-synonym expansion, resp
+ -> TcS (StopOrContinue Ct)
+
+can_eq_nc ev ty1 ps_ty1 ty2 ps_ty2
+ = do { traceTcS "can_eq_nc" $
+ vcat [ ppr ev, ppr ty1, ppr ps_ty1, ppr ty2, ppr ps_ty2 ]
+ ; can_eq_nc' ev ty1 ps_ty1 ty2 ps_ty2 }
+
+-- Expand synonyms first; see Note [Type synonyms and canonicalization]
+can_eq_nc' ev ty1 ps_ty1 ty2 ps_ty2
+ | Just ty1' <- tcView ty1 = can_eq_nc ev ty1' ps_ty1 ty2 ps_ty2
+ | Just ty2' <- tcView ty2 = can_eq_nc ev ty1 ps_ty1 ty2' ps_ty2
+
+-- Type family on LHS or RHS take priority over tyvars,
+-- so that tv ~ F ty gets flattened
+-- Otherwise F a ~ F a might not get solved!
+can_eq_nc' ev (TyConApp fn1 tys1) _ ty2 ps_ty2
+ | isTypeFamilyTyCon fn1 = can_eq_fam_nc ev NotSwapped fn1 tys1 ty2 ps_ty2
+can_eq_nc' ev ty1 ps_ty1 (TyConApp fn2 tys2) _
+ | isTypeFamilyTyCon fn2 = can_eq_fam_nc ev IsSwapped fn2 tys2 ty1 ps_ty1
+
+-- Type variable on LHS or RHS are next
+can_eq_nc' ev (TyVarTy tv1) _ ty2 ps_ty2
+ = canEqTyVar ev NotSwapped tv1 ty2 ps_ty2
+can_eq_nc' ev ty1 ps_ty1 (TyVarTy tv2) _
+ = canEqTyVar ev IsSwapped tv2 ty1 ps_ty1
+
+----------------------
+-- Otherwise try to decompose
+----------------------
+
+-- Literals
+can_eq_nc' ev ty1@(LitTy l1) _ (LitTy l2) _
+ | l1 == l2
+ = do { when (isWanted ev) $
+ setEvBind (ctev_evar ev) (EvCoercion (mkTcNomReflCo ty1))
+ ; stopWith ev "Equal LitTy" }
+
+-- Decomposable type constructor applications
+-- Synonyms and type functions (which are not decomposable)
+-- have already been dealt with
+can_eq_nc' ev (TyConApp tc1 tys1) _ (TyConApp tc2 tys2) _
+ | isDecomposableTyCon tc1
+ , isDecomposableTyCon tc2
+ = canDecomposableTyConApp ev tc1 tys1 tc2 tys2
+
+can_eq_nc' ev (TyConApp tc1 _) ps_ty1 (FunTy {}) ps_ty2
+ | isDecomposableTyCon tc1
+ -- The guard is important
+ -- e.g. (x -> y) ~ (F x y) where F has arity 1
+ -- should not fail, but get the app/app case
+ = canEqFailure ev ps_ty1 ps_ty2
+
+can_eq_nc' ev (FunTy s1 t1) _ (FunTy s2 t2) _
+ = canDecomposableTyConAppOK ev funTyCon [s1,t1] [s2,t2]
+
+can_eq_nc' ev (FunTy {}) ps_ty1 (TyConApp tc2 _) ps_ty2
+ | isDecomposableTyCon tc2
+ = canEqFailure ev ps_ty1 ps_ty2
+
+can_eq_nc' ev s1@(ForAllTy {}) _ s2@(ForAllTy {}) _
+ | CtWanted { ctev_loc = loc, ctev_evar = orig_ev } <- ev
+ = do { let (tvs1,body1) = tcSplitForAllTys s1
+ (tvs2,body2) = tcSplitForAllTys s2
+ ; if not (equalLength tvs1 tvs2) then
+ canEqFailure ev s1 s2
+ else
+ do { traceTcS "Creating implication for polytype equality" $ ppr ev
+ ; ev_term <- deferTcSForAllEq Nominal loc (tvs1,body1) (tvs2,body2)
+ ; setEvBind orig_ev ev_term
+ ; stopWith ev "Deferred polytype equality" } }
+ | otherwise
+ = do { traceTcS "Ommitting decomposition of given polytype equality" $
+ pprEq s1 s2 -- See Note [Do not decompose given polytype equalities]
+ ; stopWith ev "Discard given polytype equality" }
+
+can_eq_nc' ev (AppTy s1 t1) ps_ty1 ty2 ps_ty2
+ = can_eq_app ev NotSwapped s1 t1 ps_ty1 ty2 ps_ty2
+can_eq_nc' ev ty1 ps_ty1 (AppTy s2 t2) ps_ty2
+ = can_eq_app ev IsSwapped s2 t2 ps_ty2 ty1 ps_ty1
+
+-- Everything else is a definite type error, eg LitTy ~ TyConApp
+can_eq_nc' ev _ ps_ty1 _ ps_ty2
+ = canEqFailure ev ps_ty1 ps_ty2
+
+------------
+can_eq_fam_nc :: CtEvidence -> SwapFlag
+ -> TyCon -> [TcType]
+ -> TcType -> TcType
+ -> TcS (StopOrContinue Ct)
+-- Canonicalise a non-canonical equality of form (F tys ~ ty)
+-- or the swapped version thereof
+-- Flatten both sides and go round again
+can_eq_fam_nc ev swapped fn tys rhs ps_rhs
+ = do { let fmode = FE { fe_ev = ev, fe_mode = FM_FlattenAll }
+ ; (xi_lhs, co_lhs) <- flattenFamApp fmode fn tys
+ ; mb_ct <- rewriteEqEvidence ev swapped xi_lhs rhs co_lhs (mkTcNomReflCo rhs)
+ ; case mb_ct of
+ Stop ev s -> return (Stop ev s)
+ ContinueWith new_ev -> can_eq_nc new_ev xi_lhs xi_lhs rhs ps_rhs }
+
+------------
+can_eq_app, can_eq_flat_app
+ :: CtEvidence -> SwapFlag
+ -> Type -> Type -> Type -- LHS (s1 t2), after and before type-synonym expansion, resp
+ -> Type -> Type -- RHS (ty2), after and before type-synonym expansion, resp
+ -> TcS (StopOrContinue Ct)
+-- See Note [Canonicalising type applications]
+can_eq_app ev swapped s1 t1 ps_ty1 ty2 ps_ty2
+ = do { traceTcS "can_eq_app 1" $
+ vcat [ ppr ev, ppr swapped, ppr s1, ppr t1, ppr ty2 ]
+ ; let fmode = FE { fe_ev = ev, fe_mode = FM_FlattenAll }
+ ; (xi_s1, co_s1) <- flatten fmode s1
+ ; traceTcS "can_eq_app 2" $ vcat [ ppr ev, ppr xi_s1 ]
+ ; if s1 `tcEqType` xi_s1
+ then can_eq_flat_app ev swapped s1 t1 ps_ty1 ty2 ps_ty2
+ else
+ do { (xi_t1, co_t1) <- flatten fmode t1
+ -- We flatten t1 as well so that (xi_s1 xi_t1) is well-kinded
+ -- If we form (xi_s1 t1) that might (appear) ill-kinded,
+ -- and then crash in a call to typeKind
+ ; let xi1 = mkAppTy xi_s1 xi_t1
+ co1 = mkTcAppCo co_s1 co_t1
+ ; traceTcS "can_eq_app 3" $ vcat [ ppr ev, ppr xi1, ppr co1 ]
+ ; mb_ct <- rewriteEqEvidence ev swapped xi1 ps_ty2
+ co1 (mkTcNomReflCo ps_ty2)
+ ; traceTcS "can_eq_app 4" $ vcat [ ppr ev, ppr xi1, ppr co1 ]
+ ; case mb_ct of
+ Stop ev s -> return (Stop ev s)
+ ContinueWith new_ev -> can_eq_nc new_ev xi1 xi1 ty2 ps_ty2 }}
+
+-- Preconditions: s1 is already flattened
+-- ty2 is not a type variable, so flattening
+-- can't turn it into an application if it
+-- doesn't look like one already
+-- See Note [Canonicalising type applications]
+can_eq_flat_app ev swapped s1 t1 ps_ty1 ty2 ps_ty2
+ | Just (s2,t2) <- tcSplitAppTy_maybe ty2
+ = unSwap swapped decompose_it (s1,t1) (s2,t2)
+ | otherwise
+ = unSwap swapped (canEqFailure ev) ps_ty1 ps_ty2
+ where
+ decompose_it (s1,t1) (s2,t2)
+ = do { let xevcomp [x,y] = EvCoercion (mkTcAppCo (evTermCoercion x) (evTermCoercion y))
+ xevcomp _ = error "canEqAppTy: can't happen" -- Can't happen
+ xevdecomp x = let xco = evTermCoercion x
+ in [ EvCoercion (mkTcLRCo CLeft xco)
+ , EvCoercion (mkTcLRCo CRight xco)]
+ ; xCtEvidence ev (XEvTerm [mkTcEqPred s1 s2, mkTcEqPred t1 t2] xevcomp xevdecomp)
+ ; stopWith ev "Decomposed AppTy" }
+
+
+------------------------
+canDecomposableTyConApp :: CtEvidence
+ -> TyCon -> [TcType]
+ -> TyCon -> [TcType]
+ -> TcS (StopOrContinue Ct)
+canDecomposableTyConApp ev tc1 tys1 tc2 tys2
+ | tc1 /= tc2 || length tys1 /= length tys2
+ -- Fail straight away for better error messages
+ = canEqFailure ev (mkTyConApp tc1 tys1) (mkTyConApp tc2 tys2)
+ | otherwise
+ = do { traceTcS "canDecomposableTyConApp" (ppr ev $$ ppr tc1 $$ ppr tys1 $$ ppr tys2)
+ ; canDecomposableTyConAppOK ev tc1 tys1 tys2 }
+
+canDecomposableTyConAppOK :: CtEvidence
+ -> TyCon -> [TcType] -> [TcType]
+ -> TcS (StopOrContinue Ct)
+
+canDecomposableTyConAppOK ev tc1 tys1 tys2
+ = do { let xcomp xs = EvCoercion (mkTcTyConAppCo Nominal tc1 (map evTermCoercion xs))
+ xdecomp x = zipWith (\_ i -> EvCoercion $ mkTcNthCo i (evTermCoercion x)) tys1 [0..]
+ xev = XEvTerm (zipWith mkTcEqPred tys1 tys2) xcomp xdecomp
+ ; xCtEvidence ev xev
+ ; stopWith ev "Decomposed TyConApp" }
+
+canEqFailure :: CtEvidence -> TcType -> TcType -> TcS (StopOrContinue Ct)
+-- See Note [Make sure that insolubles are fully rewritten]
+canEqFailure ev ty1 ty2
+ = do { let fmode = FE { fe_ev = ev, fe_mode = FM_SubstOnly }
+ ; (s1, co1) <- flatten fmode ty1
+ ; (s2, co2) <- flatten fmode ty2
+ ; mb_ct <- rewriteEqEvidence ev NotSwapped s1 s2 co1 co2
+ ; case mb_ct of
+ ContinueWith new_ev -> do { emitInsoluble (mkNonCanonical new_ev)
+ ; stopWith new_ev "Definitely not equal" }
+ Stop ev s -> pprPanic "canEqFailure" (s $$ ppr ev $$ ppr ty1 $$ ppr ty2) }
+
+{-
+Note [Canonicalising type applications]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Given (s1 t1) ~ ty2, how should we proceed?
+The simple things is to see if ty2 is of form (s2 t2), and
+decompose. By this time s1 and s2 can't be saturated type
+function applications, because those have been dealt with
+by an earlier equation in can_eq_nc, so it is always sound to
+decompose.
+
+However, over-eager decomposition gives bad error messages
+for things like
+ a b ~ Maybe c
+ e f ~ p -> q
+Suppose (in the first example) we already know a~Array. Then if we
+decompose the application eagerly, yielding
+ a ~ Maybe
+ b ~ c
+we get an error "Can't match Array ~ Maybe",
+but we'd prefer to get "Can't match Array b ~ Maybe c".
+
+So instead can_eq_app flattens s1. If flattening does something, it
+rewrites, and goes round can_eq_nc again. If flattening
+does nothing, then (at least with our present state of knowledge)
+we can only decompose, and that is what can_eq_flat_app attempts
+to do.
+
+Note [Make sure that insolubles are fully rewritten]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When an equality fails, we still want to rewrite the equality
+all the way down, so that it accurately reflects
+ (a) the mutable reference substitution in force at start of solving
+ (b) any ty-binds in force at this point in solving
+See Note [Kick out insolubles] in TcInteract.
+And if we don't do this there is a bad danger that
+TcSimplify.applyTyVarDefaulting will find a variable
+that has in fact been substituted.
+
+Note [Do not decompose Given polytype equalities]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider [G] (forall a. t1 ~ forall a. t2). Can we decompose this?
+No -- what would the evidence look like? So instead we simply discard
+this given evidence.
+
+
+Note [Combining insoluble constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As this point we have an insoluble constraint, like Int~Bool.
+
+ * If it is Wanted, delete it from the cache, so that subsequent
+ Int~Bool constraints give rise to separate error messages
+
+ * But if it is Derived, DO NOT delete from cache. A class constraint
+ may get kicked out of the inert set, and then have its functional
+ dependency Derived constraints generated a second time. In that
+ case we don't want to get two (or more) error messages by
+ generating two (or more) insoluble fundep constraints from the same
+ class constraint.
+-}
+
+canCFunEqCan :: CtEvidence
+ -> TyCon -> [TcType] -- LHS
+ -> TcTyVar -- RHS
+ -> TcS (StopOrContinue Ct)
+-- ^ Canonicalise a CFunEqCan. We know that
+-- the arg types are already flat,
+-- and the RHS is a fsk, which we must *not* substitute.
+-- So just substitute in the LHS
+canCFunEqCan ev fn tys fsk
+ = do { let fmode = FE { fe_ev = ev, fe_mode = FM_FlattenAll }
+ ; (tys', cos) <- flattenMany fmode tys
+ -- cos :: tys' ~ tys
+ ; let lhs_co = mkTcTyConAppCo Nominal fn cos
+ -- :: F tys' ~ F tys
+ new_lhs = mkTyConApp fn tys'
+ fsk_ty = mkTyVarTy fsk
+ ; mb_ev <- rewriteEqEvidence ev NotSwapped new_lhs fsk_ty
+ lhs_co (mkTcNomReflCo fsk_ty)
+ ; case mb_ev of {
+ Stop ev s -> return (Stop ev s) ;
+ ContinueWith ev' ->
+
+ do { extendFlatCache fn tys' (ctEvCoercion ev', fsk)
+ ; continueWith (CFunEqCan { cc_ev = ev', cc_fun = fn
+ , cc_tyargs = tys', cc_fsk = fsk }) } } }
+
+---------------------
+canEqTyVar :: CtEvidence -> SwapFlag
+ -> TcTyVar
+ -> TcType -> TcType
+ -> TcS (StopOrContinue Ct)
+-- A TyVar on LHS, but so far un-zonked
+canEqTyVar ev swapped tv1 ty2 ps_ty2 -- ev :: tv ~ s2
+ = do { traceTcS "canEqTyVar" (ppr tv1 $$ ppr ty2 $$ ppr swapped)
+ ; mb_yes <- flattenTyVarOuter ev tv1
+ ; case mb_yes of
+ Right (ty1, co1, _) -- co1 :: ty1 ~ tv1
+ -> do { mb <- rewriteEqEvidence ev swapped ty1 ps_ty2
+ co1 (mkTcNomReflCo ps_ty2)
+ ; traceTcS "canEqTyVar2" (vcat [ppr tv1, ppr ty2, ppr swapped, ppr ty1,
+ ppUnless (isDerived ev) (ppr co1)])
+ ; case mb of
+ Stop ev s -> return (Stop ev s)
+ ContinueWith new_ev -> can_eq_nc new_ev ty1 ty1 ty2 ps_ty2 }
+
+ Left tv1' -> do { -- FM_Avoid commented out: see Note [Lazy flattening] in TcFlatten
+ -- let fmode = FE { fe_ev = ev, fe_mode = FM_Avoid tv1' True }
+ -- Flatten the RHS less vigorously, to avoid gratuitous flattening
+ -- True <=> xi2 should not itself be a type-function application
+ let fmode = FE { fe_ev = ev, fe_mode = FM_FlattenAll }
+ ; (xi2, co2) <- flatten fmode ps_ty2 -- co2 :: xi2 ~ ps_ty2
+ -- Use ps_ty2 to preserve type synonyms if poss
+ ; dflags <- getDynFlags
+ ; canEqTyVar2 dflags ev swapped tv1' xi2 co2 } }
+
+canEqTyVar2 :: DynFlags
+ -> CtEvidence -- olhs ~ orhs (or, if swapped, orhs ~ olhs)
+ -> SwapFlag
+ -> TcTyVar -- olhs
+ -> TcType -- nrhs
+ -> TcCoercion -- nrhs ~ orhs
+ -> TcS (StopOrContinue Ct)
+-- LHS is an inert type variable,
+-- and RHS is fully rewritten, but with type synonyms
+-- preserved as much as possible
+
+canEqTyVar2 dflags ev swapped tv1 xi2 co2
+ | Just tv2 <- getTyVar_maybe xi2
+ = canEqTyVarTyVar ev swapped tv1 tv2 co2
+
+ | OC_OK xi2' <- occurCheckExpand dflags tv1 xi2 -- No occurs check
+ = do { mb <- rewriteEqEvidence ev swapped xi1 xi2' co1 co2
+ -- Ensure that the new goal has enough type synonyms
+ -- expanded by the occurCheckExpand; hence using xi2' here
+ -- See Note [occurCheckExpand]
+
+ ; let k1 = tyVarKind tv1
+ k2 = typeKind xi2'
+ ; case mb of
+ Stop ev s -> return (Stop ev s)
+ ContinueWith new_ev
+ | k2 `isSubKind` k1
+ -- Establish CTyEqCan kind invariant
+ -- Reorientation has done its best, but the kinds might
+ -- simply be incompatible
+ -> continueWith (CTyEqCan { cc_ev = new_ev
+ , cc_tyvar = tv1, cc_rhs = xi2' })
+ | otherwise
+ -> incompatibleKind new_ev xi1 k1 xi2' k2 }
+
+ | otherwise -- Occurs check error
+ = do { mb <- rewriteEqEvidence ev swapped xi1 xi2 co1 co2
+ ; case mb of
+ Stop ev s -> return (Stop ev s)
+ ContinueWith new_ev -> do { emitInsoluble (mkNonCanonical new_ev)
+ -- If we have a ~ [a], it is not canonical, and in particular
+ -- we don't want to rewrite existing inerts with it, otherwise
+ -- we'd risk divergence in the constraint solver
+ ; stopWith new_ev "Occurs check" } }
+ where
+ xi1 = mkTyVarTy tv1
+ co1 = mkTcNomReflCo xi1
+
+
+
+canEqTyVarTyVar :: CtEvidence -- tv1 ~ orhs (or orhs ~ tv1, if swapped)
+ -> SwapFlag
+ -> TcTyVar -> TcTyVar -- tv2, tv2
+ -> TcCoercion -- tv2 ~ orhs
+ -> TcS (StopOrContinue Ct)
+-- Both LHS and RHS rewrote to a type variable,
+-- If swapped = NotSwapped, then
+-- rw_orhs = tv1, rw_olhs = orhs
+-- rw_nlhs = tv2, rw_nrhs = xi1
+-- See Note [Canonical orientation for tyvar/tyvar equality constraints]
+canEqTyVarTyVar ev swapped tv1 tv2 co2
+ | tv1 == tv2
+ = do { when (isWanted ev) $
+ ASSERT( tcCoercionRole co2 == Nominal )
+ setEvBind (ctev_evar ev) (EvCoercion (maybeSym swapped co2))
+ ; stopWith ev "Equal tyvars" }
+
+ | incompat_kind = incompat
+ | isFmvTyVar tv1 = do_fmv swapped tv1 xi1 xi2 co1 co2
+ | isFmvTyVar tv2 = do_fmv (flipSwap swapped) tv2 xi2 xi1 co2 co1
+ | same_kind = if swap_over then do_swap else no_swap
+ | k1_sub_k2 = do_swap -- Note [Kind orientation for CTyEqCan]
+ | otherwise = no_swap -- k2_sub_k1
+ where
+ xi1 = mkTyVarTy tv1
+ xi2 = mkTyVarTy tv2
+ k1 = tyVarKind tv1
+ k2 = tyVarKind tv2
+ co1 = mkTcNomReflCo xi1
+ k1_sub_k2 = k1 `isSubKind` k2
+ k2_sub_k1 = k2 `isSubKind` k1
+ same_kind = k1_sub_k2 && k2_sub_k1
+ incompat_kind = not (k1_sub_k2 || k2_sub_k1)
+
+ no_swap = canon_eq swapped tv1 xi1 xi2 co1 co2
+ do_swap = canon_eq (flipSwap swapped) tv2 xi2 xi1 co2 co1
+
+ canon_eq swapped tv1 xi1 xi2 co1 co2
+ -- ev : tv1 ~ orhs (not swapped) or orhs ~ tv1 (swapped)
+ -- co1 : xi1 ~ tv1
+ -- co2 : xi2 ~ tv2
+ = do { mb <- rewriteEqEvidence ev swapped xi1 xi2 co1 co2
+ ; let mk_ct ev' = CTyEqCan { cc_ev = ev', cc_tyvar = tv1, cc_rhs = xi2 }
+ ; return (fmap mk_ct mb) }
+
+ -- See Note [Orient equalities with flatten-meta-vars on the left] in TcFlatten
+ do_fmv swapped tv1 xi1 xi2 co1 co2
+ | same_kind
+ = canon_eq swapped tv1 xi1 xi2 co1 co2
+ | otherwise -- Presumably tv1 `subKind` tv2, which is the wrong way round
+ = ASSERT2( k1_sub_k2, ppr tv1 $$ ppr tv2 )
+ ASSERT2( isWanted ev, ppr ev ) -- Only wanteds have flatten meta-vars
+ do { tv_ty <- newFlexiTcSTy (tyVarKind tv1)
+ ; new_ev <- newWantedEvVarNC (ctEvLoc ev) (mkTcEqPred tv_ty xi2)
+ ; emitWorkNC [new_ev]
+ ; canon_eq swapped tv1 xi1 tv_ty co1 (ctEvCoercion new_ev `mkTcTransCo` co2) }
+
+ incompat
+ = do { mb <- rewriteEqEvidence ev swapped xi1 xi2 (mkTcNomReflCo xi1) co2
+ ; case mb of
+ Stop ev s -> return (Stop ev s)
+ ContinueWith ev' -> incompatibleKind ev' xi1 k1 xi2 k2 }
+
+ swap_over
+ -- If tv1 is touchable, swap only if tv2 is also
+ -- touchable and it's strictly better to update the latter
+ -- But see Note [Avoid unnecessary swaps]
+ | Just lvl1 <- metaTyVarTcLevel_maybe tv1
+ = case metaTyVarTcLevel_maybe tv2 of
+ Nothing -> False
+ Just lvl2 | lvl2 `strictlyDeeperThan` lvl1 -> True
+ | lvl1 `strictlyDeeperThan` lvl2 -> False
+ | otherwise -> nicer_to_update_tv2
+
+ -- So tv1 is not a meta tyvar
+ -- If only one is a meta tyvar, put it on the left
+ -- This is not because it'll be solved; but becuase
+ -- the floating step looks for meta tyvars on the left
+ | isMetaTyVar tv2 = True
+
+ -- So neither is a meta tyvar
+
+ -- If only one is a flatten tyvar, put it on the left
+ -- See Note [Eliminate flat-skols]
+ | not (isFlattenTyVar tv1), isFlattenTyVar tv2 = True
+
+ | otherwise = False
+
+ nicer_to_update_tv2
+ = (isSigTyVar tv1 && not (isSigTyVar tv2))
+ || (isSystemName (Var.varName tv2) && not (isSystemName (Var.varName tv1)))
+
+incompatibleKind :: CtEvidence -- t1~t2
+ -> TcType -> TcKind
+ -> TcType -> TcKind -- s1~s2, flattened and zonked
+ -> TcS (StopOrContinue Ct)
+-- LHS and RHS have incompatible kinds, so emit an "irreducible" constraint
+-- CIrredEvCan (NOT CTyEqCan or CFunEqCan)
+-- for the type equality; and continue with the kind equality constraint.
+-- When the latter is solved, it'll kick out the irreducible equality for
+-- a second attempt at solving
+--
+-- See Note [Equalities with incompatible kinds]
+
+incompatibleKind new_ev s1 k1 s2 k2 -- See Note [Equalities with incompatible kinds]
+ = ASSERT( isKind k1 && isKind k2 )
+ do { traceTcS "canEqLeaf: incompatible kinds" (vcat [ppr k1, ppr k2])
+
+ -- Create a derived kind-equality, and solve it
+ ; emitNewDerived kind_co_loc (mkTcEqPred k1 k2)
+
+ -- Put the not-currently-soluble thing into the inert set
+ ; continueWith (CIrredEvCan { cc_ev = new_ev }) }
+ where
+ loc = ctEvLoc new_ev
+ kind_co_loc = setCtLocOrigin loc (KindEqOrigin s1 s2 (ctLocOrigin loc))
+
+{-
+Note [Canonical orientation for tyvar/tyvar equality constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When we have a ~ b where both 'a' and 'b' are TcTyVars, which way
+round should be oriented in the CTyEqCan? The rules, implemented by
+canEqTyVarTyVar, are these
+
+ * If either is a flatten-meta-variables, it goes on the left.
+
+ * If one is a strict sub-kind of the other e.g.
+ (alpha::?) ~ (beta::*)
+ orient them so RHS is a subkind of LHS. That way we will replace
+ 'a' with 'b', correctly narrowing the kind.
+ This establishes the subkind invariant of CTyEqCan.
+
+ * Put a meta-tyvar on the left if possible
+ alpha[3] ~ r
+
+ * If both are meta-tyvars, put the more touchable one (deepest level
+ number) on the left, so there is the best chance of unifying it
+ alpha[3] ~ beta[2]
+
+ * If both are meta-tyvars and both at the same level, put a SigTv
+ on the right if possible
+ alpha[2] ~ beta[2](sig-tv)
+ That way, when we unify alpha := beta, we don't lose the SigTv flag.
+
+ * Put a meta-tv with a System Name on the left if possible so it
+ gets eliminated (improves error messages)
+
+ * If one is a flatten-skolem, put it on the left so that it is
+ substituted out Note [Elminate flat-skols]
+ fsk ~ a
+
+Note [Avoid unnecessary swaps]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If we swap without actually improving matters, we can get an infnite loop.
+Consider
+ work item: a ~ b
+ inert item: b ~ c
+We canonicalise the work-time to (a ~ c). If we then swap it before
+aeding to the inert set, we'll add (c ~ a), and therefore kick out the
+inert guy, so we get
+ new work item: b ~ c
+ inert item: c ~ a
+And now the cycle just repeats
+
+Note [Eliminate flat-skols]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Suppose we have [G] Num (F [a])
+then we flatten to
+ [G] Num fsk
+ [G] F [a] ~ fsk
+where fsk is a flatten-skolem (FlatSkol). Suppose we have
+ type instance F [a] = a
+then we'll reduce the second constraint to
+ [G] a ~ fsk
+and then replace all uses of 'a' with fsk. That's bad because
+in error messages intead of saying 'a' we'll say (F [a]). In all
+places, including those where the programmer wrote 'a' in the first
+place. Very confusing! See Trac #7862.
+
+Solution: re-orient a~fsk to fsk~a, so that we preferentially eliminate
+the fsk.
+
+Note [Equalities with incompatible kinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+canEqLeaf is about to make a CTyEqCan or CFunEqCan; but both have the
+invariant that LHS and RHS satisfy the kind invariants for CTyEqCan,
+CFunEqCan. What if we try to unify two things with incompatible
+kinds?
+
+eg a ~ b where a::*, b::*->*
+or a ~ b where a::*, b::k, k is a kind variable
+
+The CTyEqCan compatKind invariant is important. If we make a CTyEqCan
+for a~b, then we might well *substitute* 'b' for 'a', and that might make
+a well-kinded type ill-kinded; and that is bad (eg typeKind can crash, see
+Trac #7696).
+
+So instead for these ill-kinded equalities we generate a CIrredCan,
+and put it in the inert set, which keeps it out of the way until a
+subsequent substitution (on kind variables, say) re-activates it.
+
+NB: it is important that the types s1,s2 are flattened and zonked
+ so that their kinds k1, k2 are inert wrt the substitution. That
+ means that they can only become the same if we change the inert
+ set, which in turn will kick out the irreducible equality
+ E.g. it is WRONG to make an irred (a:k1)~(b:k2)
+ if we already have a substitution k1:=k2
+
+NB: it's important that the new CIrredCan goes in the inert set rather
+than back into the work list. We used to do the latter, but that led
+to an infinite loop when we encountered it again, and put it back in
+the work list again.
+
+See also Note [Kind orientation for CTyEqCan] and
+ Note [Kind orientation for CFunEqCan] in TcRnTypes
+
+Note [Type synonyms and canonicalization]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We treat type synonym applications as xi types, that is, they do not
+count as type function applications. However, we do need to be a bit
+careful with type synonyms: like type functions they may not be
+generative or injective. However, unlike type functions, they are
+parametric, so there is no problem in expanding them whenever we see
+them, since we do not need to know anything about their arguments in
+order to expand them; this is what justifies not having to treat them
+as specially as type function applications. The thing that causes
+some subtleties is that we prefer to leave type synonym applications
+*unexpanded* whenever possible, in order to generate better error
+messages.
+
+If we encounter an equality constraint with type synonym applications
+on both sides, or a type synonym application on one side and some sort
+of type application on the other, we simply must expand out the type
+synonyms in order to continue decomposing the equality constraint into
+primitive equality constraints. For example, suppose we have
+
+ type F a = [Int]
+
+and we encounter the equality
+
+ F a ~ [b]
+
+In order to continue we must expand F a into [Int], giving us the
+equality
+
+ [Int] ~ [b]
+
+which we can then decompose into the more primitive equality
+constraint
+
+ Int ~ b.
+
+However, if we encounter an equality constraint with a type synonym
+application on one side and a variable on the other side, we should
+NOT (necessarily) expand the type synonym, since for the purpose of
+good error messages we want to leave type synonyms unexpanded as much
+as possible. Hence the ps_ty1, ps_ty2 argument passed to canEqTyVar.
+
+
+Note [occurCheckExpand]
+~~~~~~~~~~~~~~~~~~~~~~~
+There is a subtle point with type synonyms and the occurs check that
+takes place for equality constraints of the form tv ~ xi. As an
+example, suppose we have
+
+ type F a = Int
+
+and we come across the equality constraint
+
+ a ~ F a
+
+This should not actually fail the occurs check, since expanding out
+the type synonym results in the legitimate equality constraint a ~
+Int. We must actually do this expansion, because unifying a with F a
+will lead the type checker into infinite loops later. Put another
+way, canonical equality constraints should never *syntactically*
+contain the LHS variable in the RHS type. However, we don't always
+need to expand type synonyms when doing an occurs check; for example,
+the constraint
+
+ a ~ F b
+
+is obviously fine no matter what F expands to. And in this case we
+would rather unify a with F b (rather than F b's expansion) in order
+to get better error messages later.
+
+So, when doing an occurs check with a type synonym application on the
+RHS, we use some heuristics to find an expansion of the RHS which does
+not contain the variable from the LHS. In particular, given
+
+ a ~ F t1 ... tn
+
+we first try expanding each of the ti to types which no longer contain
+a. If this turns out to be impossible, we next try expanding F
+itself, and so on. See Note [Occurs check expansion] in TcType
+-}