{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFunctor #-}
module TcCanonical(
canonicalize,
unifyDerived,
makeSuperClasses, maybeSym,
StopOrContinue(..), stopWith, continueWith,
solveCallStack
) where
#include "HsVersions.h"
import GhcPrelude
import Constraint
import Predicate
import TcOrigin
import TcUnify( swapOverTyVars, metaTyVarUpdateOK )
import TcType
import Type
import TcFlatten
import TcSMonad
import TcEvidence
import TcEvTerm
import Class
import TyCon
import TyCoRep
import Coercion
import CoreSyn
import Id( idType, mkTemplateLocals )
import FamInstEnv ( FamInstEnvs )
import FamInst ( tcTopNormaliseNewTypeTF_maybe )
import Var
import VarEnv( mkInScopeSet )
import VarSet( delVarSetList )
import Outputable
import DynFlags( DynFlags )
import NameSet
import RdrName
import GHC.Hs.Types( HsIPName(..) )
import Pair
import Util
import Bag
import MonadUtils
import Control.Monad
import Data.Maybe ( isJust )
import Data.List ( zip4 )
import BasicTypes
import Data.Bifunctor ( bimap )
import Data.Foldable ( traverse_ )
canonicalize :: Ct -> TcS (StopOrContinue Ct)
canonicalize :: Ct -> TcS (StopOrContinue Ct)
canonicalize (CNonCanonical { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev })
= {-# SCC "canNC" #-}
case PredType -> Pred
classifyPredType PredType
pred of
ClassPred Class
cls [PredType]
tys -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:cls" (Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
cls SDoc -> SDoc -> SDoc
<+> [PredType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [PredType]
tys)
CtEvidence -> Class -> [PredType] -> TcS (StopOrContinue Ct)
canClassNC CtEvidence
ev Class
cls [PredType]
tys
EqPred EqRel
eq_rel PredType
ty1 PredType
ty2 -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:eq" (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty1 SDoc -> SDoc -> SDoc
$$ PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty2)
CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ty2
IrredPred {} -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:irred" (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
pred)
CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtEvidence
ev
ForAllPred [TyCoVarBinder]
_ [PredType]
_ PredType
pred -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:forall" (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
pred)
CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll CtEvidence
ev (PredType -> Bool
isClassPred PredType
pred)
where
pred :: PredType
pred = CtEvidence -> PredType
ctEvPred CtEvidence
ev
canonicalize (CQuantCan (QCI { qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev, qci_pend_sc :: QCInst -> Bool
qci_pend_sc = Bool
pend_sc }))
= CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll CtEvidence
ev Bool
pend_sc
canonicalize (CIrredCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev })
| EqPred EqRel
eq_rel PredType
ty1 PredType
ty2 <- PredType -> Pred
classifyPredType (CtEvidence -> PredType
ctEvPred CtEvidence
ev)
=
CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ty2
| Bool
otherwise
= CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtEvidence
ev
canonicalize (CDictCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev, cc_class :: Ct -> Class
cc_class = Class
cls
, cc_tyargs :: Ct -> [PredType]
cc_tyargs = [PredType]
xis, cc_pend_sc :: Ct -> Bool
cc_pend_sc = Bool
pend_sc })
= {-# SCC "canClass" #-}
CtEvidence
-> Class -> [PredType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [PredType]
xis Bool
pend_sc
canonicalize (CTyEqCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev
, cc_tyvar :: Ct -> TcTyVar
cc_tyvar = TcTyVar
tv
, cc_rhs :: Ct -> PredType
cc_rhs = PredType
xi
, cc_eq_rel :: Ct -> EqRel
cc_eq_rel = EqRel
eq_rel })
= {-# SCC "canEqLeafTyVarEq" #-}
CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel (TcTyVar -> PredType
mkTyVarTy TcTyVar
tv) PredType
xi
canonicalize (CFunEqCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev
, cc_fun :: Ct -> TyCon
cc_fun = TyCon
fn
, cc_tyargs :: Ct -> [PredType]
cc_tyargs = [PredType]
xis1
, cc_fsk :: Ct -> TcTyVar
cc_fsk = TcTyVar
fsk })
= {-# SCC "canEqLeafFunEq" #-}
CtEvidence
-> TyCon -> [PredType] -> TcTyVar -> TcS (StopOrContinue Ct)
canCFunEqCan CtEvidence
ev TyCon
fn [PredType]
xis1 TcTyVar
fsk
canonicalize (CHoleCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev, cc_hole :: Ct -> Hole
cc_hole = Hole
hole })
= CtEvidence -> Hole -> TcS (StopOrContinue Ct)
canHole CtEvidence
ev Hole
hole
canClassNC :: CtEvidence -> Class -> [Type] -> TcS (StopOrContinue Ct)
canClassNC :: CtEvidence -> Class -> [PredType] -> TcS (StopOrContinue Ct)
canClassNC CtEvidence
ev Class
cls [PredType]
tys
| CtEvidence -> Bool
isGiven CtEvidence
ev
= do { [Ct]
sc_cts <- CtEvidence
-> [TcTyVar] -> [PredType] -> Class -> [PredType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [] [] Class
cls [PredType]
tys
; [Ct] -> TcS ()
emitWork [Ct]
sc_cts
; CtEvidence
-> Class -> [PredType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [PredType]
tys Bool
False }
| CtEvidence -> Bool
isWanted CtEvidence
ev
, Just FastString
ip_name <- Class -> [PredType] -> Maybe FastString
isCallStackPred Class
cls [PredType]
tys
, OccurrenceOf Name
func <- CtLoc -> CtOrigin
ctLocOrigin CtLoc
loc
= do {
; let new_loc :: CtLoc
new_loc = CtLoc -> CtOrigin -> CtLoc
setCtLocOrigin CtLoc
loc (HsIPName -> CtOrigin
IPOccOrigin (FastString -> HsIPName
HsIPName FastString
ip_name))
; CtEvidence
new_ev <- CtLoc -> PredType -> TcS CtEvidence
newWantedEvVarNC CtLoc
new_loc PredType
pred
; let ev_cs :: EvCallStack
ev_cs = Name -> RealSrcSpan -> EvExpr -> EvCallStack
EvCsPushCall Name
func (CtLoc -> RealSrcSpan
ctLocSpan CtLoc
loc) (CtEvidence -> EvExpr
ctEvExpr CtEvidence
new_ev)
; CtEvidence -> EvCallStack -> TcS ()
solveCallStack CtEvidence
ev EvCallStack
ev_cs
; CtEvidence
-> Class -> [PredType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
new_ev Class
cls [PredType]
tys Bool
False }
| Bool
otherwise
= CtEvidence
-> Class -> [PredType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [PredType]
tys (Class -> Bool
has_scs Class
cls)
where
has_scs :: Class -> Bool
has_scs Class
cls = Bool -> Bool
not ([PredType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Class -> [PredType]
classSCTheta Class
cls))
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
pred :: PredType
pred = CtEvidence -> PredType
ctEvPred CtEvidence
ev
solveCallStack :: CtEvidence -> EvCallStack -> TcS ()
solveCallStack :: CtEvidence -> EvCallStack -> TcS ()
solveCallStack CtEvidence
ev EvCallStack
ev_cs = do
EvExpr
cs_tm <- EvCallStack -> TcS EvExpr
forall (m :: * -> *).
(MonadThings m, HasModule m, HasDynFlags m) =>
EvCallStack -> m EvExpr
evCallStack EvCallStack
ev_cs
let ev_tm :: EvTerm
ev_tm = EvExpr -> TcCoercion -> EvTerm
mkEvCast EvExpr
cs_tm (PredType -> TcCoercion
wrapIP (CtEvidence -> PredType
ctEvPred CtEvidence
ev))
CtEvidence -> EvTerm -> TcS ()
setEvBindIfWanted CtEvidence
ev EvTerm
ev_tm
canClass :: CtEvidence
-> Class -> [Type]
-> Bool
-> TcS (StopOrContinue Ct)
canClass :: CtEvidence
-> Class -> [PredType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [PredType]
tys Bool
pend_sc
=
ASSERT2( ctEvRole ev == Nominal, ppr ev $$ ppr cls $$ ppr tys )
do { ([PredType]
xis, [TcCoercion]
cos, TcCoercion
_kind_co) <- CtEvidence
-> TyCon
-> [PredType]
-> TcS ([PredType], [TcCoercion], TcCoercion)
flattenArgsNom CtEvidence
ev TyCon
cls_tc [PredType]
tys
; MASSERT( isTcReflCo _kind_co )
; let co :: TcCoercion
co = Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTcTyConAppCo Role
Nominal TyCon
cls_tc [TcCoercion]
cos
xi :: PredType
xi = Class -> [PredType] -> PredType
mkClassPred Class
cls [PredType]
xis
mk_ct :: CtEvidence -> Ct
mk_ct CtEvidence
new_ev = CDictCan :: CtEvidence -> Class -> [PredType] -> Bool -> Ct
CDictCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_ev
, cc_tyargs :: [PredType]
cc_tyargs = [PredType]
xis
, cc_class :: Class
cc_class = Class
cls
, cc_pend_sc :: Bool
cc_pend_sc = Bool
pend_sc }
; StopOrContinue CtEvidence
mb <- CtEvidence
-> PredType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev PredType
xi TcCoercion
co
; String -> SDoc -> TcS ()
traceTcS String
"canClass" ([SDoc] -> SDoc
vcat [ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
xi, StopOrContinue CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr StopOrContinue CtEvidence
mb ])
; StopOrContinue Ct -> TcS (StopOrContinue Ct)
forall (m :: * -> *) a. Monad m => a -> m a
return ((CtEvidence -> Ct)
-> StopOrContinue CtEvidence -> StopOrContinue Ct
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CtEvidence -> Ct
mk_ct StopOrContinue CtEvidence
mb) }
where
cls_tc :: TyCon
cls_tc = Class -> TyCon
classTyCon Class
cls
makeSuperClasses :: [Ct] -> TcS [Ct]
makeSuperClasses :: [Ct] -> TcS [Ct]
makeSuperClasses [Ct]
cts = (Ct -> TcS [Ct]) -> [Ct] -> TcS [Ct]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM Ct -> TcS [Ct]
go [Ct]
cts
where
go :: Ct -> TcS [Ct]
go (CDictCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev, cc_class :: Ct -> Class
cc_class = Class
cls, cc_tyargs :: Ct -> [PredType]
cc_tyargs = [PredType]
tys })
= CtEvidence
-> [TcTyVar] -> [PredType] -> Class -> [PredType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [] [] Class
cls [PredType]
tys
go (CQuantCan (QCI { qci_pred :: QCInst -> PredType
qci_pred = PredType
pred, qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev }))
= ASSERT2( isClassPred pred, ppr pred )
CtEvidence
-> [TcTyVar] -> [PredType] -> Class -> [PredType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
where
([TcTyVar]
tvs, [PredType]
theta, Class
cls, [PredType]
tys) = PredType -> ([TcTyVar], [PredType], Class, [PredType])
tcSplitDFunTy (CtEvidence -> PredType
ctEvPred CtEvidence
ev)
go Ct
ct = String -> SDoc -> TcS [Ct]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"makeSuperClasses" (Ct -> SDoc
forall a. Outputable a => a -> SDoc
ppr Ct
ct)
mkStrictSuperClasses
:: CtEvidence
-> [TyVar] -> ThetaType
-> Class -> [Type] -> TcS [Ct]
mkStrictSuperClasses :: CtEvidence
-> [TcTyVar] -> [PredType] -> Class -> [PredType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
= NameSet
-> CtEvidence
-> [TcTyVar]
-> [PredType]
-> Class
-> [PredType]
-> TcS [Ct]
mk_strict_superclasses (Name -> NameSet
unitNameSet (Class -> Name
className Class
cls))
CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
mk_strict_superclasses :: NameSet -> CtEvidence
-> [TyVar] -> ThetaType
-> Class -> [Type] -> TcS [Ct]
mk_strict_superclasses :: NameSet
-> CtEvidence
-> [TcTyVar]
-> [PredType]
-> Class
-> [PredType]
-> TcS [Ct]
mk_strict_superclasses NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
| CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
evar, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc } <- CtEvidence
ev
= (TcTyVar -> TcS [Ct]) -> [TcTyVar] -> TcS [Ct]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (TcTyVar -> CtLoc -> TcTyVar -> TcS [Ct]
do_one_given TcTyVar
evar (CtLoc -> CtLoc
mk_given_loc CtLoc
loc)) ([TcTyVar] -> TcS [Ct]) -> [TcTyVar] -> TcS [Ct]
forall a b. (a -> b) -> a -> b
$
Class -> [TcTyVar]
classSCSelIds Class
cls
where
dict_ids :: [TcTyVar]
dict_ids = [PredType] -> [TcTyVar]
mkTemplateLocals [PredType]
theta
size :: TypeSize
size = [PredType] -> TypeSize
sizeTypes [PredType]
tys
do_one_given :: TcTyVar -> CtLoc -> TcTyVar -> TcS [Ct]
do_one_given TcTyVar
evar CtLoc
given_loc TcTyVar
sel_id
| HasDebugCallStack => PredType -> Bool
PredType -> Bool
isUnliftedType PredType
sc_pred
, Bool -> Bool
not ([TcTyVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcTyVar]
tvs Bool -> Bool -> Bool
&& [PredType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PredType]
theta)
=
[Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise
= do { CtEvidence
given_ev <- CtLoc -> (PredType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
given_loc ((PredType, EvTerm) -> TcS CtEvidence)
-> (PredType, EvTerm) -> TcS CtEvidence
forall a b. (a -> b) -> a -> b
$
(PredType
given_ty, TcTyVar -> TcTyVar -> EvTerm
mk_sc_sel TcTyVar
evar TcTyVar
sel_id)
; NameSet
-> CtEvidence -> [TcTyVar] -> [PredType] -> PredType -> TcS [Ct]
mk_superclasses NameSet
rec_clss CtEvidence
given_ev [TcTyVar]
tvs [PredType]
theta PredType
sc_pred }
where
sc_pred :: PredType
sc_pred = PredType -> PredType
funResultTy (HasDebugCallStack => PredType -> [PredType] -> PredType
PredType -> [PredType] -> PredType
piResultTys (TcTyVar -> PredType
idType TcTyVar
sel_id) [PredType]
tys)
given_ty :: PredType
given_ty = [TcTyVar] -> [PredType] -> PredType -> PredType
mkInfSigmaTy [TcTyVar]
tvs [PredType]
theta PredType
sc_pred
mk_sc_sel :: TcTyVar -> TcTyVar -> EvTerm
mk_sc_sel TcTyVar
evar TcTyVar
sel_id
= EvExpr -> EvTerm
EvExpr (EvExpr -> EvTerm) -> EvExpr -> EvTerm
forall a b. (a -> b) -> a -> b
$ [TcTyVar] -> EvExpr -> EvExpr
forall b. [b] -> Expr b -> Expr b
mkLams [TcTyVar]
tvs (EvExpr -> EvExpr) -> EvExpr -> EvExpr
forall a b. (a -> b) -> a -> b
$ [TcTyVar] -> EvExpr -> EvExpr
forall b. [b] -> Expr b -> Expr b
mkLams [TcTyVar]
dict_ids (EvExpr -> EvExpr) -> EvExpr -> EvExpr
forall a b. (a -> b) -> a -> b
$
TcTyVar -> EvExpr
forall b. TcTyVar -> Expr b
Var TcTyVar
sel_id EvExpr -> [PredType] -> EvExpr
forall b. Expr b -> [PredType] -> Expr b
`mkTyApps` [PredType]
tys EvExpr -> EvExpr -> EvExpr
forall b. Expr b -> Expr b -> Expr b
`App`
(TcTyVar -> EvExpr
evId TcTyVar
evar EvExpr -> [PredType] -> EvExpr
forall b. Expr b -> [PredType] -> Expr b
`mkTyApps` [TcTyVar] -> [PredType]
mkTyVarTys [TcTyVar]
tvs EvExpr -> [TcTyVar] -> EvExpr
forall b. Expr b -> [TcTyVar] -> Expr b
`mkVarApps` [TcTyVar]
dict_ids)
mk_given_loc :: CtLoc -> CtLoc
mk_given_loc CtLoc
loc
| Class -> Bool
isCTupleClass Class
cls
= CtLoc
loc
| GivenOrigin SkolemInfo
skol_info <- CtLoc -> CtOrigin
ctLocOrigin CtLoc
loc
= case SkolemInfo
skol_info of
SkolemInfo
InstSkol -> CtLoc
loc { ctl_origin :: CtOrigin
ctl_origin = SkolemInfo -> CtOrigin
GivenOrigin (TypeSize -> SkolemInfo
InstSC TypeSize
size) }
InstSC TypeSize
n -> CtLoc
loc { ctl_origin :: CtOrigin
ctl_origin = SkolemInfo -> CtOrigin
GivenOrigin (TypeSize -> SkolemInfo
InstSC (TypeSize
n TypeSize -> TypeSize -> TypeSize
forall a. Ord a => a -> a -> a
`max` TypeSize
size)) }
SkolemInfo
_ -> CtLoc
loc
| Bool
otherwise
= CtLoc
loc
mk_strict_superclasses NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
| (PredType -> Bool) -> [PredType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all PredType -> Bool
noFreeVarsOfType [PredType]
tys
= [Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise
= ASSERT2( null tvs && null theta, ppr tvs $$ ppr theta )
(PredType -> TcS [Ct]) -> [PredType] -> TcS [Ct]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM PredType -> TcS [Ct]
do_one_derived (Class -> [PredType] -> [PredType]
immSuperClasses Class
cls [PredType]
tys)
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
do_one_derived :: PredType -> TcS [Ct]
do_one_derived PredType
sc_pred
= do { CtEvidence
sc_ev <- CtLoc -> PredType -> TcS CtEvidence
newDerivedNC CtLoc
loc PredType
sc_pred
; NameSet
-> CtEvidence -> [TcTyVar] -> [PredType] -> PredType -> TcS [Ct]
mk_superclasses NameSet
rec_clss CtEvidence
sc_ev [] [] PredType
sc_pred }
mk_superclasses :: NameSet -> CtEvidence
-> [TyVar] -> ThetaType -> PredType -> TcS [Ct]
mk_superclasses :: NameSet
-> CtEvidence -> [TcTyVar] -> [PredType] -> PredType -> TcS [Ct]
mk_superclasses NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [PredType]
theta PredType
pred
| ClassPred Class
cls [PredType]
tys <- PredType -> Pred
classifyPredType PredType
pred
= NameSet
-> CtEvidence
-> [TcTyVar]
-> [PredType]
-> Class
-> [PredType]
-> TcS [Ct]
mk_superclasses_of NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
| Bool
otherwise
= [Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return [CtEvidence -> Ct
mkNonCanonical CtEvidence
ev]
mk_superclasses_of :: NameSet -> CtEvidence
-> [TyVar] -> ThetaType -> Class -> [Type]
-> TcS [Ct]
mk_superclasses_of :: NameSet
-> CtEvidence
-> [TcTyVar]
-> [PredType]
-> Class
-> [PredType]
-> TcS [Ct]
mk_superclasses_of NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
| Bool
loop_found = do { String -> SDoc -> TcS ()
traceTcS String
"mk_superclasses_of: loop" (Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
cls SDoc -> SDoc -> SDoc
<+> [PredType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [PredType]
tys)
; [Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return [Ct
this_ct] }
| Bool
otherwise = do { String -> SDoc -> TcS ()
traceTcS String
"mk_superclasses_of" ([SDoc] -> SDoc
vcat [ Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
cls SDoc -> SDoc -> SDoc
<+> [PredType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [PredType]
tys
, Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Class -> Bool
isCTupleClass Class
cls)
, NameSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr NameSet
rec_clss
])
; [Ct]
sc_cts <- NameSet
-> CtEvidence
-> [TcTyVar]
-> [PredType]
-> Class
-> [PredType]
-> TcS [Ct]
mk_strict_superclasses NameSet
rec_clss' CtEvidence
ev [TcTyVar]
tvs [PredType]
theta Class
cls [PredType]
tys
; [Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return (Ct
this_ct Ct -> [Ct] -> [Ct]
forall a. a -> [a] -> [a]
: [Ct]
sc_cts) }
where
cls_nm :: Name
cls_nm = Class -> Name
className Class
cls
loop_found :: Bool
loop_found = Bool -> Bool
not (Class -> Bool
isCTupleClass Class
cls) Bool -> Bool -> Bool
&& Name
cls_nm Name -> NameSet -> Bool
`elemNameSet` NameSet
rec_clss
rec_clss' :: NameSet
rec_clss' = NameSet
rec_clss NameSet -> Name -> NameSet
`extendNameSet` Name
cls_nm
this_ct :: Ct
this_ct | [TcTyVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcTyVar]
tvs, [PredType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PredType]
theta
= CDictCan :: CtEvidence -> Class -> [PredType] -> Bool -> Ct
CDictCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
ev, cc_class :: Class
cc_class = Class
cls, cc_tyargs :: [PredType]
cc_tyargs = [PredType]
tys
, cc_pend_sc :: Bool
cc_pend_sc = Bool
loop_found }
| Bool
otherwise
= QCInst -> Ct
CQuantCan (QCI :: CtEvidence -> [TcTyVar] -> PredType -> Bool -> QCInst
QCI { qci_tvs :: [TcTyVar]
qci_tvs = [TcTyVar]
tvs, qci_pred :: PredType
qci_pred = Class -> [PredType] -> PredType
mkClassPred Class
cls [PredType]
tys
, qci_ev :: CtEvidence
qci_ev = CtEvidence
ev
, qci_pend_sc :: Bool
qci_pend_sc = Bool
loop_found })
canIrred :: CtEvidence -> TcS (StopOrContinue Ct)
canIrred :: CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtEvidence
ev
= do { let pred :: PredType
pred = CtEvidence -> PredType
ctEvPred CtEvidence
ev
; String -> SDoc -> TcS ()
traceTcS String
"can_pred" (String -> SDoc
text String
"IrredPred = " SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
pred)
; (PredType
xi,TcCoercion
co) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev PredType
pred
; CtEvidence
-> PredType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev PredType
xi TcCoercion
co TcS (StopOrContinue CtEvidence)
-> (CtEvidence -> TcS (StopOrContinue Ct))
-> TcS (StopOrContinue Ct)
forall a b.
TcS (StopOrContinue a)
-> (a -> TcS (StopOrContinue b)) -> TcS (StopOrContinue b)
`andWhenContinue` \ CtEvidence
new_ev ->
do {
; case PredType -> Pred
classifyPredType (CtEvidence -> PredType
ctEvPred CtEvidence
new_ev) of
ClassPred Class
cls [PredType]
tys -> CtEvidence -> Class -> [PredType] -> TcS (StopOrContinue Ct)
canClassNC CtEvidence
new_ev Class
cls [PredType]
tys
EqPred EqRel
eq_rel PredType
ty1 PredType
ty2 -> CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
new_ev EqRel
eq_rel PredType
ty1 PredType
ty2
Pred
_ -> Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (Ct -> TcS (StopOrContinue Ct)) -> Ct -> TcS (StopOrContinue Ct)
forall a b. (a -> b) -> a -> b
$
CtEvidence -> Ct
mkIrredCt CtEvidence
new_ev } }
canHole :: CtEvidence -> Hole -> TcS (StopOrContinue Ct)
canHole :: CtEvidence -> Hole -> TcS (StopOrContinue Ct)
canHole CtEvidence
ev Hole
hole
= do { let pred :: PredType
pred = CtEvidence -> PredType
ctEvPred CtEvidence
ev
; (PredType
xi,TcCoercion
co) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev PredType
pred
; CtEvidence
-> PredType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev PredType
xi TcCoercion
co TcS (StopOrContinue CtEvidence)
-> (CtEvidence -> TcS (StopOrContinue Ct))
-> TcS (StopOrContinue Ct)
forall a b.
TcS (StopOrContinue a)
-> (a -> TcS (StopOrContinue b)) -> TcS (StopOrContinue b)
`andWhenContinue` \ CtEvidence
new_ev ->
do { (Cts -> Cts) -> TcS ()
updInertIrreds (Cts -> Ct -> Cts
`snocCts` (CHoleCan :: CtEvidence -> Hole -> Ct
CHoleCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_ev
, cc_hole :: Hole
cc_hole = Hole
hole }))
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
new_ev String
"Emit insoluble hole" } }
canForAll :: CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll :: CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll CtEvidence
ev Bool
pend_sc
= do {
let pred :: PredType
pred = CtEvidence -> PredType
ctEvPred CtEvidence
ev
; (PredType
xi,TcCoercion
co) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev PredType
pred
; CtEvidence
-> PredType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev PredType
xi TcCoercion
co TcS (StopOrContinue CtEvidence)
-> (CtEvidence -> TcS (StopOrContinue Ct))
-> TcS (StopOrContinue Ct)
forall a b.
TcS (StopOrContinue a)
-> (a -> TcS (StopOrContinue b)) -> TcS (StopOrContinue b)
`andWhenContinue` \ CtEvidence
new_ev ->
do {
; case PredType -> Pred
classifyPredType (CtEvidence -> PredType
ctEvPred CtEvidence
new_ev) of
ForAllPred [TyCoVarBinder]
tv_bndrs [PredType]
theta PredType
pred
-> CtEvidence
-> [TyCoVarBinder]
-> [PredType]
-> PredType
-> Bool
-> TcS (StopOrContinue Ct)
solveForAll CtEvidence
new_ev [TyCoVarBinder]
tv_bndrs [PredType]
theta PredType
pred Bool
pend_sc
Pred
_ -> String -> SDoc -> TcS (StopOrContinue Ct)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"canForAll" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
new_ev)
} }
solveForAll :: CtEvidence -> [TyVarBinder] -> TcThetaType -> PredType -> Bool
-> TcS (StopOrContinue Ct)
solveForAll :: CtEvidence
-> [TyCoVarBinder]
-> [PredType]
-> PredType
-> Bool
-> TcS (StopOrContinue Ct)
solveForAll CtEvidence
ev [TyCoVarBinder]
tv_bndrs [PredType]
theta PredType
pred Bool
pend_sc
| CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest } <- CtEvidence
ev
=
do { let skol_info :: SkolemInfo
skol_info = SkolemInfo
QuantCtxtSkol
empty_subst :: TCvSubst
empty_subst = InScopeSet -> TCvSubst
mkEmptyTCvSubst (InScopeSet -> TCvSubst) -> InScopeSet -> TCvSubst
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet (VarSet -> InScopeSet) -> VarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$
[PredType] -> VarSet
tyCoVarsOfTypes (PredType
predPredType -> [PredType] -> [PredType]
forall a. a -> [a] -> [a]
:[PredType]
theta) VarSet -> [TcTyVar] -> VarSet
`delVarSetList` [TcTyVar]
tvs
; (TCvSubst
subst, [TcTyVar]
skol_tvs) <- TCvSubst -> [TcTyVar] -> TcS (TCvSubst, [TcTyVar])
tcInstSkolTyVarsX TCvSubst
empty_subst [TcTyVar]
tvs
; [TcTyVar]
given_ev_vars <- (PredType -> TcS TcTyVar) -> [PredType] -> TcS [TcTyVar]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM PredType -> TcS TcTyVar
newEvVar (HasCallStack => TCvSubst -> [PredType] -> [PredType]
TCvSubst -> [PredType] -> [PredType]
substTheta TCvSubst
subst [PredType]
theta)
; (TcTyVar
w_id, TcEvBinds
ev_binds)
<- SkolemInfo
-> [TcTyVar]
-> [TcTyVar]
-> TcS (TcTyVar, Cts)
-> TcS (TcTyVar, TcEvBinds)
forall result.
SkolemInfo
-> [TcTyVar]
-> [TcTyVar]
-> TcS (result, Cts)
-> TcS (result, TcEvBinds)
checkConstraintsTcS SkolemInfo
skol_info [TcTyVar]
skol_tvs [TcTyVar]
given_ev_vars (TcS (TcTyVar, Cts) -> TcS (TcTyVar, TcEvBinds))
-> TcS (TcTyVar, Cts) -> TcS (TcTyVar, TcEvBinds)
forall a b. (a -> b) -> a -> b
$
do { CtEvidence
wanted_ev <- CtLoc -> PredType -> TcS CtEvidence
newWantedEvVarNC CtLoc
loc (PredType -> TcS CtEvidence) -> PredType -> TcS CtEvidence
forall a b. (a -> b) -> a -> b
$
HasCallStack => TCvSubst -> PredType -> PredType
TCvSubst -> PredType -> PredType
substTy TCvSubst
subst PredType
pred
; (TcTyVar, Cts) -> TcS (TcTyVar, Cts)
forall (m :: * -> *) a. Monad m => a -> m a
return ( CtEvidence -> TcTyVar
ctEvEvId CtEvidence
wanted_ev
, Ct -> Cts
forall a. a -> Bag a
unitBag (CtEvidence -> Ct
mkNonCanonical CtEvidence
wanted_ev)) }
; TcEvDest -> EvTerm -> TcS ()
setWantedEvTerm TcEvDest
dest (EvTerm -> TcS ()) -> EvTerm -> TcS ()
forall a b. (a -> b) -> a -> b
$
EvFun :: [TcTyVar] -> [TcTyVar] -> TcEvBinds -> TcTyVar -> EvTerm
EvFun { et_tvs :: [TcTyVar]
et_tvs = [TcTyVar]
skol_tvs, et_given :: [TcTyVar]
et_given = [TcTyVar]
given_ev_vars
, et_binds :: TcEvBinds
et_binds = TcEvBinds
ev_binds, et_body :: TcTyVar
et_body = TcTyVar
w_id }
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Wanted forall-constraint" }
| CtEvidence -> Bool
isGiven CtEvidence
ev
= do { QCInst -> TcS ()
addInertForAll QCInst
qci
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Given forall-constraint" }
| Bool
otherwise
= CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Derived forall-constraint"
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
tvs :: [TcTyVar]
tvs = [TyCoVarBinder] -> [TcTyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyCoVarBinder]
tv_bndrs
qci :: QCInst
qci = QCI :: CtEvidence -> [TcTyVar] -> PredType -> Bool -> QCInst
QCI { qci_ev :: CtEvidence
qci_ev = CtEvidence
ev, qci_tvs :: [TcTyVar]
qci_tvs = [TcTyVar]
tvs
, qci_pred :: PredType
qci_pred = PredType
pred, qci_pend_sc :: Bool
qci_pend_sc = Bool
pend_sc }
canEqNC :: CtEvidence -> EqRel -> Type -> Type -> TcS (StopOrContinue Ct)
canEqNC :: CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ty2
= do { Either (Pair PredType) PredType
result <- PredType -> PredType -> TcS (Either (Pair PredType) PredType)
zonk_eq_types PredType
ty1 PredType
ty2
; case Either (Pair PredType) PredType
result of
Left (Pair PredType
ty1' PredType
ty2') -> Bool
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
False CtEvidence
ev EqRel
eq_rel PredType
ty1' PredType
ty1 PredType
ty2' PredType
ty2
Right PredType
ty -> CtEvidence -> EqRel -> PredType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel PredType
ty }
can_eq_nc
:: Bool
-> CtEvidence
-> EqRel
-> Type -> Type
-> Type -> Type
-> TcS (StopOrContinue Ct)
can_eq_nc :: Bool
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
flat CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 PredType
ty2 PredType
ps_ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"can_eq_nc" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
flat, CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev, EqRel -> SDoc
forall a. Outputable a => a -> SDoc
ppr EqRel
eq_rel, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty1, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ps_ty1, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty2, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ps_ty2 ]
; GlobalRdrEnv
rdr_env <- TcS GlobalRdrEnv
getGlobalRdrEnvTcS
; (FamInstEnv, FamInstEnv)
fam_insts <- TcS (FamInstEnv, FamInstEnv)
getFamInstEnvs
; Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
fam_insts CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 PredType
ty2 PredType
ps_ty2 }
can_eq_nc'
:: Bool
-> GlobalRdrEnv
-> FamInstEnvs
-> CtEvidence
-> EqRel
-> Type -> Type
-> Type -> Type
-> TcS (StopOrContinue Ct)
can_eq_nc' :: Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 PredType
ty2 PredType
ps_ty2
| Just PredType
ty1' <- PredType -> Maybe PredType
tcView PredType
ty1 = Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel PredType
ty1' PredType
ps_ty1 PredType
ty2 PredType
ps_ty2
| Just PredType
ty2' <- PredType -> Maybe PredType
tcView PredType
ty2 = Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 PredType
ty2' PredType
ps_ty2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
ReprEq PredType
ty1 PredType
_ PredType
ty2 PredType
_
| PredType
ty1 HasDebugCallStack => PredType -> PredType -> Bool
PredType -> PredType -> Bool
`tcEqType` PredType
ty2
= CtEvidence -> EqRel -> PredType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
ReprEq PredType
ty1
can_eq_nc' Bool
_flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 PredType
ty2 PredType
ps_ty2
| EqRel
ReprEq <- EqRel
eq_rel
, Just ((Bag GlobalRdrElt, TcCoercion), PredType)
stuff1 <- (FamInstEnv, FamInstEnv)
-> GlobalRdrEnv
-> PredType
-> Maybe ((Bag GlobalRdrElt, TcCoercion), PredType)
tcTopNormaliseNewTypeTF_maybe (FamInstEnv, FamInstEnv)
envs GlobalRdrEnv
rdr_env PredType
ty1
= CtEvidence
-> SwapFlag
-> PredType
-> ((Bag GlobalRdrElt, TcCoercion), PredType)
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc CtEvidence
ev SwapFlag
NotSwapped PredType
ty1 ((Bag GlobalRdrElt, TcCoercion), PredType)
stuff1 PredType
ty2 PredType
ps_ty2
| EqRel
ReprEq <- EqRel
eq_rel
, Just ((Bag GlobalRdrElt, TcCoercion), PredType)
stuff2 <- (FamInstEnv, FamInstEnv)
-> GlobalRdrEnv
-> PredType
-> Maybe ((Bag GlobalRdrElt, TcCoercion), PredType)
tcTopNormaliseNewTypeTF_maybe (FamInstEnv, FamInstEnv)
envs GlobalRdrEnv
rdr_env PredType
ty2
= CtEvidence
-> SwapFlag
-> PredType
-> ((Bag GlobalRdrElt, TcCoercion), PredType)
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc CtEvidence
ev SwapFlag
IsSwapped PredType
ty2 ((Bag GlobalRdrElt, TcCoercion), PredType)
stuff2 PredType
ty1 PredType
ps_ty1
can_eq_nc' Bool
flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (CastTy PredType
ty1 TcCoercion
co1) PredType
_ PredType
ty2 PredType
ps_ty2
= Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> PredType
-> TcCoercion
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqCast Bool
flat CtEvidence
ev EqRel
eq_rel SwapFlag
NotSwapped PredType
ty1 TcCoercion
co1 PredType
ty2 PredType
ps_ty2
can_eq_nc' Bool
flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 (CastTy PredType
ty2 TcCoercion
co2) PredType
_
= Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> PredType
-> TcCoercion
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqCast Bool
flat CtEvidence
ev EqRel
eq_rel SwapFlag
IsSwapped PredType
ty2 TcCoercion
co2 PredType
ty1 PredType
ps_ty1
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (TyVarTy TcTyVar
tv1) PredType
ps_ty1 PredType
ty2 PredType
ps_ty2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVar CtEvidence
ev EqRel
eq_rel SwapFlag
NotSwapped TcTyVar
tv1 PredType
ps_ty1 PredType
ty2 PredType
ps_ty2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ps_ty1 (TyVarTy TcTyVar
tv2) PredType
ps_ty2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVar CtEvidence
ev EqRel
eq_rel SwapFlag
IsSwapped TcTyVar
tv2 PredType
ps_ty2 PredType
ty1 PredType
ps_ty1
can_eq_nc' Bool
_flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel ty1 :: PredType
ty1@(LitTy TyLit
l1) PredType
_ (LitTy TyLit
l2) PredType
_
| TyLit
l1 TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
l2
= do { CtEvidence -> EvTerm -> TcS ()
setEvBindIfWanted CtEvidence
ev (TcCoercion -> EvTerm
evCoercion (TcCoercion -> EvTerm) -> TcCoercion -> EvTerm
forall a b. (a -> b) -> a -> b
$ Role -> PredType -> TcCoercion
mkReflCo (EqRel -> Role
eqRelRole EqRel
eq_rel) PredType
ty1)
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Equal LitTy" }
can_eq_nc' Bool
_flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
_ PredType
ty2 PredType
_
| Just (TyCon
tc1, [PredType]
tys1) <- HasDebugCallStack => PredType -> Maybe (TyCon, [PredType])
PredType -> Maybe (TyCon, [PredType])
repSplitTyConApp_maybe PredType
ty1
, Just (TyCon
tc2, [PredType]
tys2) <- HasDebugCallStack => PredType -> Maybe (TyCon, [PredType])
PredType -> Maybe (TyCon, [PredType])
repSplitTyConApp_maybe PredType
ty2
, Bool -> Bool
not (TyCon -> Bool
isTypeFamilyTyCon TyCon
tc1)
, Bool -> Bool
not (TyCon -> Bool
isTypeFamilyTyCon TyCon
tc2)
= CtEvidence
-> EqRel
-> TyCon
-> [PredType]
-> TyCon
-> [PredType]
-> TcS (StopOrContinue Ct)
canTyConApp CtEvidence
ev EqRel
eq_rel TyCon
tc1 [PredType]
tys1 TyCon
tc2 [PredType]
tys2
can_eq_nc' Bool
_flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel
s1 :: PredType
s1@(ForAllTy {}) PredType
_ s2 :: PredType
s2@(ForAllTy {}) PredType
_
= CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
can_eq_nc_forall CtEvidence
ev EqRel
eq_rel PredType
s1 PredType
s2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (AppTy PredType
t1 PredType
s1) PredType
_ PredType
ty2 PredType
_
| EqRel
NomEq <- EqRel
eq_rel
, Just (PredType
t2, PredType
s2) <- PredType -> Maybe (PredType, PredType)
tcSplitAppTy_maybe PredType
ty2
= CtEvidence
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_app CtEvidence
ev PredType
t1 PredType
s1 PredType
t2 PredType
s2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
_ (AppTy PredType
t2 PredType
s2) PredType
_
| EqRel
NomEq <- EqRel
eq_rel
, Just (PredType
t1, PredType
s1) <- PredType -> Maybe (PredType, PredType)
tcSplitAppTy_maybe PredType
ty1
= CtEvidence
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_app CtEvidence
ev PredType
t1 PredType
s1 PredType
t2 PredType
s2
can_eq_nc' Bool
False GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel PredType
_ PredType
ps_ty1 PredType
_ PredType
ps_ty2
= do { (PredType
xi1, TcCoercion
co1) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev PredType
ps_ty1
; (PredType
xi2, TcCoercion
co2) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev PredType
ps_ty2
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped PredType
xi1 PredType
xi2 TcCoercion
co1 TcCoercion
co2
; Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
True GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
new_ev EqRel
eq_rel PredType
xi1 PredType
xi1 PredType
xi2 PredType
xi2 }
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel PredType
_ PredType
ps_ty1 PredType
_ PredType
ps_ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"can_eq_nc' catch-all case" (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ps_ty1 SDoc -> SDoc -> SDoc
$$ PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ps_ty2)
; case EqRel
eq_rel of
EqRel
ReprEq -> Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkIrredCt CtEvidence
ev)
EqRel
NomEq -> Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkInsolubleCt CtEvidence
ev) }
can_eq_nc_forall :: CtEvidence -> EqRel
-> Type -> Type
-> TcS (StopOrContinue Ct)
can_eq_nc_forall :: CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
can_eq_nc_forall CtEvidence
ev EqRel
eq_rel PredType
s1 PredType
s2
| CtWanted { ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc, ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
orig_dest } <- CtEvidence
ev
= do { let free_tvs :: VarSet
free_tvs = [PredType] -> VarSet
tyCoVarsOfTypes [PredType
s1,PredType
s2]
([TyCoVarBinder]
bndrs1, PredType
phi1) = PredType -> ([TyCoVarBinder], PredType)
tcSplitForAllVarBndrs PredType
s1
([TyCoVarBinder]
bndrs2, PredType
phi2) = PredType -> ([TyCoVarBinder], PredType)
tcSplitForAllVarBndrs PredType
s2
; if Bool -> Bool
not ([TyCoVarBinder] -> [TyCoVarBinder] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [TyCoVarBinder]
bndrs1 [TyCoVarBinder]
bndrs2)
then do { String -> SDoc -> TcS ()
traceTcS String
"Forall failure" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
s1, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
s2, [TyCoVarBinder] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVarBinder]
bndrs1, [TyCoVarBinder] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVarBinder]
bndrs2
, [ArgFlag] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((TyCoVarBinder -> ArgFlag) -> [TyCoVarBinder] -> [ArgFlag]
forall a b. (a -> b) -> [a] -> [b]
map TyCoVarBinder -> ArgFlag
forall tv argf. VarBndr tv argf -> argf
binderArgFlag [TyCoVarBinder]
bndrs1)
, [ArgFlag] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((TyCoVarBinder -> ArgFlag) -> [TyCoVarBinder] -> [ArgFlag]
forall a b. (a -> b) -> [a] -> [b]
map TyCoVarBinder -> ArgFlag
forall tv argf. VarBndr tv argf -> argf
binderArgFlag [TyCoVarBinder]
bndrs2) ]
; CtEvidence -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev PredType
s1 PredType
s2 }
else
do { String -> SDoc -> TcS ()
traceTcS String
"Creating implication for polytype equality" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
; let empty_subst1 :: TCvSubst
empty_subst1 = InScopeSet -> TCvSubst
mkEmptyTCvSubst (InScopeSet -> TCvSubst) -> InScopeSet -> TCvSubst
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet VarSet
free_tvs
; (TCvSubst
subst1, [TcTyVar]
skol_tvs) <- TCvSubst -> [TcTyVar] -> TcS (TCvSubst, [TcTyVar])
tcInstSkolTyVarsX TCvSubst
empty_subst1 ([TcTyVar] -> TcS (TCvSubst, [TcTyVar]))
-> [TcTyVar] -> TcS (TCvSubst, [TcTyVar])
forall a b. (a -> b) -> a -> b
$
[TyCoVarBinder] -> [TcTyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyCoVarBinder]
bndrs1
; let skol_info :: SkolemInfo
skol_info = PredType -> SkolemInfo
UnifyForAllSkol PredType
phi1
phi1' :: PredType
phi1' = HasCallStack => TCvSubst -> PredType -> PredType
TCvSubst -> PredType -> PredType
substTy TCvSubst
subst1 PredType
phi1
go :: [TcTyVar] -> TCvSubst -> [TyVarBinder]
-> TcS (TcCoercion, Cts)
go :: [TcTyVar] -> TCvSubst -> [TyCoVarBinder] -> TcS (TcCoercion, Cts)
go (TcTyVar
skol_tv:[TcTyVar]
skol_tvs) TCvSubst
subst (TyCoVarBinder
bndr2:[TyCoVarBinder]
bndrs2)
= do { let tv2 :: TcTyVar
tv2 = TyCoVarBinder -> TcTyVar
forall tv argf. VarBndr tv argf -> tv
binderVar TyCoVarBinder
bndr2
; (TcCoercion
kind_co, Cts
wanteds1) <- CtLoc -> Role -> PredType -> PredType -> TcS (TcCoercion, Cts)
unify CtLoc
loc Role
Nominal (TcTyVar -> PredType
tyVarKind TcTyVar
skol_tv)
(HasCallStack => TCvSubst -> PredType -> PredType
TCvSubst -> PredType -> PredType
substTy TCvSubst
subst (TcTyVar -> PredType
tyVarKind TcTyVar
tv2))
; let subst' :: TCvSubst
subst' = TCvSubst -> TcTyVar -> PredType -> TCvSubst
extendTvSubstAndInScope TCvSubst
subst TcTyVar
tv2
(PredType -> TcCoercion -> PredType
mkCastTy (TcTyVar -> PredType
mkTyVarTy TcTyVar
skol_tv) TcCoercion
kind_co)
; (TcCoercion
co, Cts
wanteds2) <- [TcTyVar] -> TCvSubst -> [TyCoVarBinder] -> TcS (TcCoercion, Cts)
go [TcTyVar]
skol_tvs TCvSubst
subst' [TyCoVarBinder]
bndrs2
; (TcCoercion, Cts) -> TcS (TcCoercion, Cts)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TcTyVar -> TcCoercion -> TcCoercion -> TcCoercion
mkTcForAllCo TcTyVar
skol_tv TcCoercion
kind_co TcCoercion
co
, Cts
wanteds1 Cts -> Cts -> Cts
forall a. Bag a -> Bag a -> Bag a
`unionBags` Cts
wanteds2 ) }
go [] TCvSubst
subst [TyCoVarBinder]
bndrs2
= ASSERT( null bndrs2 )
CtLoc -> Role -> PredType -> PredType -> TcS (TcCoercion, Cts)
unify CtLoc
loc (EqRel -> Role
eqRelRole EqRel
eq_rel) PredType
phi1' (TCvSubst -> PredType -> PredType
substTyUnchecked TCvSubst
subst PredType
phi2)
go [TcTyVar]
_ TCvSubst
_ [TyCoVarBinder]
_ = String -> TcS (TcCoercion, Cts)
forall a. String -> a
panic String
"cna_eq_nc_forall"
empty_subst2 :: TCvSubst
empty_subst2 = InScopeSet -> TCvSubst
mkEmptyTCvSubst (TCvSubst -> InScopeSet
getTCvInScope TCvSubst
subst1)
; TcCoercion
all_co <- SkolemInfo -> [TcTyVar] -> TcS (TcCoercion, Cts) -> TcS TcCoercion
forall result.
SkolemInfo -> [TcTyVar] -> TcS (result, Cts) -> TcS result
checkTvConstraintsTcS SkolemInfo
skol_info [TcTyVar]
skol_tvs (TcS (TcCoercion, Cts) -> TcS TcCoercion)
-> TcS (TcCoercion, Cts) -> TcS TcCoercion
forall a b. (a -> b) -> a -> b
$
[TcTyVar] -> TCvSubst -> [TyCoVarBinder] -> TcS (TcCoercion, Cts)
go [TcTyVar]
skol_tvs TCvSubst
empty_subst2 [TyCoVarBinder]
bndrs2
; TcEvDest -> TcCoercion -> TcS ()
setWantedEq TcEvDest
orig_dest TcCoercion
all_co
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Deferred polytype equality" } }
| Bool
otherwise
= do { String -> SDoc -> TcS ()
traceTcS String
"Omitting decomposition of given polytype equality" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
PredType -> PredType -> SDoc
pprEq PredType
s1 PredType
s2
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Discard given polytype equality" }
where
unify :: CtLoc -> Role -> TcType -> TcType -> TcS (TcCoercion, Cts)
unify :: CtLoc -> Role -> PredType -> PredType -> TcS (TcCoercion, Cts)
unify CtLoc
loc Role
role PredType
ty1 PredType
ty2
| PredType
ty1 HasDebugCallStack => PredType -> PredType -> Bool
PredType -> PredType -> Bool
`tcEqType` PredType
ty2
= (TcCoercion, Cts) -> TcS (TcCoercion, Cts)
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> PredType -> TcCoercion
mkTcReflCo Role
role PredType
ty1, Cts
forall a. Bag a
emptyBag)
| Bool
otherwise
= do { (CtEvidence
wanted, TcCoercion
co) <- CtLoc
-> Role -> PredType -> PredType -> TcS (CtEvidence, TcCoercion)
newWantedEq CtLoc
loc Role
role PredType
ty1 PredType
ty2
; (TcCoercion, Cts) -> TcS (TcCoercion, Cts)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercion
co, Ct -> Cts
forall a. a -> Bag a
unitBag (CtEvidence -> Ct
mkNonCanonical CtEvidence
wanted)) }
zonk_eq_types :: TcType -> TcType -> TcS (Either (Pair TcType) TcType)
zonk_eq_types :: PredType -> PredType -> TcS (Either (Pair PredType) PredType)
zonk_eq_types = PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go
where
go :: PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go (TyVarTy TcTyVar
tv1) (TyVarTy TcTyVar
tv2) = TcTyVar -> TcTyVar -> TcS (Either (Pair PredType) PredType)
tyvar_tyvar TcTyVar
tv1 TcTyVar
tv2
go (TyVarTy TcTyVar
tv1) PredType
ty2 = SwapFlag
-> TcTyVar -> PredType -> TcS (Either (Pair PredType) PredType)
tyvar SwapFlag
NotSwapped TcTyVar
tv1 PredType
ty2
go PredType
ty1 (TyVarTy TcTyVar
tv2) = SwapFlag
-> TcTyVar -> PredType -> TcS (Either (Pair PredType) PredType)
tyvar SwapFlag
IsSwapped TcTyVar
tv2 PredType
ty1
go PredType
ty1 PredType
ty2
| Just (PredType
arg1, PredType
res1) <- Maybe (PredType, PredType)
split1
, Just (PredType
arg2, PredType
res2) <- Maybe (PredType, PredType)
split2
= do { Either (Pair PredType) PredType
res_a <- PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go PredType
arg1 PredType
arg2
; Either (Pair PredType) PredType
res_b <- PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go PredType
res1 PredType
res2
; Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType))
-> Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall a b. (a -> b) -> a -> b
$ (PredType -> PredType -> PredType)
-> Either (Pair PredType) PredType
-> Either (Pair PredType) PredType
-> Either (Pair PredType) PredType
forall a b c.
(a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev PredType -> PredType -> PredType
mkVisFunTy Either (Pair PredType) PredType
res_b Either (Pair PredType) PredType
res_a
}
| Maybe (PredType, PredType) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (PredType, PredType)
split1 Bool -> Bool -> Bool
|| Maybe (PredType, PredType) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (PredType, PredType)
split2
= PredType -> PredType -> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a b.
Monad m =>
a -> a -> m (Either (Pair a) b)
bale_out PredType
ty1 PredType
ty2
where
split1 :: Maybe (PredType, PredType)
split1 = PredType -> Maybe (PredType, PredType)
tcSplitFunTy_maybe PredType
ty1
split2 :: Maybe (PredType, PredType)
split2 = PredType -> Maybe (PredType, PredType)
tcSplitFunTy_maybe PredType
ty2
go PredType
ty1 PredType
ty2
| Just (TyCon
tc1, [PredType]
tys1) <- HasDebugCallStack => PredType -> Maybe (TyCon, [PredType])
PredType -> Maybe (TyCon, [PredType])
repSplitTyConApp_maybe PredType
ty1
, Just (TyCon
tc2, [PredType]
tys2) <- HasDebugCallStack => PredType -> Maybe (TyCon, [PredType])
PredType -> Maybe (TyCon, [PredType])
repSplitTyConApp_maybe PredType
ty2
= if TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2 Bool -> Bool -> Bool
&& [PredType]
tys1 [PredType] -> [PredType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [PredType]
tys2
then TyCon
-> [PredType]
-> [PredType]
-> TcS (Either (Pair PredType) PredType)
tycon TyCon
tc1 [PredType]
tys1 [PredType]
tys2
else PredType -> PredType -> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a b.
Monad m =>
a -> a -> m (Either (Pair a) b)
bale_out PredType
ty1 PredType
ty2
go PredType
ty1 PredType
ty2
| Just (PredType
ty1a, PredType
ty1b) <- PredType -> Maybe (PredType, PredType)
tcRepSplitAppTy_maybe PredType
ty1
, Just (PredType
ty2a, PredType
ty2b) <- PredType -> Maybe (PredType, PredType)
tcRepSplitAppTy_maybe PredType
ty2
= do { Either (Pair PredType) PredType
res_a <- PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go PredType
ty1a PredType
ty2a
; Either (Pair PredType) PredType
res_b <- PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go PredType
ty1b PredType
ty2b
; Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType))
-> Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall a b. (a -> b) -> a -> b
$ (PredType -> PredType -> PredType)
-> Either (Pair PredType) PredType
-> Either (Pair PredType) PredType
-> Either (Pair PredType) PredType
forall a b c.
(a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev PredType -> PredType -> PredType
mkAppTy Either (Pair PredType) PredType
res_b Either (Pair PredType) PredType
res_a }
go ty1 :: PredType
ty1@(LitTy TyLit
lit1) (LitTy TyLit
lit2)
| TyLit
lit1 TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
lit2
= Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a. Monad m => a -> m a
return (PredType -> Either (Pair PredType) PredType
forall a b. b -> Either a b
Right PredType
ty1)
go PredType
ty1 PredType
ty2 = PredType -> PredType -> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a b.
Monad m =>
a -> a -> m (Either (Pair a) b)
bale_out PredType
ty1 PredType
ty2
bale_out :: a -> a -> m (Either (Pair a) b)
bale_out a
ty1 a
ty2 = Either (Pair a) b -> m (Either (Pair a) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair a) b -> m (Either (Pair a) b))
-> Either (Pair a) b -> m (Either (Pair a) b)
forall a b. (a -> b) -> a -> b
$ Pair a -> Either (Pair a) b
forall a b. a -> Either a b
Left (a -> a -> Pair a
forall a. a -> a -> Pair a
Pair a
ty1 a
ty2)
tyvar :: SwapFlag -> TcTyVar -> TcType
-> TcS (Either (Pair TcType) TcType)
tyvar :: SwapFlag
-> TcTyVar -> PredType -> TcS (Either (Pair PredType) PredType)
tyvar SwapFlag
swapped TcTyVar
tv PredType
ty
= case TcTyVar -> TcTyVarDetails
tcTyVarDetails TcTyVar
tv of
MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
mtv_ref = IORef MetaDetails
ref }
-> do { MetaDetails
cts <- IORef MetaDetails -> TcS MetaDetails
forall a. TcRef a -> TcS a
readTcRef IORef MetaDetails
ref
; case MetaDetails
cts of
MetaDetails
Flexi -> TcS (Either (Pair PredType) PredType)
forall b. TcS (Either (Pair PredType) b)
give_up
Indirect PredType
ty' -> do { TcTyVar -> PredType -> TcS ()
forall a a. (Outputable a, Outputable a) => a -> a -> TcS ()
trace_indirect TcTyVar
tv PredType
ty'
; SwapFlag
-> (PredType -> PredType -> TcS (Either (Pair PredType) PredType))
-> PredType
-> PredType
-> TcS (Either (Pair PredType) PredType)
forall a b. SwapFlag -> (a -> a -> b) -> a -> a -> b
unSwap SwapFlag
swapped PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go PredType
ty' PredType
ty } }
TcTyVarDetails
_ -> TcS (Either (Pair PredType) PredType)
forall b. TcS (Either (Pair PredType) b)
give_up
where
give_up :: TcS (Either (Pair PredType) b)
give_up = Either (Pair PredType) b -> TcS (Either (Pair PredType) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair PredType) b -> TcS (Either (Pair PredType) b))
-> Either (Pair PredType) b -> TcS (Either (Pair PredType) b)
forall a b. (a -> b) -> a -> b
$ Pair PredType -> Either (Pair PredType) b
forall a b. a -> Either a b
Left (Pair PredType -> Either (Pair PredType) b)
-> Pair PredType -> Either (Pair PredType) b
forall a b. (a -> b) -> a -> b
$ SwapFlag
-> (PredType -> PredType -> Pair PredType)
-> PredType
-> PredType
-> Pair PredType
forall a b. SwapFlag -> (a -> a -> b) -> a -> a -> b
unSwap SwapFlag
swapped PredType -> PredType -> Pair PredType
forall a. a -> a -> Pair a
Pair (TcTyVar -> PredType
mkTyVarTy TcTyVar
tv) PredType
ty
tyvar_tyvar :: TcTyVar -> TcTyVar -> TcS (Either (Pair PredType) PredType)
tyvar_tyvar TcTyVar
tv1 TcTyVar
tv2
| TcTyVar
tv1 TcTyVar -> TcTyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TcTyVar
tv2 = Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a. Monad m => a -> m a
return (PredType -> Either (Pair PredType) PredType
forall a b. b -> Either a b
Right (TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1))
| Bool
otherwise = do { (PredType
ty1', Bool
progress1) <- TcTyVar -> TcS (PredType, Bool)
quick_zonk TcTyVar
tv1
; (PredType
ty2', Bool
progress2) <- TcTyVar -> TcS (PredType, Bool)
quick_zonk TcTyVar
tv2
; if Bool
progress1 Bool -> Bool -> Bool
|| Bool
progress2
then PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go PredType
ty1' PredType
ty2'
else Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType))
-> Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall a b. (a -> b) -> a -> b
$ Pair PredType -> Either (Pair PredType) PredType
forall a b. a -> Either a b
Left (PredType -> PredType -> Pair PredType
forall a. a -> a -> Pair a
Pair (TcTyVar -> PredType
TyVarTy TcTyVar
tv1) (TcTyVar -> PredType
TyVarTy TcTyVar
tv2)) }
trace_indirect :: a -> a -> TcS ()
trace_indirect a
tv a
ty
= String -> SDoc -> TcS ()
traceTcS String
"Following filled tyvar (zonk_eq_types)"
(a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
tv SDoc -> SDoc -> SDoc
<+> SDoc
equals SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
ty)
quick_zonk :: TcTyVar -> TcS (PredType, Bool)
quick_zonk TcTyVar
tv = case TcTyVar -> TcTyVarDetails
tcTyVarDetails TcTyVar
tv of
MetaTv { mtv_ref :: TcTyVarDetails -> IORef MetaDetails
mtv_ref = IORef MetaDetails
ref }
-> do { MetaDetails
cts <- IORef MetaDetails -> TcS MetaDetails
forall a. TcRef a -> TcS a
readTcRef IORef MetaDetails
ref
; case MetaDetails
cts of
MetaDetails
Flexi -> (PredType, Bool) -> TcS (PredType, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVar -> PredType
TyVarTy TcTyVar
tv, Bool
False)
Indirect PredType
ty' -> do { TcTyVar -> PredType -> TcS ()
forall a a. (Outputable a, Outputable a) => a -> a -> TcS ()
trace_indirect TcTyVar
tv PredType
ty'
; (PredType, Bool) -> TcS (PredType, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (PredType
ty', Bool
True) } }
TcTyVarDetails
_ -> (PredType, Bool) -> TcS (PredType, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVar -> PredType
TyVarTy TcTyVar
tv, Bool
False)
tycon :: TyCon -> [TcType] -> [TcType]
-> TcS (Either (Pair TcType) TcType)
tycon :: TyCon
-> [PredType]
-> [PredType]
-> TcS (Either (Pair PredType) PredType)
tycon TyCon
tc [PredType]
tys1 [PredType]
tys2
= do { [Either (Pair PredType) PredType]
results <- (PredType -> PredType -> TcS (Either (Pair PredType) PredType))
-> [PredType]
-> [PredType]
-> TcS [Either (Pair PredType) PredType]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM PredType -> PredType -> TcS (Either (Pair PredType) PredType)
go [PredType]
tys1 [PredType]
tys2
; Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType))
-> Either (Pair PredType) PredType
-> TcS (Either (Pair PredType) PredType)
forall a b. (a -> b) -> a -> b
$ case [Either (Pair PredType) PredType]
-> Either (Pair [PredType]) [PredType]
combine_results [Either (Pair PredType) PredType]
results of
Left Pair [PredType]
tys -> Pair PredType -> Either (Pair PredType) PredType
forall a b. a -> Either a b
Left (TyCon -> [PredType] -> PredType
mkTyConApp TyCon
tc ([PredType] -> PredType) -> Pair [PredType] -> Pair PredType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair [PredType]
tys)
Right [PredType]
tys -> PredType -> Either (Pair PredType) PredType
forall a b. b -> Either a b
Right (TyCon -> [PredType] -> PredType
mkTyConApp TyCon
tc [PredType]
tys) }
combine_results :: [Either (Pair TcType) TcType]
-> Either (Pair [TcType]) [TcType]
combine_results :: [Either (Pair PredType) PredType]
-> Either (Pair [PredType]) [PredType]
combine_results = (Pair [PredType] -> Pair [PredType])
-> ([PredType] -> [PredType])
-> Either (Pair [PredType]) [PredType]
-> Either (Pair [PredType]) [PredType]
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (([PredType] -> [PredType]) -> Pair [PredType] -> Pair [PredType]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [PredType] -> [PredType]
forall a. [a] -> [a]
reverse) [PredType] -> [PredType]
forall a. [a] -> [a]
reverse (Either (Pair [PredType]) [PredType]
-> Either (Pair [PredType]) [PredType])
-> ([Either (Pair PredType) PredType]
-> Either (Pair [PredType]) [PredType])
-> [Either (Pair PredType) PredType]
-> Either (Pair [PredType]) [PredType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Either (Pair [PredType]) [PredType]
-> Either (Pair PredType) PredType
-> Either (Pair [PredType]) [PredType])
-> Either (Pair [PredType]) [PredType]
-> [Either (Pair PredType) PredType]
-> Either (Pair [PredType]) [PredType]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((PredType -> [PredType] -> [PredType])
-> Either (Pair [PredType]) [PredType]
-> Either (Pair PredType) PredType
-> Either (Pair [PredType]) [PredType]
forall a b c.
(a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev (:)) ([PredType] -> Either (Pair [PredType]) [PredType]
forall a b. b -> Either a b
Right [])
combine_rev :: (a -> b -> c)
-> Either (Pair b) b
-> Either (Pair a) a
-> Either (Pair c) c
combine_rev :: (a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev a -> b -> c
f (Left Pair b
list) (Left Pair a
elt) = Pair c -> Either (Pair c) c
forall a b. a -> Either a b
Left (a -> b -> c
f (a -> b -> c) -> Pair a -> Pair (b -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair a
elt Pair (b -> c) -> Pair b -> Pair c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Pair b
list)
combine_rev a -> b -> c
f (Left Pair b
list) (Right a
ty) = Pair c -> Either (Pair c) c
forall a b. a -> Either a b
Left (a -> b -> c
f (a -> b -> c) -> Pair a -> Pair (b -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> Pair a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
ty Pair (b -> c) -> Pair b -> Pair c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Pair b
list)
combine_rev a -> b -> c
f (Right b
tys) (Left Pair a
elt) = Pair c -> Either (Pair c) c
forall a b. a -> Either a b
Left (a -> b -> c
f (a -> b -> c) -> Pair a -> Pair (b -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair a
elt Pair (b -> c) -> Pair b -> Pair c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> b -> Pair b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
tys)
combine_rev a -> b -> c
f (Right b
tys) (Right a
ty) = c -> Either (Pair c) c
forall a b. b -> Either a b
Right (a -> b -> c
f a
ty b
tys)
can_eq_newtype_nc :: CtEvidence
-> SwapFlag
-> TcType
-> ((Bag GlobalRdrElt, TcCoercion), TcType)
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc :: CtEvidence
-> SwapFlag
-> PredType
-> ((Bag GlobalRdrElt, TcCoercion), PredType)
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc CtEvidence
ev SwapFlag
swapped PredType
ty1 ((Bag GlobalRdrElt
gres, TcCoercion
co), PredType
ty1') PredType
ty2 PredType
ps_ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"can_eq_newtype_nc" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev, SwapFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr SwapFlag
swapped, TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
co, Bag GlobalRdrElt -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bag GlobalRdrElt
gres, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty1', PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty2 ]
; CtLoc -> PredType -> TcS ()
checkReductionDepth (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) PredType
ty1
; [GlobalRdrElt] -> TcS ()
addUsedGREs [GlobalRdrElt]
gre_list
; (Name -> TcS ()) -> [Name] -> TcS ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Name -> TcS ()
keepAlive ([Name] -> TcS ()) -> [Name] -> TcS ()
forall a b. (a -> b) -> a -> b
$ (GlobalRdrElt -> Name) -> [GlobalRdrElt] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> Name
gre_name [GlobalRdrElt]
gre_list
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
ty1' PredType
ps_ty2
(TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co) (Role -> PredType -> TcCoercion
mkTcReflCo Role
Representational PredType
ps_ty2)
; Bool
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
False CtEvidence
new_ev EqRel
ReprEq PredType
ty1' PredType
ty1' PredType
ty2 PredType
ps_ty2 }
where
gre_list :: [GlobalRdrElt]
gre_list = Bag GlobalRdrElt -> [GlobalRdrElt]
forall a. Bag a -> [a]
bagToList Bag GlobalRdrElt
gres
can_eq_app :: CtEvidence
-> Xi -> Xi
-> Xi -> Xi
-> TcS (StopOrContinue Ct)
can_eq_app :: CtEvidence
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_app CtEvidence
ev PredType
s1 PredType
t1 PredType
s2 PredType
t2
| CtDerived {} <- CtEvidence
ev
= do { CtLoc -> [Role] -> [PredType] -> [PredType] -> TcS ()
unifyDeriveds CtLoc
loc [Role
Nominal, Role
Nominal] [PredType
s1, PredType
t1] [PredType
s2, PredType
t2]
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Decomposed [D] AppTy" }
| CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest } <- CtEvidence
ev
= do { TcCoercion
co_s <- CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Nominal PredType
s1 PredType
s2
; let arg_loc :: CtLoc
arg_loc
| PredType -> Bool
isNextArgVisible PredType
s1 = CtLoc
loc
| Bool
otherwise = CtLoc -> (CtOrigin -> CtOrigin) -> CtLoc
updateCtLocOrigin CtLoc
loc CtOrigin -> CtOrigin
toInvisibleOrigin
; TcCoercion
co_t <- CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
arg_loc Role
Nominal PredType
t1 PredType
t2
; let co :: TcCoercion
co = TcCoercion -> TcCoercion -> TcCoercion
mkAppCo TcCoercion
co_s TcCoercion
co_t
; TcEvDest -> TcCoercion -> TcS ()
setWantedEq TcEvDest
dest TcCoercion
co
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Decomposed [W] AppTy" }
| PredType
s1k PredType -> PredType -> Bool
`mismatches` PredType
s2k
= CtEvidence -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev (PredType
s1 PredType -> PredType -> PredType
`mkAppTy` PredType
t1) (PredType
s2 PredType -> PredType -> PredType
`mkAppTy` PredType
t2)
| CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
evar } <- CtEvidence
ev
= do { let co :: TcCoercion
co = TcTyVar -> TcCoercion
mkTcCoVarCo TcTyVar
evar
co_s :: TcCoercion
co_s = LeftOrRight -> TcCoercion -> TcCoercion
mkTcLRCo LeftOrRight
CLeft TcCoercion
co
co_t :: TcCoercion
co_t = LeftOrRight -> TcCoercion -> TcCoercion
mkTcLRCo LeftOrRight
CRight TcCoercion
co
; CtEvidence
evar_s <- CtLoc -> (PredType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc ( CtEvidence -> PredType -> PredType -> PredType
mkTcEqPredLikeEv CtEvidence
ev PredType
s1 PredType
s2
, TcCoercion -> EvTerm
evCoercion TcCoercion
co_s )
; CtEvidence
evar_t <- CtLoc -> (PredType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc ( CtEvidence -> PredType -> PredType -> PredType
mkTcEqPredLikeEv CtEvidence
ev PredType
t1 PredType
t2
, TcCoercion -> EvTerm
evCoercion TcCoercion
co_t )
; [CtEvidence] -> TcS ()
emitWorkNC [CtEvidence
evar_t]
; CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
evar_s EqRel
NomEq PredType
s1 PredType
s2 }
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
s1k :: PredType
s1k = HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind PredType
s1
s2k :: PredType
s2k = HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind PredType
s2
PredType
k1 mismatches :: PredType -> PredType -> Bool
`mismatches` PredType
k2
= PredType -> Bool
isForAllTy PredType
k1 Bool -> Bool -> Bool
&& Bool -> Bool
not (PredType -> Bool
isForAllTy PredType
k2)
Bool -> Bool -> Bool
|| Bool -> Bool
not (PredType -> Bool
isForAllTy PredType
k1) Bool -> Bool -> Bool
&& PredType -> Bool
isForAllTy PredType
k2
canEqCast :: Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType -> Coercion
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqCast :: Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> PredType
-> TcCoercion
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqCast Bool
flat CtEvidence
ev EqRel
eq_rel SwapFlag
swapped PredType
ty1 TcCoercion
co1 PredType
ty2 PredType
ps_ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"Decomposing cast" ([SDoc] -> SDoc
vcat [ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty1 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"|>" SDoc -> SDoc -> SDoc
<+> TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
co1
, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ps_ty2 ])
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
ty1 PredType
ps_ty2
(Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflRightCo Role
role PredType
ty1 TcCoercion
co1)
(Role -> PredType -> TcCoercion
mkTcReflCo Role
role PredType
ps_ty2)
; Bool
-> CtEvidence
-> EqRel
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
flat CtEvidence
new_ev EqRel
eq_rel PredType
ty1 PredType
ty1 PredType
ty2 PredType
ps_ty2 }
where
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
canTyConApp :: CtEvidence -> EqRel
-> TyCon -> [TcType]
-> TyCon -> [TcType]
-> TcS (StopOrContinue Ct)
canTyConApp :: CtEvidence
-> EqRel
-> TyCon
-> [PredType]
-> TyCon
-> [PredType]
-> TcS (StopOrContinue Ct)
canTyConApp CtEvidence
ev EqRel
eq_rel TyCon
tc1 [PredType]
tys1 TyCon
tc2 [PredType]
tys2
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2
, [PredType]
tys1 [PredType] -> [PredType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [PredType]
tys2
= do { InertSet
inerts <- TcS InertSet
getTcSInerts
; if InertSet -> Bool
can_decompose InertSet
inerts
then do { String -> SDoc -> TcS ()
traceTcS String
"canTyConApp"
(CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev SDoc -> SDoc -> SDoc
$$ EqRel -> SDoc
forall a. Outputable a => a -> SDoc
ppr EqRel
eq_rel SDoc -> SDoc -> SDoc
$$ TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc1 SDoc -> SDoc -> SDoc
$$ [PredType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [PredType]
tys1 SDoc -> SDoc -> SDoc
$$ [PredType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [PredType]
tys2)
; CtEvidence -> EqRel -> TyCon -> [PredType] -> [PredType] -> TcS ()
canDecomposableTyConAppOK CtEvidence
ev EqRel
eq_rel TyCon
tc1 [PredType]
tys1 [PredType]
tys2
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Decomposed TyConApp" }
else CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqFailure CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ty2 }
| TyCon -> Bool
tyConSkolem TyCon
tc1 Bool -> Bool -> Bool
|| TyCon -> Bool
tyConSkolem TyCon
tc2
= do { String -> SDoc -> TcS ()
traceTcS String
"canTyConApp: skolem abstract" (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc1 SDoc -> SDoc -> SDoc
$$ TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc2)
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkIrredCt CtEvidence
ev) }
| EqRel
eq_rel EqRel -> EqRel -> Bool
forall a. Eq a => a -> a -> Bool
== EqRel
ReprEq Bool -> Bool -> Bool
&& Bool -> Bool
not (TyCon -> Role -> Bool
isGenerativeTyCon TyCon
tc1 Role
Representational Bool -> Bool -> Bool
&&
TyCon -> Role -> Bool
isGenerativeTyCon TyCon
tc2 Role
Representational)
= CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqFailure CtEvidence
ev EqRel
eq_rel PredType
ty1 PredType
ty2
| Bool
otherwise
= CtEvidence -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev PredType
ty1 PredType
ty2
where
ty1 :: PredType
ty1 = TyCon -> [PredType] -> PredType
mkTyConApp TyCon
tc1 [PredType]
tys1
ty2 :: PredType
ty2 = TyCon -> [PredType] -> PredType
mkTyConApp TyCon
tc2 [PredType]
tys2
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
pred :: PredType
pred = CtEvidence -> PredType
ctEvPred CtEvidence
ev
can_decompose :: InertSet -> Bool
can_decompose InertSet
inerts
= TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc1 (EqRel -> Role
eqRelRole EqRel
eq_rel)
Bool -> Bool -> Bool
|| (CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev CtFlavour -> CtFlavour -> Bool
forall a. Eq a => a -> a -> Bool
/= CtFlavour
Given Bool -> Bool -> Bool
&& Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag (CtLoc -> PredType -> InertSet -> Cts
matchableGivens CtLoc
loc PredType
pred InertSet
inerts))
canDecomposableTyConAppOK :: CtEvidence -> EqRel
-> TyCon -> [TcType] -> [TcType]
-> TcS ()
canDecomposableTyConAppOK :: CtEvidence -> EqRel -> TyCon -> [PredType] -> [PredType] -> TcS ()
canDecomposableTyConAppOK CtEvidence
ev EqRel
eq_rel TyCon
tc [PredType]
tys1 [PredType]
tys2
= ASSERT( tys1 `equalLength` tys2 )
case CtEvidence
ev of
CtDerived {}
-> CtLoc -> [Role] -> [PredType] -> [PredType] -> TcS ()
unifyDeriveds CtLoc
loc [Role]
tc_roles [PredType]
tys1 [PredType]
tys2
CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest }
-> do { [TcCoercion]
cos <- (CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion)
-> [CtLoc]
-> [Role]
-> [PredType]
-> [PredType]
-> TcS [TcCoercion]
forall (m :: * -> *) a b c d e.
Monad m =>
(a -> b -> c -> d -> m e) -> [a] -> [b] -> [c] -> [d] -> m [e]
zipWith4M CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted [CtLoc]
new_locs [Role]
tc_roles [PredType]
tys1 [PredType]
tys2
; TcEvDest -> TcCoercion -> TcS ()
setWantedEq TcEvDest
dest (HasDebugCallStack => Role -> TyCon -> [TcCoercion] -> TcCoercion
Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTyConAppCo Role
role TyCon
tc [TcCoercion]
cos) }
CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
evar }
-> do { let ev_co :: TcCoercion
ev_co = TcTyVar -> TcCoercion
mkCoVarCo TcTyVar
evar
; [CtEvidence]
given_evs <- CtLoc -> [(PredType, EvTerm)] -> TcS [CtEvidence]
newGivenEvVars CtLoc
loc ([(PredType, EvTerm)] -> TcS [CtEvidence])
-> [(PredType, EvTerm)] -> TcS [CtEvidence]
forall a b. (a -> b) -> a -> b
$
[ ( Role -> PredType -> PredType -> PredType
mkPrimEqPredRole Role
r PredType
ty1 PredType
ty2
, TcCoercion -> EvTerm
evCoercion (TcCoercion -> EvTerm) -> TcCoercion -> EvTerm
forall a b. (a -> b) -> a -> b
$ HasDebugCallStack => Role -> Int -> TcCoercion -> TcCoercion
Role -> Int -> TcCoercion -> TcCoercion
mkNthCo Role
r Int
i TcCoercion
ev_co )
| (Role
r, PredType
ty1, PredType
ty2, Int
i) <- [Role]
-> [PredType]
-> [PredType]
-> [Int]
-> [(Role, PredType, PredType, Int)]
forall a b c d. [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip4 [Role]
tc_roles [PredType]
tys1 [PredType]
tys2 [Int
0..]
, Role
r Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
/= Role
Phantom
, Bool -> Bool
not (PredType -> Bool
isCoercionTy PredType
ty1) Bool -> Bool -> Bool
&& Bool -> Bool
not (PredType -> Bool
isCoercionTy PredType
ty2) ]
; [CtEvidence] -> TcS ()
emitWorkNC [CtEvidence]
given_evs }
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
tc_roles :: [Role]
tc_roles = Role -> TyCon -> [Role]
tyConRolesX Role
role TyCon
tc
new_locs :: [CtLoc]
new_locs = [ CtLoc
new_loc
| TyConBinder
bndr <- TyCon -> [TyConBinder]
tyConBinders TyCon
tc
, let new_loc0 :: CtLoc
new_loc0 | TyConBinder -> Bool
isNamedTyConBinder TyConBinder
bndr = CtLoc -> CtLoc
toKindLoc CtLoc
loc
| Bool
otherwise = CtLoc
loc
new_loc :: CtLoc
new_loc | TyConBinder -> Bool
forall tv. VarBndr tv TyConBndrVis -> Bool
isVisibleTyConBinder TyConBinder
bndr
= CtLoc -> (CtOrigin -> CtOrigin) -> CtLoc
updateCtLocOrigin CtLoc
new_loc0 CtOrigin -> CtOrigin
toInvisibleOrigin
| Bool
otherwise
= CtLoc
new_loc0 ]
[CtLoc] -> [CtLoc] -> [CtLoc]
forall a. [a] -> [a] -> [a]
++ CtLoc -> [CtLoc]
forall a. a -> [a]
repeat CtLoc
loc
canEqFailure :: CtEvidence -> EqRel
-> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqFailure :: CtEvidence
-> EqRel -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqFailure CtEvidence
ev EqRel
NomEq PredType
ty1 PredType
ty2
= CtEvidence -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev PredType
ty1 PredType
ty2
canEqFailure CtEvidence
ev EqRel
ReprEq PredType
ty1 PredType
ty2
= do { (PredType
xi1, TcCoercion
co1) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev PredType
ty1
; (PredType
xi2, TcCoercion
co2) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev PredType
ty2
; String -> SDoc -> TcS ()
traceTcS String
"canEqFailure with ReprEq" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty1, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
ty2, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
xi1, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
xi2 ]
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped PredType
xi1 PredType
xi2 TcCoercion
co1 TcCoercion
co2
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkIrredCt CtEvidence
new_ev) }
canEqHardFailure :: CtEvidence
-> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure :: CtEvidence -> PredType -> PredType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev PredType
ty1 PredType
ty2
= do { (PredType
s1, TcCoercion
co1) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev PredType
ty1
; (PredType
s2, TcCoercion
co2) <- FlattenMode -> CtEvidence -> PredType -> TcS (PredType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev PredType
ty2
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped PredType
s1 PredType
s2 TcCoercion
co1 TcCoercion
co2
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkInsolubleCt CtEvidence
new_ev) }
canCFunEqCan :: CtEvidence
-> TyCon -> [TcType]
-> TcTyVar
-> TcS (StopOrContinue Ct)
canCFunEqCan :: CtEvidence
-> TyCon -> [PredType] -> TcTyVar -> TcS (StopOrContinue Ct)
canCFunEqCan CtEvidence
ev TyCon
fn [PredType]
tys TcTyVar
fsk
= do { ([PredType]
tys', [TcCoercion]
cos, TcCoercion
kind_co) <- CtEvidence
-> TyCon
-> [PredType]
-> TcS ([PredType], [TcCoercion], TcCoercion)
flattenArgsNom CtEvidence
ev TyCon
fn [PredType]
tys
; let lhs_co :: TcCoercion
lhs_co = Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTcTyConAppCo Role
Nominal TyCon
fn [TcCoercion]
cos
new_lhs :: PredType
new_lhs = TyCon -> [PredType] -> PredType
mkTyConApp TyCon
fn [PredType]
tys'
flav :: CtFlavour
flav = CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev
; (CtEvidence
ev', TcTyVar
fsk')
<- if TcCoercion -> Bool
isTcReflexiveCo TcCoercion
kind_co
then do { String -> SDoc -> TcS ()
traceTcS String
"canCFunEqCan: refl" (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
new_lhs)
; let fsk_ty :: PredType
fsk_ty = TcTyVar -> PredType
mkTyVarTy TcTyVar
fsk
; CtEvidence
ev' <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped PredType
new_lhs PredType
fsk_ty
TcCoercion
lhs_co (PredType -> TcCoercion
mkTcNomReflCo PredType
fsk_ty)
; (CtEvidence, TcTyVar) -> TcS (CtEvidence, TcTyVar)
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence
ev', TcTyVar
fsk) }
else do { String -> SDoc -> TcS ()
traceTcS String
"canCFunEqCan: non-refl" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text String
"Kind co:" SDoc -> SDoc -> SDoc
<+> TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
kind_co
, String -> SDoc
text String
"RHS:" SDoc -> SDoc -> SDoc
<+> TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
fsk SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TcTyVar -> PredType
tyVarKind TcTyVar
fsk)
, String -> SDoc
text String
"LHS:" SDoc -> SDoc -> SDoc
<+> SDoc -> Int -> SDoc -> SDoc
hang (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [PredType] -> PredType
mkTyConApp TyCon
fn [PredType]
tys))
Int
2 (SDoc
dcolon SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind (TyCon -> [PredType] -> PredType
mkTyConApp TyCon
fn [PredType]
tys)))
, String -> SDoc
text String
"New LHS" SDoc -> SDoc -> SDoc
<+> SDoc -> Int -> SDoc -> SDoc
hang (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
new_lhs)
Int
2 (SDoc
dcolon SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind PredType
new_lhs)) ]
; (CtEvidence
ev', TcCoercion
new_co, TcTyVar
new_fsk)
<- CtFlavour
-> CtLoc
-> TyCon
-> [PredType]
-> TcS (CtEvidence, TcCoercion, TcTyVar)
newFlattenSkolem CtFlavour
flav (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) TyCon
fn [PredType]
tys'
; let xi :: PredType
xi = TcTyVar -> PredType
mkTyVarTy TcTyVar
new_fsk PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
kind_co
co :: TcCoercion
co = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
lhs_co TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo`
Role -> PredType -> TcCoercion -> TcCoercion -> TcCoercion
mkTcCoherenceRightCo Role
Nominal
(TcTyVar -> PredType
mkTyVarTy TcTyVar
new_fsk)
TcCoercion
kind_co
TcCoercion
new_co
; String -> SDoc -> TcS ()
traceTcS String
"Discharging fmv/fsk due to hetero flattening" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev)
; CtEvidence -> TcTyVar -> TcCoercion -> PredType -> TcS ()
dischargeFunEq CtEvidence
ev TcTyVar
fsk TcCoercion
co PredType
xi
; (CtEvidence, TcTyVar) -> TcS (CtEvidence, TcTyVar)
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence
ev', TcTyVar
new_fsk) }
; TyCon -> [PredType] -> (TcCoercion, PredType, CtFlavour) -> TcS ()
extendFlatCache TyCon
fn [PredType]
tys' (HasDebugCallStack => CtEvidence -> TcCoercion
CtEvidence -> TcCoercion
ctEvCoercion CtEvidence
ev', TcTyVar -> PredType
mkTyVarTy TcTyVar
fsk', CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev')
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CFunEqCan :: CtEvidence -> TyCon -> [PredType] -> TcTyVar -> Ct
CFunEqCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
ev', cc_fun :: TyCon
cc_fun = TyCon
fn
, cc_tyargs :: [PredType]
cc_tyargs = [PredType]
tys', cc_fsk :: TcTyVar
cc_fsk = TcTyVar
fsk' }) }
canEqTyVar :: CtEvidence
-> EqRel -> SwapFlag
-> TcTyVar
-> TcType
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar :: CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVar CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 PredType
ps_xi1 PredType
xi2 PredType
ps_xi2
| PredType
k1 HasDebugCallStack => PredType -> PredType -> Bool
PredType -> PredType -> Bool
`tcEqType` PredType
k2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 PredType
ps_xi1 PredType
xi2 PredType
ps_xi2
| Bool
otherwise
= do { (PredType
flat_k1, TcCoercion
k1_co) <- CtLoc -> CtFlavour -> PredType -> TcS (PredType, TcCoercion)
flattenKind CtLoc
loc CtFlavour
flav PredType
k1
; (PredType
flat_k2, TcCoercion
k2_co) <- CtLoc -> CtFlavour -> PredType -> TcS (PredType, TcCoercion)
flattenKind CtLoc
loc CtFlavour
flav PredType
k2
; String -> SDoc -> TcS ()
traceTcS String
"canEqTyVar tried flattening kinds"
([SDoc] -> SDoc
vcat [ [SDoc] -> SDoc
sep [ SDoc -> SDoc
parens (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv1 SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
k1)
, String -> SDoc
text String
"~"
, SDoc -> SDoc
parens (PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
xi2 SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
k2) ]
, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
flat_k1
, TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
k1_co
, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
flat_k2
, TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
k2_co ])
; let role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
; if PredType
flat_k1 HasDebugCallStack => PredType -> PredType -> Bool
PredType -> PredType -> Bool
`tcEqType` PredType
flat_k2
then do { let rhs_kind_co :: TcCoercion
rhs_kind_co = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
k2_co TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo` TcCoercion
k1_co
new_rhs :: PredType
new_rhs = PredType
xi2 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
rhs_kind_co
ps_rhs :: PredType
ps_rhs = PredType
ps_xi2 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
rhs_kind_co
rhs_co :: TcCoercion
rhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role PredType
xi2 TcCoercion
rhs_kind_co
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
xi1 PredType
new_rhs
(Role -> PredType -> TcCoercion
mkTcReflCo Role
role PredType
xi1) TcCoercion
rhs_co
; CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
new_ev EqRel
eq_rel SwapFlag
NotSwapped TcTyVar
tv1 PredType
ps_xi1 PredType
new_rhs PredType
ps_rhs }
else
do { let sym_k1_co :: TcCoercion
sym_k1_co = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
k1_co
sym_k2_co :: TcCoercion
sym_k2_co = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
k2_co
new_lhs :: PredType
new_lhs = PredType
xi1 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
sym_k1_co
new_rhs :: PredType
new_rhs = PredType
xi2 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
sym_k2_co
ps_rhs :: PredType
ps_rhs = PredType
ps_xi2 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
sym_k2_co
lhs_co :: TcCoercion
lhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role PredType
xi1 TcCoercion
sym_k1_co
rhs_co :: TcCoercion
rhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role PredType
xi2 TcCoercion
sym_k2_co
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
new_lhs PredType
new_rhs TcCoercion
lhs_co TcCoercion
rhs_co
; CtEvidence
-> EqRel
-> TcTyVar
-> TcCoercion
-> PredType
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVarHetero CtEvidence
new_ev EqRel
eq_rel TcTyVar
tv1 TcCoercion
sym_k1_co PredType
flat_k1 PredType
ps_xi1
PredType
new_rhs PredType
flat_k2 PredType
ps_rhs } }
where
xi1 :: PredType
xi1 = TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1
k1 :: PredType
k1 = TcTyVar -> PredType
tyVarKind TcTyVar
tv1
k2 :: PredType
k2 = HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind PredType
xi2
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
flav :: CtFlavour
flav = CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev
canEqTyVarHetero :: CtEvidence
-> EqRel
-> TcTyVar -> TcCoercionN -> TcKind
-> TcType
-> TcType -> TcKind
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHetero :: CtEvidence
-> EqRel
-> TcTyVar
-> TcCoercion
-> PredType
-> PredType
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVarHetero CtEvidence
ev EqRel
eq_rel TcTyVar
tv1 TcCoercion
co1 PredType
ki1 PredType
ps_tv1 PredType
xi2 PredType
ki2 PredType
ps_xi2
| CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
evar } <- CtEvidence
ev
= do { let kind_co :: TcCoercion
kind_co = TcCoercion -> TcCoercion
mkTcKindCo (TcTyVar -> TcCoercion
mkTcCoVarCo TcTyVar
evar)
; CtEvidence
kind_ev <- CtLoc -> (PredType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
kind_loc (PredType
kind_pty, TcCoercion -> EvTerm
evCoercion TcCoercion
kind_co)
; let
homo_co :: TcCoercion
homo_co = TcCoercion -> TcCoercion
mkTcSymCo (HasDebugCallStack => CtEvidence -> TcCoercion
CtEvidence -> TcCoercion
ctEvCoercion CtEvidence
kind_ev) TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo` TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co1
rhs' :: PredType
rhs' = PredType -> TcCoercion -> PredType
mkCastTy PredType
xi2 TcCoercion
homo_co
ps_rhs' :: PredType
ps_rhs' = PredType -> TcCoercion -> PredType
mkCastTy PredType
ps_xi2 TcCoercion
homo_co
rhs_co :: TcCoercion
rhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role PredType
xi2 TcCoercion
homo_co
lhs' :: PredType
lhs' = TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1
lhs_co :: TcCoercion
lhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflRightCo Role
role PredType
lhs' TcCoercion
co1
; String -> SDoc -> TcS ()
traceTcS String
"Hetero equality gives rise to given kind equality"
(CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
kind_ev SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
kind_pty)
; [CtEvidence] -> TcS ()
emitWorkNC [CtEvidence
kind_ev]
; CtEvidence
type_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped PredType
lhs' PredType
rhs' TcCoercion
lhs_co TcCoercion
rhs_co
; CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
type_ev EqRel
eq_rel SwapFlag
NotSwapped TcTyVar
tv1 PredType
ps_tv1 PredType
rhs' PredType
ps_rhs' }
| Bool
otherwise
= do { CtLoc -> Role -> PredType -> PredType -> TcS ()
emitNewDerivedEq CtLoc
kind_loc Role
Nominal PredType
ki1 PredType
ki2
; String -> SDoc -> TcS ()
traceTcS String
"Hetero equality gives rise to derived kind equality" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkIrredCt CtEvidence
ev) }
where
kind_pty :: PredType
kind_pty = PredType -> PredType -> PredType -> PredType -> PredType
mkHeteroPrimEqPred PredType
liftedTypeKind PredType
liftedTypeKind PredType
ki1 PredType
ki2
kind_loc :: CtLoc
kind_loc = PredType -> PredType -> CtLoc -> CtLoc
mkKindLoc (TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
co1) PredType
xi2 CtLoc
loc
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctev_loc CtEvidence
ev
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
canEqTyVarHomo :: CtEvidence
-> EqRel -> SwapFlag
-> TcTyVar
-> TcType
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo :: CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> PredType
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 PredType
ps_xi1 PredType
xi2 PredType
_
| Just (TcTyVar
tv2, TcCoercion
_) <- PredType -> Maybe (TcTyVar, TcCoercion)
tcGetCastedTyVar_maybe PredType
xi2
, TcTyVar
tv1 TcTyVar -> TcTyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TcTyVar
tv2
= CtEvidence -> EqRel -> PredType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel (TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1)
| Just (TcTyVar
tv2, TcCoercion
co2) <- PredType -> Maybe (TcTyVar, TcCoercion)
tcGetCastedTyVar_maybe PredType
xi2
, TcTyVar -> TcTyVar -> Bool
swapOverTyVars TcTyVar
tv1 TcTyVar
tv2
= do { String -> SDoc -> TcS ()
traceTcS String
"canEqTyVar swapOver" (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv1 SDoc -> SDoc -> SDoc
$$ TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv2 SDoc -> SDoc -> SDoc
$$ SwapFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr SwapFlag
swapped)
; let role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
sym_co2 :: TcCoercion
sym_co2 = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co2
ty1 :: PredType
ty1 = TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1
new_lhs :: PredType
new_lhs = PredType
ty1 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
sym_co2
lhs_co :: TcCoercion
lhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role PredType
ty1 TcCoercion
sym_co2
new_rhs :: PredType
new_rhs = TcTyVar -> PredType
mkTyVarTy TcTyVar
tv2
rhs_co :: TcCoercion
rhs_co = Role -> PredType -> TcCoercion -> TcCoercion
mkTcGReflRightCo Role
role PredType
new_rhs TcCoercion
co2
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
new_lhs PredType
new_rhs TcCoercion
lhs_co TcCoercion
rhs_co
; DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVar2 DynFlags
dflags CtEvidence
new_ev EqRel
eq_rel SwapFlag
IsSwapped TcTyVar
tv2 (PredType
ps_xi1 PredType -> TcCoercion -> PredType
`mkCastTy` TcCoercion
sym_co2) }
canEqTyVarHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 PredType
_ PredType
_ PredType
ps_xi2
= do { DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVar2 DynFlags
dflags CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 PredType
ps_xi2 }
canEqTyVar2 :: DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar2 :: DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> PredType
-> TcS (StopOrContinue Ct)
canEqTyVar2 DynFlags
dflags CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 PredType
rhs
| Just PredType
rhs' <- DynFlags -> TcTyVar -> PredType -> Maybe PredType
metaTyVarUpdateOK DynFlags
dflags TcTyVar
tv1 PredType
rhs
= do { CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
lhs PredType
rhs' TcCoercion
rewrite_co1 TcCoercion
rewrite_co2
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CTyEqCan :: CtEvidence -> TcTyVar -> PredType -> EqRel -> Ct
CTyEqCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_ev, cc_tyvar :: TcTyVar
cc_tyvar = TcTyVar
tv1
, cc_rhs :: PredType
cc_rhs = PredType
rhs', cc_eq_rel :: EqRel
cc_eq_rel = EqRel
eq_rel }) }
| Bool
otherwise
= do { String -> SDoc -> TcS ()
traceTcS String
"canEqTyVar2 can't unify" (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv1 SDoc -> SDoc -> SDoc
$$ PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
rhs)
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped PredType
lhs PredType
rhs TcCoercion
rewrite_co1 TcCoercion
rewrite_co2
; if EqRel -> TcTyVar -> PredType -> Bool
isInsolubleOccursCheck EqRel
eq_rel TcTyVar
tv1 PredType
rhs
then Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkInsolubleCt CtEvidence
new_ev)
else Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> Ct
mkIrredCt CtEvidence
new_ev) }
where
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
lhs :: PredType
lhs = TcTyVar -> PredType
mkTyVarTy TcTyVar
tv1
rewrite_co1 :: TcCoercion
rewrite_co1 = Role -> PredType -> TcCoercion
mkTcReflCo Role
role PredType
lhs
rewrite_co2 :: TcCoercion
rewrite_co2 = Role -> PredType -> TcCoercion
mkTcReflCo Role
role PredType
rhs
canEqReflexive :: CtEvidence
-> EqRel
-> TcType
-> TcS (StopOrContinue Ct)
canEqReflexive :: CtEvidence -> EqRel -> PredType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel PredType
ty
= do { CtEvidence -> EvTerm -> TcS ()
setEvBindIfWanted CtEvidence
ev (TcCoercion -> EvTerm
evCoercion (TcCoercion -> EvTerm) -> TcCoercion -> EvTerm
forall a b. (a -> b) -> a -> b
$
Role -> PredType -> TcCoercion
mkTcReflCo (EqRel -> Role
eqRelRole EqRel
eq_rel) PredType
ty)
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Solved by reflexivity" }
data StopOrContinue a
= ContinueWith a
| Stop CtEvidence
SDoc
deriving (a -> StopOrContinue b -> StopOrContinue a
(a -> b) -> StopOrContinue a -> StopOrContinue b
(forall a b. (a -> b) -> StopOrContinue a -> StopOrContinue b)
-> (forall a b. a -> StopOrContinue b -> StopOrContinue a)
-> Functor StopOrContinue
forall a b. a -> StopOrContinue b -> StopOrContinue a
forall a b. (a -> b) -> StopOrContinue a -> StopOrContinue b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> StopOrContinue b -> StopOrContinue a
$c<$ :: forall a b. a -> StopOrContinue b -> StopOrContinue a
fmap :: (a -> b) -> StopOrContinue a -> StopOrContinue b
$cfmap :: forall a b. (a -> b) -> StopOrContinue a -> StopOrContinue b
Functor)
instance Outputable a => Outputable (StopOrContinue a) where
ppr :: StopOrContinue a -> SDoc
ppr (Stop CtEvidence
ev SDoc
s) = String -> SDoc
text String
"Stop" SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
parens SDoc
s SDoc -> SDoc -> SDoc
<+> CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
ppr (ContinueWith a
w) = String -> SDoc
text String
"ContinueWith" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
w
continueWith :: a -> TcS (StopOrContinue a)
continueWith :: a -> TcS (StopOrContinue a)
continueWith = StopOrContinue a -> TcS (StopOrContinue a)
forall (m :: * -> *) a. Monad m => a -> m a
return (StopOrContinue a -> TcS (StopOrContinue a))
-> (a -> StopOrContinue a) -> a -> TcS (StopOrContinue a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> StopOrContinue a
forall a. a -> StopOrContinue a
ContinueWith
stopWith :: CtEvidence -> String -> TcS (StopOrContinue a)
stopWith :: CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
s = StopOrContinue a -> TcS (StopOrContinue a)
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence -> SDoc -> StopOrContinue a
forall a. CtEvidence -> SDoc -> StopOrContinue a
Stop CtEvidence
ev (String -> SDoc
text String
s))
andWhenContinue :: TcS (StopOrContinue a)
-> (a -> TcS (StopOrContinue b))
-> TcS (StopOrContinue b)
andWhenContinue :: TcS (StopOrContinue a)
-> (a -> TcS (StopOrContinue b)) -> TcS (StopOrContinue b)
andWhenContinue TcS (StopOrContinue a)
tcs1 a -> TcS (StopOrContinue b)
tcs2
= do { StopOrContinue a
r <- TcS (StopOrContinue a)
tcs1
; case StopOrContinue a
r of
Stop CtEvidence
ev SDoc
s -> StopOrContinue b -> TcS (StopOrContinue b)
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence -> SDoc -> StopOrContinue b
forall a. CtEvidence -> SDoc -> StopOrContinue a
Stop CtEvidence
ev SDoc
s)
ContinueWith a
ct -> a -> TcS (StopOrContinue b)
tcs2 a
ct }
infixr 0 `andWhenContinue`
rewriteEvidence :: CtEvidence
-> TcPredType
-> TcCoercion
-> TcS (StopOrContinue CtEvidence)
rewriteEvidence :: CtEvidence
-> PredType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence old_ev :: CtEvidence
old_ev@(CtDerived {}) PredType
new_pred TcCoercion
_co
=
CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence
old_ev { ctev_pred :: PredType
ctev_pred = PredType
new_pred })
rewriteEvidence CtEvidence
old_ev PredType
new_pred TcCoercion
co
| TcCoercion -> Bool
isTcReflCo TcCoercion
co
= CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence
old_ev { ctev_pred :: PredType
ctev_pred = PredType
new_pred })
rewriteEvidence ev :: CtEvidence
ev@(CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
old_evar, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc }) PredType
new_pred TcCoercion
co
= do { CtEvidence
new_ev <- CtLoc -> (PredType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc (PredType
new_pred, EvTerm
new_tm)
; CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith CtEvidence
new_ev }
where
new_tm :: EvTerm
new_tm = EvExpr -> TcCoercion -> EvTerm
mkEvCast (TcTyVar -> EvExpr
evId TcTyVar
old_evar) (Role -> Role -> TcCoercion -> TcCoercion
tcDowngradeRole Role
Representational
(CtEvidence -> Role
ctEvRole CtEvidence
ev)
(TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co))
rewriteEvidence ev :: CtEvidence
ev@(CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest
, ctev_nosh :: CtEvidence -> ShadowInfo
ctev_nosh = ShadowInfo
si
, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc }) PredType
new_pred TcCoercion
co
= do { MaybeNew
mb_new_ev <- ShadowInfo -> CtLoc -> PredType -> TcS MaybeNew
newWanted_SI ShadowInfo
si CtLoc
loc PredType
new_pred
; MASSERT( tcCoercionRole co == ctEvRole ev )
; TcEvDest -> EvTerm -> TcS ()
setWantedEvTerm TcEvDest
dest
(EvExpr -> TcCoercion -> EvTerm
mkEvCast (MaybeNew -> EvExpr
getEvExpr MaybeNew
mb_new_ev)
(Role -> Role -> TcCoercion -> TcCoercion
tcDowngradeRole Role
Representational (CtEvidence -> Role
ctEvRole CtEvidence
ev) TcCoercion
co))
; case MaybeNew
mb_new_ev of
Fresh CtEvidence
new_ev -> CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith CtEvidence
new_ev
Cached EvExpr
_ -> CtEvidence -> String -> TcS (StopOrContinue CtEvidence)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Cached wanted" }
rewriteEqEvidence :: CtEvidence
-> SwapFlag
-> TcType -> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence :: CtEvidence
-> SwapFlag
-> PredType
-> PredType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
old_ev SwapFlag
swapped PredType
nlhs PredType
nrhs TcCoercion
lhs_co TcCoercion
rhs_co
| CtDerived {} <- CtEvidence
old_ev
= CtEvidence -> TcS CtEvidence
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence
old_ev { ctev_pred :: PredType
ctev_pred = PredType
new_pred })
| SwapFlag
NotSwapped <- SwapFlag
swapped
, TcCoercion -> Bool
isTcReflCo TcCoercion
lhs_co
, TcCoercion -> Bool
isTcReflCo TcCoercion
rhs_co
= CtEvidence -> TcS CtEvidence
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence
old_ev { ctev_pred :: PredType
ctev_pred = PredType
new_pred })
| CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
old_evar } <- CtEvidence
old_ev
= do { let new_tm :: EvTerm
new_tm = TcCoercion -> EvTerm
evCoercion (TcCoercion
lhs_co
TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo` SwapFlag -> TcCoercion -> TcCoercion
maybeSym SwapFlag
swapped (TcTyVar -> TcCoercion
mkTcCoVarCo TcTyVar
old_evar)
TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo` TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
rhs_co)
; CtLoc -> (PredType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc' (PredType
new_pred, EvTerm
new_tm) }
| CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest, ctev_nosh :: CtEvidence -> ShadowInfo
ctev_nosh = ShadowInfo
si } <- CtEvidence
old_ev
= do { (CtEvidence
new_ev, TcCoercion
hole_co) <- ShadowInfo
-> CtLoc
-> Role
-> PredType
-> PredType
-> TcS (CtEvidence, TcCoercion)
newWantedEq_SI ShadowInfo
si CtLoc
loc' (CtEvidence -> Role
ctEvRole CtEvidence
old_ev) PredType
nlhs PredType
nrhs
; let co :: TcCoercion
co = SwapFlag -> TcCoercion -> TcCoercion
maybeSym SwapFlag
swapped (TcCoercion -> TcCoercion) -> TcCoercion -> TcCoercion
forall a b. (a -> b) -> a -> b
$
TcCoercion -> TcCoercion
mkSymCo TcCoercion
lhs_co
TcCoercion -> TcCoercion -> TcCoercion
`mkTransCo` TcCoercion
hole_co
TcCoercion -> TcCoercion -> TcCoercion
`mkTransCo` TcCoercion
rhs_co
; TcEvDest -> TcCoercion -> TcS ()
setWantedEq TcEvDest
dest TcCoercion
co
; String -> SDoc -> TcS ()
traceTcS String
"rewriteEqEvidence" ([SDoc] -> SDoc
vcat [CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
old_ev, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
nlhs, PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
nrhs, TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
co])
; CtEvidence -> TcS CtEvidence
forall (m :: * -> *) a. Monad m => a -> m a
return CtEvidence
new_ev }
| Bool
otherwise
= String -> TcS CtEvidence
forall a. String -> a
panic String
"rewriteEvidence"
where
new_pred :: PredType
new_pred = CtEvidence -> PredType -> PredType -> PredType
mkTcEqPredLikeEv CtEvidence
old_ev PredType
nlhs PredType
nrhs
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
old_ev
loc' :: CtLoc
loc' = CtLoc -> CtLoc
bumpCtLocDepth CtLoc
loc
unifyWanted :: CtLoc -> Role
-> TcType -> TcType -> TcS Coercion
unifyWanted :: CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Phantom PredType
ty1 PredType
ty2
= do { TcCoercion
kind_co <- CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Nominal (HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind PredType
ty1) (HasDebugCallStack => PredType -> PredType
PredType -> PredType
tcTypeKind PredType
ty2)
; TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercion -> PredType -> PredType -> TcCoercion
mkPhantomCo TcCoercion
kind_co PredType
ty1 PredType
ty2) }
unifyWanted CtLoc
loc Role
role PredType
orig_ty1 PredType
orig_ty2
= PredType -> PredType -> TcS TcCoercion
go PredType
orig_ty1 PredType
orig_ty2
where
go :: PredType -> PredType -> TcS TcCoercion
go PredType
ty1 PredType
ty2 | Just PredType
ty1' <- PredType -> Maybe PredType
tcView PredType
ty1 = PredType -> PredType -> TcS TcCoercion
go PredType
ty1' PredType
ty2
go PredType
ty1 PredType
ty2 | Just PredType
ty2' <- PredType -> Maybe PredType
tcView PredType
ty2 = PredType -> PredType -> TcS TcCoercion
go PredType
ty1 PredType
ty2'
go (FunTy AnonArgFlag
_ PredType
s1 PredType
t1) (FunTy AnonArgFlag
_ PredType
s2 PredType
t2)
= do { TcCoercion
co_s <- CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
role PredType
s1 PredType
s2
; TcCoercion
co_t <- CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
role PredType
t1 PredType
t2
; TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcCoercion -> TcCoercion -> TcCoercion
mkFunCo Role
role TcCoercion
co_s TcCoercion
co_t) }
go (TyConApp TyCon
tc1 [PredType]
tys1) (TyConApp TyCon
tc2 [PredType]
tys2)
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2, [PredType]
tys1 [PredType] -> [PredType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [PredType]
tys2
, TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc1 Role
role
= do { [TcCoercion]
cos <- (Role -> PredType -> PredType -> TcS TcCoercion)
-> [Role] -> [PredType] -> [PredType] -> TcS [TcCoercion]
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M (CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
unifyWanted CtLoc
loc)
(Role -> TyCon -> [Role]
tyConRolesX Role
role TyCon
tc1) [PredType]
tys1 [PredType]
tys2
; TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (HasDebugCallStack => Role -> TyCon -> [TcCoercion] -> TcCoercion
Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTyConAppCo Role
role TyCon
tc1 [TcCoercion]
cos) }
go ty1 :: PredType
ty1@(TyVarTy TcTyVar
tv) PredType
ty2
= do { Maybe PredType
mb_ty <- TcTyVar -> TcS (Maybe PredType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe PredType
mb_ty of
Just PredType
ty1' -> PredType -> PredType -> TcS TcCoercion
go PredType
ty1' PredType
ty2
Maybe PredType
Nothing -> PredType -> PredType -> TcS TcCoercion
bale_out PredType
ty1 PredType
ty2}
go PredType
ty1 ty2 :: PredType
ty2@(TyVarTy TcTyVar
tv)
= do { Maybe PredType
mb_ty <- TcTyVar -> TcS (Maybe PredType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe PredType
mb_ty of
Just PredType
ty2' -> PredType -> PredType -> TcS TcCoercion
go PredType
ty1 PredType
ty2'
Maybe PredType
Nothing -> PredType -> PredType -> TcS TcCoercion
bale_out PredType
ty1 PredType
ty2 }
go ty1 :: PredType
ty1@(CoercionTy {}) (CoercionTy {})
= TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> PredType -> TcCoercion
mkReflCo Role
role PredType
ty1)
go PredType
ty1 PredType
ty2 = PredType -> PredType -> TcS TcCoercion
bale_out PredType
ty1 PredType
ty2
bale_out :: PredType -> PredType -> TcS TcCoercion
bale_out PredType
ty1 PredType
ty2
| PredType
ty1 HasDebugCallStack => PredType -> PredType -> Bool
PredType -> PredType -> Bool
`tcEqType` PredType
ty2 = TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> PredType -> TcCoercion
mkTcReflCo Role
role PredType
ty1)
| Bool
otherwise = CtLoc -> Role -> PredType -> PredType -> TcS TcCoercion
emitNewWantedEq CtLoc
loc Role
role PredType
orig_ty1 PredType
orig_ty2
unifyDeriveds :: CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
unifyDeriveds :: CtLoc -> [Role] -> [PredType] -> [PredType] -> TcS ()
unifyDeriveds CtLoc
loc [Role]
roles [PredType]
tys1 [PredType]
tys2 = (Role -> PredType -> PredType -> TcS ())
-> [Role] -> [PredType] -> [PredType] -> TcS ()
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m ()
zipWith3M_ (CtLoc -> Role -> PredType -> PredType -> TcS ()
unify_derived CtLoc
loc) [Role]
roles [PredType]
tys1 [PredType]
tys2
unifyDerived :: CtLoc -> Role -> Pair TcType -> TcS ()
unifyDerived :: CtLoc -> Role -> Pair PredType -> TcS ()
unifyDerived CtLoc
loc Role
role (Pair PredType
ty1 PredType
ty2) = CtLoc -> Role -> PredType -> PredType -> TcS ()
unify_derived CtLoc
loc Role
role PredType
ty1 PredType
ty2
unify_derived :: CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived :: CtLoc -> Role -> PredType -> PredType -> TcS ()
unify_derived CtLoc
_ Role
Phantom PredType
_ PredType
_ = () -> TcS ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
unify_derived CtLoc
loc Role
role PredType
orig_ty1 PredType
orig_ty2
= PredType -> PredType -> TcS ()
go PredType
orig_ty1 PredType
orig_ty2
where
go :: PredType -> PredType -> TcS ()
go PredType
ty1 PredType
ty2 | Just PredType
ty1' <- PredType -> Maybe PredType
tcView PredType
ty1 = PredType -> PredType -> TcS ()
go PredType
ty1' PredType
ty2
go PredType
ty1 PredType
ty2 | Just PredType
ty2' <- PredType -> Maybe PredType
tcView PredType
ty2 = PredType -> PredType -> TcS ()
go PredType
ty1 PredType
ty2'
go (FunTy AnonArgFlag
_ PredType
s1 PredType
t1) (FunTy AnonArgFlag
_ PredType
s2 PredType
t2)
= do { CtLoc -> Role -> PredType -> PredType -> TcS ()
unify_derived CtLoc
loc Role
role PredType
s1 PredType
s2
; CtLoc -> Role -> PredType -> PredType -> TcS ()
unify_derived CtLoc
loc Role
role PredType
t1 PredType
t2 }
go (TyConApp TyCon
tc1 [PredType]
tys1) (TyConApp TyCon
tc2 [PredType]
tys2)
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2, [PredType]
tys1 [PredType] -> [PredType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [PredType]
tys2
, TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc1 Role
role
= CtLoc -> [Role] -> [PredType] -> [PredType] -> TcS ()
unifyDeriveds CtLoc
loc (Role -> TyCon -> [Role]
tyConRolesX Role
role TyCon
tc1) [PredType]
tys1 [PredType]
tys2
go ty1 :: PredType
ty1@(TyVarTy TcTyVar
tv) PredType
ty2
= do { Maybe PredType
mb_ty <- TcTyVar -> TcS (Maybe PredType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe PredType
mb_ty of
Just PredType
ty1' -> PredType -> PredType -> TcS ()
go PredType
ty1' PredType
ty2
Maybe PredType
Nothing -> PredType -> PredType -> TcS ()
bale_out PredType
ty1 PredType
ty2 }
go PredType
ty1 ty2 :: PredType
ty2@(TyVarTy TcTyVar
tv)
= do { Maybe PredType
mb_ty <- TcTyVar -> TcS (Maybe PredType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe PredType
mb_ty of
Just PredType
ty2' -> PredType -> PredType -> TcS ()
go PredType
ty1 PredType
ty2'
Maybe PredType
Nothing -> PredType -> PredType -> TcS ()
bale_out PredType
ty1 PredType
ty2 }
go PredType
ty1 PredType
ty2 = PredType -> PredType -> TcS ()
bale_out PredType
ty1 PredType
ty2
bale_out :: PredType -> PredType -> TcS ()
bale_out PredType
ty1 PredType
ty2
| PredType
ty1 HasDebugCallStack => PredType -> PredType -> Bool
PredType -> PredType -> Bool
`tcEqType` PredType
ty2 = () -> TcS ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = CtLoc -> Role -> PredType -> PredType -> TcS ()
emitNewDerivedEq CtLoc
loc Role
role PredType
orig_ty1 PredType
orig_ty2
maybeSym :: SwapFlag -> TcCoercion -> TcCoercion
maybeSym :: SwapFlag -> TcCoercion -> TcCoercion
maybeSym SwapFlag
IsSwapped TcCoercion
co = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co
maybeSym SwapFlag
NotSwapped TcCoercion
co = TcCoercion
co