{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFunctor #-}
module GHC.Tc.Solver.Canonical(
canonicalize,
unifyDerived,
makeSuperClasses, maybeSym,
StopOrContinue(..), stopWith, continueWith,
solveCallStack
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Tc.Types.Constraint
import GHC.Core.Predicate
import GHC.Tc.Types.Origin
import GHC.Tc.Utils.Unify( swapOverTyVars, metaTyVarUpdateOK, MetaTyVarUpdateResult(..) )
import GHC.Tc.Utils.TcType
import GHC.Core.Type
import GHC.Tc.Solver.Flatten
import GHC.Tc.Solver.Monad
import GHC.Tc.Types.Evidence
import GHC.Tc.Types.EvTerm
import GHC.Core.Class
import GHC.Core.TyCon
import GHC.Core.Multiplicity
import GHC.Core.TyCo.Rep
import GHC.Core.Coercion
import GHC.Core
import GHC.Types.Id( mkTemplateLocals )
import GHC.Core.FamInstEnv ( FamInstEnvs )
import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe )
import GHC.Types.Var
import GHC.Types.Var.Env( mkInScopeSet )
import GHC.Types.Var.Set( delVarSetList )
import GHC.Utils.Outputable
import GHC.Driver.Session( DynFlags )
import GHC.Types.Name.Set
import GHC.Types.Name.Reader
import GHC.Hs.Type( HsIPName(..) )
import GHC.Data.Pair
import GHC.Utils.Misc
import GHC.Data.Bag
import GHC.Utils.Monad
import Control.Monad
import Data.Maybe ( isJust )
import Data.List ( zip4 )
import GHC.Types.Basic
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 TcType -> Pred
classifyPredType TcType
pred of
ClassPred Class
cls [TcType]
tys -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:cls" (Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
cls SDoc -> SDoc -> SDoc
<+> [TcType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TcType]
tys)
CtEvidence -> Class -> [TcType] -> TcS (StopOrContinue Ct)
canClassNC CtEvidence
ev Class
cls [TcType]
tys
EqPred EqRel
eq_rel TcType
ty1 TcType
ty2 -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:eq" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1 SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2)
CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ty2
IrredPred {} -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:irred" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
pred)
CtIrredStatus -> CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtIrredStatus
OtherCIS CtEvidence
ev
ForAllPred [TcTyVar]
tvs [TcType]
theta TcType
p -> do String -> SDoc -> TcS ()
traceTcS String
"canEvNC:forall" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
pred)
CtEvidence
-> [TcTyVar] -> [TcType] -> TcType -> TcS (StopOrContinue Ct)
canForAllNC CtEvidence
ev [TcTyVar]
tvs [TcType]
theta TcType
p
where
pred :: TcType
pred = CtEvidence -> TcType
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, cc_status :: Ct -> CtIrredStatus
cc_status = CtIrredStatus
status })
| EqPred EqRel
eq_rel TcType
ty1 TcType
ty2 <- TcType -> Pred
classifyPredType (CtEvidence -> TcType
ctEvPred CtEvidence
ev)
=
CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ty2
| Bool
otherwise
= CtIrredStatus -> CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtIrredStatus
status CtEvidence
ev
canonicalize (CDictCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev, cc_class :: Ct -> Class
cc_class = Class
cls
, cc_tyargs :: Ct -> [TcType]
cc_tyargs = [TcType]
xis, cc_pend_sc :: Ct -> Bool
cc_pend_sc = Bool
pend_sc })
= {-# SCC "canClass" #-}
CtEvidence -> Class -> [TcType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [TcType]
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 -> TcType
cc_rhs = TcType
xi
, cc_eq_rel :: Ct -> EqRel
cc_eq_rel = EqRel
eq_rel })
= {-# SCC "canEqLeafTyVarEq" #-}
CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel (TcTyVar -> TcType
mkTyVarTy TcTyVar
tv) TcType
xi
canonicalize (CFunEqCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev
, cc_fun :: Ct -> TyCon
cc_fun = TyCon
fn
, cc_tyargs :: Ct -> [TcType]
cc_tyargs = [TcType]
xis1
, cc_fsk :: Ct -> TcTyVar
cc_fsk = TcTyVar
fsk })
= {-# SCC "canEqLeafFunEq" #-}
CtEvidence
-> TyCon -> [TcType] -> TcTyVar -> TcS (StopOrContinue Ct)
canCFunEqCan CtEvidence
ev TyCon
fn [TcType]
xis1 TcTyVar
fsk
canClassNC :: CtEvidence -> Class -> [Type] -> TcS (StopOrContinue Ct)
canClassNC :: CtEvidence -> Class -> [TcType] -> TcS (StopOrContinue Ct)
canClassNC CtEvidence
ev Class
cls [TcType]
tys
| CtEvidence -> Bool
isGiven CtEvidence
ev
= do { [Ct]
sc_cts <- CtEvidence
-> [TcTyVar] -> [TcType] -> Class -> [TcType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [] [] Class
cls [TcType]
tys
; [Ct] -> TcS ()
emitWork [Ct]
sc_cts
; CtEvidence -> Class -> [TcType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [TcType]
tys Bool
False }
| CtEvidence -> Bool
isWanted CtEvidence
ev
, Just FastString
ip_name <- Class -> [TcType] -> Maybe FastString
isCallStackPred Class
cls [TcType]
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 -> TcType -> TcS CtEvidence
newWantedEvVarNC CtLoc
new_loc TcType
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 -> [TcType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
new_ev Class
cls [TcType]
tys Bool
False }
| Bool
otherwise
= CtEvidence -> Class -> [TcType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [TcType]
tys (Class -> Bool
has_scs Class
cls)
where
has_scs :: Class -> Bool
has_scs Class
cls = Bool -> Bool
not ([TcType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Class -> [TcType]
classSCTheta Class
cls))
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
pred :: TcType
pred = CtEvidence -> TcType
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 (TcType -> TcCoercion
wrapIP (CtEvidence -> TcType
ctEvPred CtEvidence
ev))
CtEvidence -> EvTerm -> TcS ()
setEvBindIfWanted CtEvidence
ev EvTerm
ev_tm
canClass :: CtEvidence
-> Class -> [Type]
-> Bool
-> TcS (StopOrContinue Ct)
canClass :: CtEvidence -> Class -> [TcType] -> Bool -> TcS (StopOrContinue Ct)
canClass CtEvidence
ev Class
cls [TcType]
tys Bool
pend_sc
=
ASSERT2( ctEvRole ev == Nominal, ppr ev $$ ppr cls $$ ppr tys )
do { ([TcType]
xis, [TcCoercion]
cos, TcCoercion
_kind_co) <- CtEvidence
-> TyCon -> [TcType] -> TcS ([TcType], [TcCoercion], TcCoercion)
flattenArgsNom CtEvidence
ev TyCon
cls_tc [TcType]
tys
; MASSERT( isTcReflCo _kind_co )
; let co :: TcCoercion
co = Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTcTyConAppCo Role
Nominal TyCon
cls_tc [TcCoercion]
cos
xi :: TcType
xi = Class -> [TcType] -> TcType
mkClassPred Class
cls [TcType]
xis
mk_ct :: CtEvidence -> Ct
mk_ct CtEvidence
new_ev = CDictCan :: CtEvidence -> Class -> [TcType] -> Bool -> Ct
CDictCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_ev
, cc_tyargs :: [TcType]
cc_tyargs = [TcType]
xis
, cc_class :: Class
cc_class = Class
cls
, cc_pend_sc :: Bool
cc_pend_sc = Bool
pend_sc }
; StopOrContinue CtEvidence
mb <- CtEvidence
-> TcType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev TcType
xi TcCoercion
co
; String -> SDoc -> TcS ()
traceTcS String
"canClass" ([SDoc] -> SDoc
vcat [ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
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 -> [TcType]
cc_tyargs = [TcType]
tys })
= CtEvidence
-> [TcTyVar] -> [TcType] -> Class -> [TcType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [] [] Class
cls [TcType]
tys
go (CQuantCan (QCI { qci_pred :: QCInst -> TcType
qci_pred = TcType
pred, qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev }))
= ASSERT2( isClassPred pred, ppr pred )
CtEvidence
-> [TcTyVar] -> [TcType] -> Class -> [TcType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
tys
where
([TcTyVar]
tvs, [TcType]
theta, Class
cls, [TcType]
tys) = TcType -> ([TcTyVar], [TcType], Class, [TcType])
tcSplitDFunTy (CtEvidence -> TcType
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] -> [TcType] -> Class -> [TcType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
tys
= NameSet
-> CtEvidence
-> [TcTyVar]
-> [TcType]
-> Class
-> [TcType]
-> TcS [Ct]
mk_strict_superclasses (Name -> NameSet
unitNameSet (Class -> Name
className Class
cls))
CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
tys
mk_strict_superclasses :: NameSet -> CtEvidence
-> [TyVar] -> ThetaType
-> Class -> [Type] -> TcS [Ct]
mk_strict_superclasses :: NameSet
-> CtEvidence
-> [TcTyVar]
-> [TcType]
-> Class
-> [TcType]
-> TcS [Ct]
mk_strict_superclasses NameSet
rec_clss (CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
evar, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc })
[TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
tys
= (TcTyVar -> TcS [Ct]) -> [TcTyVar] -> TcS [Ct]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (CtLoc -> TcTyVar -> TcS [Ct]
do_one_given (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 = [TcType] -> [TcTyVar]
mkTemplateLocals [TcType]
theta
size :: TypeSize
size = [TcType] -> TypeSize
sizeTypes [TcType]
tys
do_one_given :: CtLoc -> TcTyVar -> TcS [Ct]
do_one_given CtLoc
given_loc TcTyVar
sel_id
| HasDebugCallStack => TcType -> Bool
TcType -> Bool
isUnliftedType TcType
sc_pred
, Bool -> Bool
not ([TcTyVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcTyVar]
tvs Bool -> Bool -> Bool
&& [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
theta)
=
[Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise
= do { CtEvidence
given_ev <- CtLoc -> (TcType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
given_loc ((TcType, EvTerm) -> TcS CtEvidence)
-> (TcType, EvTerm) -> TcS CtEvidence
forall a b. (a -> b) -> a -> b
$
TcTyVar -> TcType -> (TcType, EvTerm)
mk_given_desc TcTyVar
sel_id TcType
sc_pred
; NameSet
-> CtEvidence -> [TcTyVar] -> [TcType] -> TcType -> TcS [Ct]
mk_superclasses NameSet
rec_clss CtEvidence
given_ev [TcTyVar]
tvs [TcType]
theta TcType
sc_pred }
where
sc_pred :: TcType
sc_pred = TcTyVar -> [TcType] -> TcType
classMethodInstTy TcTyVar
sel_id [TcType]
tys
mk_given_desc :: Id -> PredType -> (PredType, EvTerm)
mk_given_desc :: TcTyVar -> TcType -> (TcType, EvTerm)
mk_given_desc TcTyVar
sel_id TcType
sc_pred
= (TcType
swizzled_pred, EvTerm
swizzled_evterm)
where
([TcTyVar]
sc_tvs, TcType
sc_rho) = TcType -> ([TcTyVar], TcType)
splitForAllTys TcType
sc_pred
([Scaled TcType]
sc_theta, TcType
sc_inner_pred) = TcType -> ([Scaled TcType], TcType)
splitFunTys TcType
sc_rho
all_tvs :: [TcTyVar]
all_tvs = [TcTyVar]
tvs [TcTyVar] -> [TcTyVar] -> [TcTyVar]
forall a. [a] -> [a] -> [a]
`chkAppend` [TcTyVar]
sc_tvs
all_theta :: [TcType]
all_theta = [TcType]
theta [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
`chkAppend` ((Scaled TcType -> TcType) -> [Scaled TcType] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map Scaled TcType -> TcType
forall a. Scaled a -> a
scaledThing [Scaled TcType]
sc_theta)
swizzled_pred :: TcType
swizzled_pred = [TcTyVar] -> [TcType] -> TcType -> TcType
mkInfSigmaTy [TcTyVar]
all_tvs [TcType]
all_theta TcType
sc_inner_pred
swizzled_evterm :: EvTerm
swizzled_evterm = 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]
all_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 -> [TcType] -> EvExpr
forall b. Expr b -> [TcType] -> Expr b
`mkTyApps` [TcType]
tys
EvExpr -> EvExpr -> EvExpr
forall b. Expr b -> Expr b -> Expr b
`App` (TcTyVar -> EvExpr
evId TcTyVar
evar EvExpr -> [TcTyVar] -> EvExpr
forall b. Expr b -> [TcTyVar] -> Expr b
`mkVarApps` ([TcTyVar]
tvs [TcTyVar] -> [TcTyVar] -> [TcTyVar]
forall a. [a] -> [a] -> [a]
++ [TcTyVar]
dict_ids))
EvExpr -> [TcTyVar] -> EvExpr
forall b. Expr b -> [TcTyVar] -> Expr b
`mkVarApps` [TcTyVar]
sc_tvs
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 [TcType]
theta Class
cls [TcType]
tys
| (TcType -> Bool) -> [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all TcType -> Bool
noFreeVarsOfType [TcType]
tys
= [Ct] -> TcS [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise
= ASSERT2( null tvs && null theta, ppr tvs $$ ppr theta )
(TcType -> TcS [Ct]) -> [TcType] -> TcS [Ct]
forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM TcType -> TcS [Ct]
do_one_derived (Class -> [TcType] -> [TcType]
immSuperClasses Class
cls [TcType]
tys)
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
do_one_derived :: TcType -> TcS [Ct]
do_one_derived TcType
sc_pred
= do { CtEvidence
sc_ev <- CtLoc -> TcType -> TcS CtEvidence
newDerivedNC CtLoc
loc TcType
sc_pred
; NameSet
-> CtEvidence -> [TcTyVar] -> [TcType] -> TcType -> TcS [Ct]
mk_superclasses NameSet
rec_clss CtEvidence
sc_ev [] [] TcType
sc_pred }
mk_superclasses :: NameSet -> CtEvidence
-> [TyVar] -> ThetaType -> PredType -> TcS [Ct]
mk_superclasses :: NameSet
-> CtEvidence -> [TcTyVar] -> [TcType] -> TcType -> TcS [Ct]
mk_superclasses NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [TcType]
theta TcType
pred
| ClassPred Class
cls [TcType]
tys <- TcType -> Pred
classifyPredType TcType
pred
= NameSet
-> CtEvidence
-> [TcTyVar]
-> [TcType]
-> Class
-> [TcType]
-> TcS [Ct]
mk_superclasses_of NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
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]
-> [TcType]
-> Class
-> [TcType]
-> TcS [Ct]
mk_superclasses_of NameSet
rec_clss CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
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
<+> [TcType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TcType]
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
<+> [TcType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TcType]
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]
-> [TcType]
-> Class
-> [TcType]
-> TcS [Ct]
mk_strict_superclasses NameSet
rec_clss' CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
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, [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
theta
= CDictCan :: CtEvidence -> Class -> [TcType] -> Bool -> Ct
CDictCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
ev, cc_class :: Class
cc_class = Class
cls, cc_tyargs :: [TcType]
cc_tyargs = [TcType]
tys
, cc_pend_sc :: Bool
cc_pend_sc = Bool
loop_found }
| Bool
otherwise
= QCInst -> Ct
CQuantCan (QCI :: CtEvidence -> [TcTyVar] -> TcType -> Bool -> QCInst
QCI { qci_tvs :: [TcTyVar]
qci_tvs = [TcTyVar]
tvs, qci_pred :: TcType
qci_pred = Class -> [TcType] -> TcType
mkClassPred Class
cls [TcType]
tys
, qci_ev :: CtEvidence
qci_ev = CtEvidence
ev
, qci_pend_sc :: Bool
qci_pend_sc = Bool
loop_found })
canIrred :: CtIrredStatus -> CtEvidence -> TcS (StopOrContinue Ct)
canIrred :: CtIrredStatus -> CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtIrredStatus
status CtEvidence
ev
= do { let pred :: TcType
pred = CtEvidence -> TcType
ctEvPred CtEvidence
ev
; String -> SDoc -> TcS ()
traceTcS String
"can_pred" (String -> SDoc
text String
"IrredPred = " SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
pred)
; (TcType
xi,TcCoercion
co) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev TcType
pred
; CtEvidence
-> TcType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev TcType
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 TcType -> Pred
classifyPredType (CtEvidence -> TcType
ctEvPred CtEvidence
new_ev) of
ClassPred Class
cls [TcType]
tys -> CtEvidence -> Class -> [TcType] -> TcS (StopOrContinue Ct)
canClassNC CtEvidence
new_ev Class
cls [TcType]
tys
EqPred EqRel
eq_rel TcType
ty1 TcType
ty2 -> CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
new_ev EqRel
eq_rel TcType
ty1 TcType
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
$
CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
status CtEvidence
new_ev } }
canForAllNC :: CtEvidence -> [TyVar] -> TcThetaType -> TcPredType
-> TcS (StopOrContinue Ct)
canForAllNC :: CtEvidence
-> [TcTyVar] -> [TcType] -> TcType -> TcS (StopOrContinue Ct)
canForAllNC CtEvidence
ev [TcTyVar]
tvs [TcType]
theta TcType
pred
| CtEvidence -> Bool
isGiven CtEvidence
ev
, Just (Class
cls, [TcType]
tys) <- Maybe (Class, [TcType])
cls_pred_tys_maybe
= do { [Ct]
sc_cts <- CtEvidence
-> [TcTyVar] -> [TcType] -> Class -> [TcType] -> TcS [Ct]
mkStrictSuperClasses CtEvidence
ev [TcTyVar]
tvs [TcType]
theta Class
cls [TcType]
tys
; [Ct] -> TcS ()
emitWork [Ct]
sc_cts
; CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll CtEvidence
ev Bool
False }
| Bool
otherwise
= CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll CtEvidence
ev (Maybe (Class, [TcType]) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (Class, [TcType])
cls_pred_tys_maybe)
where
cls_pred_tys_maybe :: Maybe (Class, [TcType])
cls_pred_tys_maybe = TcType -> Maybe (Class, [TcType])
getClassPredTys_maybe TcType
pred
canForAll :: CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll :: CtEvidence -> Bool -> TcS (StopOrContinue Ct)
canForAll CtEvidence
ev Bool
pend_sc
= do {
let pred :: TcType
pred = CtEvidence -> TcType
ctEvPred CtEvidence
ev
; (TcType
xi,TcCoercion
co) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev TcType
pred
; CtEvidence
-> TcType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence CtEvidence
ev TcType
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 TcType -> Pred
classifyPredType (CtEvidence -> TcType
ctEvPred CtEvidence
new_ev) of
ForAllPred [TcTyVar]
tvs [TcType]
theta TcType
pred
-> CtEvidence
-> [TcTyVar]
-> [TcType]
-> TcType
-> Bool
-> TcS (StopOrContinue Ct)
solveForAll CtEvidence
new_ev [TcTyVar]
tvs [TcType]
theta TcType
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 -> [TyVar] -> TcThetaType -> PredType -> Bool
-> TcS (StopOrContinue Ct)
solveForAll :: CtEvidence
-> [TcTyVar]
-> [TcType]
-> TcType
-> Bool
-> TcS (StopOrContinue Ct)
solveForAll CtEvidence
ev [TcTyVar]
tvs [TcType]
theta TcType
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
$
[TcType] -> VarSet
tyCoVarsOfTypes (TcType
predTcType -> [TcType] -> [TcType]
forall a. a -> [a] -> [a]
:[TcType]
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 <- (TcType -> TcS TcTyVar) -> [TcType] -> TcS [TcTyVar]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TcType -> TcS TcTyVar
newEvVar (HasCallStack => TCvSubst -> [TcType] -> [TcType]
TCvSubst -> [TcType] -> [TcType]
substTheta TCvSubst
subst [TcType]
theta)
; (TcLevel
lvl, (TcTyVar
w_id, Bag Ct
wanteds))
<- SDoc -> TcS (TcTyVar, Bag Ct) -> TcS (TcLevel, (TcTyVar, Bag Ct))
forall a. SDoc -> TcS a -> TcS (TcLevel, a)
pushLevelNoWorkList (SkolemInfo -> SDoc
forall a. Outputable a => a -> SDoc
ppr SkolemInfo
skol_info) (TcS (TcTyVar, Bag Ct) -> TcS (TcLevel, (TcTyVar, Bag Ct)))
-> TcS (TcTyVar, Bag Ct) -> TcS (TcLevel, (TcTyVar, Bag Ct))
forall a b. (a -> b) -> a -> b
$
do { CtEvidence
wanted_ev <- CtLoc -> TcType -> TcS CtEvidence
newWantedEvVarNC CtLoc
loc (TcType -> TcS CtEvidence) -> TcType -> TcS CtEvidence
forall a b. (a -> b) -> a -> b
$
HasCallStack => TCvSubst -> TcType -> TcType
TCvSubst -> TcType -> TcType
substTy TCvSubst
subst TcType
pred
; (TcTyVar, Bag Ct) -> TcS (TcTyVar, Bag Ct)
forall (m :: * -> *) a. Monad m => a -> m a
return ( CtEvidence -> TcTyVar
ctEvEvId CtEvidence
wanted_ev
, Ct -> Bag Ct
forall a. a -> Bag a
unitBag (CtEvidence -> Ct
mkNonCanonical CtEvidence
wanted_ev)) }
; TcEvBinds
ev_binds <- TcLevel
-> SkolemInfo -> [TcTyVar] -> [TcTyVar] -> Bag Ct -> TcS TcEvBinds
emitImplicationTcS TcLevel
lvl SkolemInfo
skol_info [TcTyVar]
skol_tvs
[TcTyVar]
given_ev_vars Bag Ct
wanteds
; 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
= do { String -> SDoc -> TcS ()
traceTcS String
"discarding derived forall-constraint" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev)
; 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
qci :: QCInst
qci = QCI :: CtEvidence -> [TcTyVar] -> TcType -> Bool -> QCInst
QCI { qci_ev :: CtEvidence
qci_ev = CtEvidence
ev, qci_tvs :: [TcTyVar]
qci_tvs = [TcTyVar]
tvs
, qci_pred :: TcType
qci_pred = TcType
pred, qci_pend_sc :: Bool
qci_pend_sc = Bool
pend_sc }
canEqNC :: CtEvidence -> EqRel -> Type -> Type -> TcS (StopOrContinue Ct)
canEqNC :: CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ty2
= do { Either (Pair TcType) TcType
result <- TcType -> TcType -> TcS (Either (Pair TcType) TcType)
zonk_eq_types TcType
ty1 TcType
ty2
; case Either (Pair TcType) TcType
result of
Left (Pair TcType
ty1' TcType
ty2') -> Bool
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
False CtEvidence
ev EqRel
eq_rel TcType
ty1' TcType
ty1 TcType
ty2' TcType
ty2
Right TcType
ty -> CtEvidence -> EqRel -> TcType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel TcType
ty }
can_eq_nc
:: Bool
-> CtEvidence
-> EqRel
-> Type -> Type
-> Type -> Type
-> TcS (StopOrContinue Ct)
can_eq_nc :: Bool
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
flat CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 TcType
ty2 TcType
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, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ps_ty1, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ps_ty2 ]
; GlobalRdrEnv
rdr_env <- TcS GlobalRdrEnv
getGlobalRdrEnvTcS
; (FamInstEnv, FamInstEnv)
fam_insts <- TcS (FamInstEnv, FamInstEnv)
getFamInstEnvs
; Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
fam_insts CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 TcType
ty2 TcType
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
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
| Just TcType
ty1' <- TcType -> Maybe TcType
tcView TcType
ty1 = Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel TcType
ty1' TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
| Just TcType
ty2' <- TcType -> Maybe TcType
tcView TcType
ty2 = Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 TcType
ty2' TcType
ps_ty2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
ReprEq TcType
ty1 TcType
_ TcType
ty2 TcType
_
| TcType
ty1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
ty2
= CtEvidence -> EqRel -> TcType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
ReprEq TcType
ty1
can_eq_nc' Bool
_flat GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
| EqRel
ReprEq <- EqRel
eq_rel
, Just ((Bag GlobalRdrElt, TcCoercion), TcType)
stuff1 <- (FamInstEnv, FamInstEnv)
-> GlobalRdrEnv
-> TcType
-> Maybe ((Bag GlobalRdrElt, TcCoercion), TcType)
tcTopNormaliseNewTypeTF_maybe (FamInstEnv, FamInstEnv)
envs GlobalRdrEnv
rdr_env TcType
ty1
= CtEvidence
-> SwapFlag
-> TcType
-> ((Bag GlobalRdrElt, TcCoercion), TcType)
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc CtEvidence
ev SwapFlag
NotSwapped TcType
ty1 ((Bag GlobalRdrElt, TcCoercion), TcType)
stuff1 TcType
ty2 TcType
ps_ty2
| EqRel
ReprEq <- EqRel
eq_rel
, Just ((Bag GlobalRdrElt, TcCoercion), TcType)
stuff2 <- (FamInstEnv, FamInstEnv)
-> GlobalRdrEnv
-> TcType
-> Maybe ((Bag GlobalRdrElt, TcCoercion), TcType)
tcTopNormaliseNewTypeTF_maybe (FamInstEnv, FamInstEnv)
envs GlobalRdrEnv
rdr_env TcType
ty2
= CtEvidence
-> SwapFlag
-> TcType
-> ((Bag GlobalRdrElt, TcCoercion), TcType)
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc CtEvidence
ev SwapFlag
IsSwapped TcType
ty2 ((Bag GlobalRdrElt, TcCoercion), TcType)
stuff2 TcType
ty1 TcType
ps_ty1
can_eq_nc' Bool
flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (CastTy TcType
ty1 TcCoercion
co1) TcType
_ TcType
ty2 TcType
ps_ty2
| Bool -> Bool
not (TcType -> Bool
isTyVarTy TcType
ty2)
= Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcCoercion
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCast Bool
flat CtEvidence
ev EqRel
eq_rel SwapFlag
NotSwapped TcType
ty1 TcCoercion
co1 TcType
ty2 TcType
ps_ty2
can_eq_nc' Bool
flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 (CastTy TcType
ty2 TcCoercion
co2) TcType
_
| Bool -> Bool
not (TcType -> Bool
isTyVarTy TcType
ty1)
= Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcCoercion
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCast Bool
flat CtEvidence
ev EqRel
eq_rel SwapFlag
IsSwapped TcType
ty2 TcCoercion
co2 TcType
ty1 TcType
ps_ty1
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (TyVarTy TcTyVar
tv1) TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar CtEvidence
ev EqRel
eq_rel SwapFlag
NotSwapped TcTyVar
tv1 TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 (TyVarTy TcTyVar
tv2) TcType
ps_ty2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar CtEvidence
ev EqRel
eq_rel SwapFlag
IsSwapped TcTyVar
tv2 TcType
ps_ty2 TcType
ty1 TcType
ps_ty1
can_eq_nc' Bool
_flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel ty1 :: TcType
ty1@(LitTy TyLit
l1) TcType
_ (LitTy TyLit
l2) TcType
_
| 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 -> TcType -> TcCoercion
mkReflCo (EqRel -> Role
eqRelRole EqRel
eq_rel) TcType
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
(FunTy { ft_mult :: TcType -> TcType
ft_mult = TcType
am1, ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
af1, ft_arg :: TcType -> TcType
ft_arg = TcType
ty1a, ft_res :: TcType -> TcType
ft_res = TcType
ty1b }) TcType
_
(FunTy { ft_mult :: TcType -> TcType
ft_mult = TcType
am2, ft_af :: TcType -> AnonArgFlag
ft_af = AnonArgFlag
af2, ft_arg :: TcType -> TcType
ft_arg = TcType
ty2a, ft_res :: TcType -> TcType
ft_res = TcType
ty2b }) TcType
_
| AnonArgFlag
af1 AnonArgFlag -> AnonArgFlag -> Bool
forall a. Eq a => a -> a -> Bool
== AnonArgFlag
af2
, Just TcType
ty1a_rep <- HasDebugCallStack => TcType -> Maybe TcType
TcType -> Maybe TcType
getRuntimeRep_maybe TcType
ty1a
, Just TcType
ty1b_rep <- HasDebugCallStack => TcType -> Maybe TcType
TcType -> Maybe TcType
getRuntimeRep_maybe TcType
ty1b
, Just TcType
ty2a_rep <- HasDebugCallStack => TcType -> Maybe TcType
TcType -> Maybe TcType
getRuntimeRep_maybe TcType
ty2a
, Just TcType
ty2b_rep <- HasDebugCallStack => TcType -> Maybe TcType
TcType -> Maybe TcType
getRuntimeRep_maybe TcType
ty2b
= CtEvidence
-> EqRel
-> TyCon
-> [TcType]
-> [TcType]
-> TcS (StopOrContinue Ct)
canDecomposableTyConAppOK CtEvidence
ev EqRel
eq_rel TyCon
funTyCon
[TcType
am1, TcType
ty1a_rep, TcType
ty1b_rep, TcType
ty1a, TcType
ty1b]
[TcType
am2, TcType
ty2a_rep, TcType
ty2b_rep, TcType
ty2a, TcType
ty2b]
can_eq_nc' Bool
_flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel
(TyConApp TyCon
tc1 [TcType]
tys1) TcType
_
(TyConApp TyCon
tc2 [TcType]
tys2) TcType
_
| Bool -> Bool
not (TyCon -> Bool
isTypeFamilyTyCon TyCon
tc1)
, Bool -> Bool
not (TyCon -> Bool
isTypeFamilyTyCon TyCon
tc2)
= CtEvidence
-> EqRel
-> TyCon
-> [TcType]
-> TyCon
-> [TcType]
-> TcS (StopOrContinue Ct)
canTyConApp CtEvidence
ev EqRel
eq_rel TyCon
tc1 [TcType]
tys1 TyCon
tc2 [TcType]
tys2
can_eq_nc' Bool
_flat GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel
s1 :: TcType
s1@(ForAllTy {}) TcType
_ s2 :: TcType
s2@(ForAllTy {}) TcType
_
= CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
can_eq_nc_forall CtEvidence
ev EqRel
eq_rel TcType
s1 TcType
s2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (AppTy TcType
t1 TcType
s1) TcType
_ TcType
ty2 TcType
_
| EqRel
NomEq <- EqRel
eq_rel
, Just (TcType
t2, TcType
s2) <- TcType -> Maybe (TcType, TcType)
tcSplitAppTy_maybe TcType
ty2
= CtEvidence
-> TcType -> TcType -> TcType -> TcType -> TcS (StopOrContinue Ct)
can_eq_app CtEvidence
ev TcType
t1 TcType
s1 TcType
t2 TcType
s2
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
_ (AppTy TcType
t2 TcType
s2) TcType
_
| EqRel
NomEq <- EqRel
eq_rel
, Just (TcType
t1, TcType
s1) <- TcType -> Maybe (TcType, TcType)
tcSplitAppTy_maybe TcType
ty1
= CtEvidence
-> TcType -> TcType -> TcType -> TcType -> TcS (StopOrContinue Ct)
can_eq_app CtEvidence
ev TcType
t1 TcType
s1 TcType
t2 TcType
s2
can_eq_nc' Bool
False GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
ev EqRel
eq_rel TcType
_ TcType
ps_ty1 TcType
_ TcType
ps_ty2
= do { (TcType
xi1, TcCoercion
co1) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev TcType
ps_ty1
; (TcType
xi2, TcCoercion
co2) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev TcType
ps_ty2
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped TcType
xi1 TcType
xi2 TcCoercion
co1 TcCoercion
co2
; Bool
-> GlobalRdrEnv
-> (FamInstEnv, FamInstEnv)
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc' Bool
True GlobalRdrEnv
rdr_env (FamInstEnv, FamInstEnv)
envs CtEvidence
new_ev EqRel
eq_rel TcType
xi1 TcType
xi1 TcType
xi2 TcType
xi2 }
can_eq_nc' Bool
True GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel TcType
_ TcType
ps_ty1 TcType
_ TcType
ps_ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"can_eq_nc' catch-all case" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ps_ty1 SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ps_ty2)
; case EqRel
eq_rel of
EqRel
ReprEq -> Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
OtherCIS CtEvidence
ev)
EqRel
NomEq -> Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
InsolubleCIS CtEvidence
ev) }
can_eq_nc_forall :: CtEvidence -> EqRel
-> Type -> Type
-> TcS (StopOrContinue Ct)
can_eq_nc_forall :: CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
can_eq_nc_forall CtEvidence
ev EqRel
eq_rel TcType
s1 TcType
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 = [TcType] -> VarSet
tyCoVarsOfTypes [TcType
s1,TcType
s2]
([TyVarBinder]
bndrs1, TcType
phi1) = TcType -> ([TyVarBinder], TcType)
tcSplitForAllVarBndrs TcType
s1
([TyVarBinder]
bndrs2, TcType
phi2) = TcType -> ([TyVarBinder], TcType)
tcSplitForAllVarBndrs TcType
s2
; if Bool -> Bool
not ([TyVarBinder] -> [TyVarBinder] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [TyVarBinder]
bndrs1 [TyVarBinder]
bndrs2)
then do { String -> SDoc -> TcS ()
traceTcS String
"Forall failure" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
s1, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
s2, [TyVarBinder] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVarBinder]
bndrs1, [TyVarBinder] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVarBinder]
bndrs2
, [ArgFlag] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((TyVarBinder -> ArgFlag) -> [TyVarBinder] -> [ArgFlag]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBinder -> ArgFlag
forall tv argf. VarBndr tv argf -> argf
binderArgFlag [TyVarBinder]
bndrs1)
, [ArgFlag] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((TyVarBinder -> ArgFlag) -> [TyVarBinder] -> [ArgFlag]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBinder -> ArgFlag
forall tv argf. VarBndr tv argf -> argf
binderArgFlag [TyVarBinder]
bndrs2) ]
; CtEvidence -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev TcType
s1 TcType
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
$
[TyVarBinder] -> [TcTyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyVarBinder]
bndrs1
; let skol_info :: SkolemInfo
skol_info = TcType -> SkolemInfo
UnifyForAllSkol TcType
phi1
phi1' :: TcType
phi1' = HasCallStack => TCvSubst -> TcType -> TcType
TCvSubst -> TcType -> TcType
substTy TCvSubst
subst1 TcType
phi1
go :: [TcTyVar] -> TCvSubst -> [TyVarBinder]
-> TcS (TcCoercion, Cts)
go :: [TcTyVar] -> TCvSubst -> [TyVarBinder] -> TcS (TcCoercion, Bag Ct)
go (TcTyVar
skol_tv:[TcTyVar]
skol_tvs) TCvSubst
subst (TyVarBinder
bndr2:[TyVarBinder]
bndrs2)
= do { let tv2 :: TcTyVar
tv2 = TyVarBinder -> TcTyVar
forall tv argf. VarBndr tv argf -> tv
binderVar TyVarBinder
bndr2
; (TcCoercion
kind_co, Bag Ct
wanteds1) <- CtLoc -> Role -> TcType -> TcType -> TcS (TcCoercion, Bag Ct)
unify CtLoc
loc Role
Nominal (TcTyVar -> TcType
tyVarKind TcTyVar
skol_tv)
(HasCallStack => TCvSubst -> TcType -> TcType
TCvSubst -> TcType -> TcType
substTy TCvSubst
subst (TcTyVar -> TcType
tyVarKind TcTyVar
tv2))
; let subst' :: TCvSubst
subst' = TCvSubst -> TcTyVar -> TcType -> TCvSubst
extendTvSubstAndInScope TCvSubst
subst TcTyVar
tv2
(TcType -> TcCoercion -> TcType
mkCastTy (TcTyVar -> TcType
mkTyVarTy TcTyVar
skol_tv) TcCoercion
kind_co)
; (TcCoercion
co, Bag Ct
wanteds2) <- [TcTyVar] -> TCvSubst -> [TyVarBinder] -> TcS (TcCoercion, Bag Ct)
go [TcTyVar]
skol_tvs TCvSubst
subst' [TyVarBinder]
bndrs2
; (TcCoercion, Bag Ct) -> TcS (TcCoercion, Bag Ct)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TcTyVar -> TcCoercion -> TcCoercion -> TcCoercion
mkTcForAllCo TcTyVar
skol_tv TcCoercion
kind_co TcCoercion
co
, Bag Ct
wanteds1 Bag Ct -> Bag Ct -> Bag Ct
forall a. Bag a -> Bag a -> Bag a
`unionBags` Bag Ct
wanteds2 ) }
go [] TCvSubst
subst [TyVarBinder]
bndrs2
= ASSERT( null bndrs2 )
CtLoc -> Role -> TcType -> TcType -> TcS (TcCoercion, Bag Ct)
unify CtLoc
loc (EqRel -> Role
eqRelRole EqRel
eq_rel) TcType
phi1' (TCvSubst -> TcType -> TcType
substTyUnchecked TCvSubst
subst TcType
phi2)
go [TcTyVar]
_ TCvSubst
_ [TyVarBinder]
_ = String -> TcS (TcCoercion, Bag Ct)
forall a. String -> a
panic String
"cna_eq_nc_forall"
empty_subst2 :: TCvSubst
empty_subst2 = InScopeSet -> TCvSubst
mkEmptyTCvSubst (TCvSubst -> InScopeSet
getTCvInScope TCvSubst
subst1)
; (TcLevel
lvl, (TcCoercion
all_co, Bag Ct
wanteds)) <- SDoc
-> TcS (TcCoercion, Bag Ct) -> TcS (TcLevel, (TcCoercion, Bag Ct))
forall a. SDoc -> TcS a -> TcS (TcLevel, a)
pushLevelNoWorkList (SkolemInfo -> SDoc
forall a. Outputable a => a -> SDoc
ppr SkolemInfo
skol_info) (TcS (TcCoercion, Bag Ct) -> TcS (TcLevel, (TcCoercion, Bag Ct)))
-> TcS (TcCoercion, Bag Ct) -> TcS (TcLevel, (TcCoercion, Bag Ct))
forall a b. (a -> b) -> a -> b
$
[TcTyVar] -> TCvSubst -> [TyVarBinder] -> TcS (TcCoercion, Bag Ct)
go [TcTyVar]
skol_tvs TCvSubst
empty_subst2 [TyVarBinder]
bndrs2
; TcLevel -> SkolemInfo -> [TcTyVar] -> Bag Ct -> TcS ()
emitTvImplicationTcS TcLevel
lvl SkolemInfo
skol_info [TcTyVar]
skol_tvs Bag Ct
wanteds
; 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
$
TcType -> TcType -> SDoc
pprEq TcType
s1 TcType
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 -> TcType -> TcType -> TcS (TcCoercion, Bag Ct)
unify CtLoc
loc Role
role TcType
ty1 TcType
ty2
| TcType
ty1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
ty2
= (TcCoercion, Bag Ct) -> TcS (TcCoercion, Bag Ct)
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
ty1, Bag Ct
forall a. Bag a
emptyBag)
| Bool
otherwise
= do { (CtEvidence
wanted, TcCoercion
co) <- CtLoc -> Role -> TcType -> TcType -> TcS (CtEvidence, TcCoercion)
newWantedEq CtLoc
loc Role
role TcType
ty1 TcType
ty2
; (TcCoercion, Bag Ct) -> TcS (TcCoercion, Bag Ct)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercion
co, Ct -> Bag Ct
forall a. a -> Bag a
unitBag (CtEvidence -> Ct
mkNonCanonical CtEvidence
wanted)) }
zonk_eq_types :: TcType -> TcType -> TcS (Either (Pair TcType) TcType)
zonk_eq_types :: TcType -> TcType -> TcS (Either (Pair TcType) TcType)
zonk_eq_types = TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go
where
go :: TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go (TyVarTy TcTyVar
tv1) (TyVarTy TcTyVar
tv2) = TcTyVar -> TcTyVar -> TcS (Either (Pair TcType) TcType)
tyvar_tyvar TcTyVar
tv1 TcTyVar
tv2
go (TyVarTy TcTyVar
tv1) TcType
ty2 = SwapFlag -> TcTyVar -> TcType -> TcS (Either (Pair TcType) TcType)
tyvar SwapFlag
NotSwapped TcTyVar
tv1 TcType
ty2
go TcType
ty1 (TyVarTy TcTyVar
tv2) = SwapFlag -> TcTyVar -> TcType -> TcS (Either (Pair TcType) TcType)
tyvar SwapFlag
IsSwapped TcTyVar
tv2 TcType
ty1
go TcType
ty1 TcType
ty2
| Just (Scaled TcType
w1 TcType
arg1, TcType
res1) <- Maybe (Scaled TcType, TcType)
split1
, Just (Scaled TcType
w2 TcType
arg2, TcType
res2) <- Maybe (Scaled TcType, TcType)
split2
, TcType -> TcType -> Bool
eqType TcType
w1 TcType
w2
= do { Either (Pair TcType) TcType
res_a <- TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go TcType
arg1 TcType
arg2
; Either (Pair TcType) TcType
res_b <- TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go TcType
res1 TcType
res2
; Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType))
-> Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall a b. (a -> b) -> a -> b
$ (TcType -> TcType -> TcType)
-> Either (Pair TcType) TcType
-> Either (Pair TcType) TcType
-> Either (Pair TcType) TcType
forall a b c.
(a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev (TcType -> TcType -> TcType -> TcType
mkVisFunTy TcType
w1) Either (Pair TcType) TcType
res_b Either (Pair TcType) TcType
res_a
}
| Maybe (Scaled TcType, TcType) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (Scaled TcType, TcType)
split1 Bool -> Bool -> Bool
|| Maybe (Scaled TcType, TcType) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (Scaled TcType, TcType)
split2
= TcType -> TcType -> TcS (Either (Pair TcType) TcType)
forall {m :: * -> *} {a} {b}.
Monad m =>
a -> a -> m (Either (Pair a) b)
bale_out TcType
ty1 TcType
ty2
where
split1 :: Maybe (Scaled TcType, TcType)
split1 = TcType -> Maybe (Scaled TcType, TcType)
tcSplitFunTy_maybe TcType
ty1
split2 :: Maybe (Scaled TcType, TcType)
split2 = TcType -> Maybe (Scaled TcType, TcType)
tcSplitFunTy_maybe TcType
ty2
go TcType
ty1 TcType
ty2
| Just (TyCon
tc1, [TcType]
tys1) <- HasDebugCallStack => TcType -> Maybe (TyCon, [TcType])
TcType -> Maybe (TyCon, [TcType])
repSplitTyConApp_maybe TcType
ty1
, Just (TyCon
tc2, [TcType]
tys2) <- HasDebugCallStack => TcType -> Maybe (TyCon, [TcType])
TcType -> Maybe (TyCon, [TcType])
repSplitTyConApp_maybe TcType
ty2
= if TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2 Bool -> Bool -> Bool
&& [TcType]
tys1 [TcType] -> [TcType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [TcType]
tys2
then TyCon -> [TcType] -> [TcType] -> TcS (Either (Pair TcType) TcType)
tycon TyCon
tc1 [TcType]
tys1 [TcType]
tys2
else TcType -> TcType -> TcS (Either (Pair TcType) TcType)
forall {m :: * -> *} {a} {b}.
Monad m =>
a -> a -> m (Either (Pair a) b)
bale_out TcType
ty1 TcType
ty2
go TcType
ty1 TcType
ty2
| Just (TcType
ty1a, TcType
ty1b) <- TcType -> Maybe (TcType, TcType)
tcRepSplitAppTy_maybe TcType
ty1
, Just (TcType
ty2a, TcType
ty2b) <- TcType -> Maybe (TcType, TcType)
tcRepSplitAppTy_maybe TcType
ty2
= do { Either (Pair TcType) TcType
res_a <- TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go TcType
ty1a TcType
ty2a
; Either (Pair TcType) TcType
res_b <- TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go TcType
ty1b TcType
ty2b
; Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType))
-> Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall a b. (a -> b) -> a -> b
$ (TcType -> TcType -> TcType)
-> Either (Pair TcType) TcType
-> Either (Pair TcType) TcType
-> Either (Pair TcType) TcType
forall a b c.
(a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev TcType -> TcType -> TcType
mkAppTy Either (Pair TcType) TcType
res_b Either (Pair TcType) TcType
res_a }
go ty1 :: TcType
ty1@(LitTy TyLit
lit1) (LitTy TyLit
lit2)
| TyLit
lit1 TyLit -> TyLit -> Bool
forall a. Eq a => a -> a -> Bool
== TyLit
lit2
= Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> Either (Pair TcType) TcType
forall a b. b -> Either a b
Right TcType
ty1)
go TcType
ty1 TcType
ty2 = TcType -> TcType -> TcS (Either (Pair TcType) TcType)
forall {m :: * -> *} {a} {b}.
Monad m =>
a -> a -> m (Either (Pair a) b)
bale_out TcType
ty1 TcType
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 -> TcType -> TcS (Either (Pair TcType) TcType)
tyvar SwapFlag
swapped TcTyVar
tv TcType
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 TcType) TcType)
forall {b}. TcS (Either (Pair TcType) b)
give_up
Indirect TcType
ty' -> do { TcTyVar -> TcType -> TcS ()
forall {a} {a}. (Outputable a, Outputable a) => a -> a -> TcS ()
trace_indirect TcTyVar
tv TcType
ty'
; SwapFlag
-> (TcType -> TcType -> TcS (Either (Pair TcType) TcType))
-> TcType
-> TcType
-> TcS (Either (Pair TcType) TcType)
forall a b. SwapFlag -> (a -> a -> b) -> a -> a -> b
unSwap SwapFlag
swapped TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go TcType
ty' TcType
ty } }
TcTyVarDetails
_ -> TcS (Either (Pair TcType) TcType)
forall {b}. TcS (Either (Pair TcType) b)
give_up
where
give_up :: TcS (Either (Pair TcType) b)
give_up = Either (Pair TcType) b -> TcS (Either (Pair TcType) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair TcType) b -> TcS (Either (Pair TcType) b))
-> Either (Pair TcType) b -> TcS (Either (Pair TcType) b)
forall a b. (a -> b) -> a -> b
$ Pair TcType -> Either (Pair TcType) b
forall a b. a -> Either a b
Left (Pair TcType -> Either (Pair TcType) b)
-> Pair TcType -> Either (Pair TcType) b
forall a b. (a -> b) -> a -> b
$ SwapFlag
-> (TcType -> TcType -> Pair TcType)
-> TcType
-> TcType
-> Pair TcType
forall a b. SwapFlag -> (a -> a -> b) -> a -> a -> b
unSwap SwapFlag
swapped TcType -> TcType -> Pair TcType
forall a. a -> a -> Pair a
Pair (TcTyVar -> TcType
mkTyVarTy TcTyVar
tv) TcType
ty
tyvar_tyvar :: TcTyVar -> TcTyVar -> TcS (Either (Pair TcType) TcType)
tyvar_tyvar TcTyVar
tv1 TcTyVar
tv2
| TcTyVar
tv1 TcTyVar -> TcTyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TcTyVar
tv2 = Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType -> Either (Pair TcType) TcType
forall a b. b -> Either a b
Right (TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1))
| Bool
otherwise = do { (TcType
ty1', Bool
progress1) <- TcTyVar -> TcS (TcType, Bool)
quick_zonk TcTyVar
tv1
; (TcType
ty2', Bool
progress2) <- TcTyVar -> TcS (TcType, Bool)
quick_zonk TcTyVar
tv2
; if Bool
progress1 Bool -> Bool -> Bool
|| Bool
progress2
then TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go TcType
ty1' TcType
ty2'
else Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType))
-> Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall a b. (a -> b) -> a -> b
$ Pair TcType -> Either (Pair TcType) TcType
forall a b. a -> Either a b
Left (TcType -> TcType -> Pair TcType
forall a. a -> a -> Pair a
Pair (TcTyVar -> TcType
TyVarTy TcTyVar
tv1) (TcTyVar -> TcType
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 (TcType, 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 -> (TcType, Bool) -> TcS (TcType, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVar -> TcType
TyVarTy TcTyVar
tv, Bool
False)
Indirect TcType
ty' -> do { TcTyVar -> TcType -> TcS ()
forall {a} {a}. (Outputable a, Outputable a) => a -> a -> TcS ()
trace_indirect TcTyVar
tv TcType
ty'
; (TcType, Bool) -> TcS (TcType, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcType
ty', Bool
True) } }
TcTyVarDetails
_ -> (TcType, Bool) -> TcS (TcType, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (TcTyVar -> TcType
TyVarTy TcTyVar
tv, Bool
False)
tycon :: TyCon -> [TcType] -> [TcType]
-> TcS (Either (Pair TcType) TcType)
tycon :: TyCon -> [TcType] -> [TcType] -> TcS (Either (Pair TcType) TcType)
tycon TyCon
tc [TcType]
tys1 [TcType]
tys2
= do { [Either (Pair TcType) TcType]
results <- (TcType -> TcType -> TcS (Either (Pair TcType) TcType))
-> [TcType] -> [TcType] -> TcS [Either (Pair TcType) TcType]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM TcType -> TcType -> TcS (Either (Pair TcType) TcType)
go [TcType]
tys1 [TcType]
tys2
; Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType))
-> Either (Pair TcType) TcType -> TcS (Either (Pair TcType) TcType)
forall a b. (a -> b) -> a -> b
$ case [Either (Pair TcType) TcType] -> Either (Pair [TcType]) [TcType]
combine_results [Either (Pair TcType) TcType]
results of
Left Pair [TcType]
tys -> Pair TcType -> Either (Pair TcType) TcType
forall a b. a -> Either a b
Left (TyCon -> [TcType] -> TcType
mkTyConApp TyCon
tc ([TcType] -> TcType) -> Pair [TcType] -> Pair TcType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair [TcType]
tys)
Right [TcType]
tys -> TcType -> Either (Pair TcType) TcType
forall a b. b -> Either a b
Right (TyCon -> [TcType] -> TcType
mkTyConApp TyCon
tc [TcType]
tys) }
combine_results :: [Either (Pair TcType) TcType]
-> Either (Pair [TcType]) [TcType]
combine_results :: [Either (Pair TcType) TcType] -> Either (Pair [TcType]) [TcType]
combine_results = (Pair [TcType] -> Pair [TcType])
-> ([TcType] -> [TcType])
-> Either (Pair [TcType]) [TcType]
-> Either (Pair [TcType]) [TcType]
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (([TcType] -> [TcType]) -> Pair [TcType] -> Pair [TcType]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [TcType] -> [TcType]
forall a. [a] -> [a]
reverse) [TcType] -> [TcType]
forall a. [a] -> [a]
reverse (Either (Pair [TcType]) [TcType]
-> Either (Pair [TcType]) [TcType])
-> ([Either (Pair TcType) TcType]
-> Either (Pair [TcType]) [TcType])
-> [Either (Pair TcType) TcType]
-> Either (Pair [TcType]) [TcType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Either (Pair [TcType]) [TcType]
-> Either (Pair TcType) TcType -> Either (Pair [TcType]) [TcType])
-> Either (Pair [TcType]) [TcType]
-> [Either (Pair TcType) TcType]
-> Either (Pair [TcType]) [TcType]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((TcType -> [TcType] -> [TcType])
-> Either (Pair [TcType]) [TcType]
-> Either (Pair TcType) TcType
-> Either (Pair [TcType]) [TcType]
forall a b c.
(a -> b -> c)
-> Either (Pair b) b -> Either (Pair a) a -> Either (Pair c) c
combine_rev (:)) ([TcType] -> Either (Pair [TcType]) [TcType]
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 :: forall a b c.
(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
-> TcType
-> ((Bag GlobalRdrElt, TcCoercion), TcType)
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_newtype_nc CtEvidence
ev SwapFlag
swapped TcType
ty1 ((Bag GlobalRdrElt
gres, TcCoercion
co), TcType
ty1') TcType
ty2 TcType
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, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1', TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2 ]
; CtLoc -> TcType -> TcS ()
checkReductionDepth (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) TcType
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
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
ty1' TcType
ps_ty2
(TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co) (Role -> TcType -> TcCoercion
mkTcReflCo Role
Representational TcType
ps_ty2)
; Bool
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
False CtEvidence
new_ev EqRel
ReprEq TcType
ty1' TcType
ty1' TcType
ty2 TcType
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
-> TcType -> TcType -> TcType -> TcType -> TcS (StopOrContinue Ct)
can_eq_app CtEvidence
ev TcType
s1 TcType
t1 TcType
s2 TcType
t2
| CtDerived {} <- CtEvidence
ev
= do { CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
unifyDeriveds CtLoc
loc [Role
Nominal, Role
Nominal] [TcType
s1, TcType
t1] [TcType
s2, TcType
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 -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Nominal TcType
s1 TcType
s2
; let arg_loc :: CtLoc
arg_loc
| TcType -> Bool
isNextArgVisible TcType
s1 = CtLoc
loc
| Bool
otherwise = CtLoc -> (CtOrigin -> CtOrigin) -> CtLoc
updateCtLocOrigin CtLoc
loc CtOrigin -> CtOrigin
toInvisibleOrigin
; TcCoercion
co_t <- CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
arg_loc Role
Nominal TcType
t1 TcType
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" }
| TcType
s1k TcType -> TcType -> Bool
`mismatches` TcType
s2k
= CtEvidence -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev (TcType
s1 TcType -> TcType -> TcType
`mkAppTy` TcType
t1) (TcType
s2 TcType -> TcType -> TcType
`mkAppTy` TcType
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 -> (TcType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc ( CtEvidence -> TcType -> TcType -> TcType
mkTcEqPredLikeEv CtEvidence
ev TcType
s1 TcType
s2
, TcCoercion -> EvTerm
evCoercion TcCoercion
co_s )
; CtEvidence
evar_t <- CtLoc -> (TcType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc ( CtEvidence -> TcType -> TcType -> TcType
mkTcEqPredLikeEv CtEvidence
ev TcType
t1 TcType
t2
, TcCoercion -> EvTerm
evCoercion TcCoercion
co_t )
; [CtEvidence] -> TcS ()
emitWorkNC [CtEvidence
evar_t]
; CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqNC CtEvidence
evar_s EqRel
NomEq TcType
s1 TcType
s2 }
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
s1k :: TcType
s1k = HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
s1
s2k :: TcType
s2k = HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
s2
TcType
k1 mismatches :: TcType -> TcType -> Bool
`mismatches` TcType
k2
= TcType -> Bool
isForAllTy TcType
k1 Bool -> Bool -> Bool
&& Bool -> Bool
not (TcType -> Bool
isForAllTy TcType
k2)
Bool -> Bool -> Bool
|| Bool -> Bool
not (TcType -> Bool
isForAllTy TcType
k1) Bool -> Bool -> Bool
&& TcType -> Bool
isForAllTy TcType
k2
canEqCast :: Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType -> Coercion
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqCast :: Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcCoercion
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCast Bool
flat CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcType
ty1 TcCoercion
co1 TcType
ty2 TcType
ps_ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"Decomposing cast" ([SDoc] -> SDoc
vcat [ CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"|>" SDoc -> SDoc -> SDoc
<+> TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
co1
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ps_ty2 ])
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
ty1 TcType
ps_ty2
(Role -> TcType -> TcCoercion -> TcCoercion
mkTcGReflRightCo Role
role TcType
ty1 TcCoercion
co1)
(Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
ps_ty2)
; Bool
-> CtEvidence
-> EqRel
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
can_eq_nc Bool
flat CtEvidence
new_ev EqRel
eq_rel TcType
ty1 TcType
ty1 TcType
ty2 TcType
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
-> [TcType]
-> TyCon
-> [TcType]
-> TcS (StopOrContinue Ct)
canTyConApp CtEvidence
ev EqRel
eq_rel TyCon
tc1 [TcType]
tys1 TyCon
tc2 [TcType]
tys2
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2
, [TcType]
tys1 [TcType] -> [TcType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [TcType]
tys2
= do { InertSet
inerts <- TcS InertSet
getTcSInerts
; if InertSet -> Bool
can_decompose InertSet
inerts
then CtEvidence
-> EqRel
-> TyCon
-> [TcType]
-> [TcType]
-> TcS (StopOrContinue Ct)
canDecomposableTyConAppOK CtEvidence
ev EqRel
eq_rel TyCon
tc1 [TcType]
tys1 [TcType]
tys2
else CtEvidence -> EqRel -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqFailure CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
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 (CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
OtherCIS 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 -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqFailure CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ty2
| Bool
otherwise
= CtEvidence -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev TcType
ty1 TcType
ty2
where
ty1 :: TcType
ty1 = TyCon -> [TcType] -> TcType
mkTyConApp TyCon
tc1 [TcType]
tys1
ty2 :: TcType
ty2 = TyCon -> [TcType] -> TcType
mkTyConApp TyCon
tc2 [TcType]
tys2
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
pred :: TcType
pred = CtEvidence -> TcType
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
&& Bag Ct -> Bool
forall a. Bag a -> Bool
isEmptyBag (CtLoc -> TcType -> InertSet -> Bag Ct
matchableGivens CtLoc
loc TcType
pred InertSet
inerts))
canDecomposableTyConAppOK :: CtEvidence -> EqRel
-> TyCon -> [TcType] -> [TcType]
-> TcS (StopOrContinue Ct)
canDecomposableTyConAppOK :: CtEvidence
-> EqRel
-> TyCon
-> [TcType]
-> [TcType]
-> TcS (StopOrContinue Ct)
canDecomposableTyConAppOK CtEvidence
ev EqRel
eq_rel TyCon
tc [TcType]
tys1 [TcType]
tys2
= ASSERT( tys1 `equalLength` tys2 )
do { String -> SDoc -> TcS ()
traceTcS String
"canDecomposableTyConAppOK"
(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
tc SDoc -> SDoc -> SDoc
$$ [TcType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TcType]
tys1 SDoc -> SDoc -> SDoc
$$ [TcType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TcType]
tys2)
; case CtEvidence
ev of
CtDerived {}
-> CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
unifyDeriveds CtLoc
loc [Role]
tc_roles [TcType]
tys1 [TcType]
tys2
CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest }
-> do { [TcCoercion]
cos <- (CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion)
-> [CtLoc] -> [Role] -> [TcType] -> [TcType] -> 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 -> TcType -> TcType -> TcS TcCoercion
unifyWanted [CtLoc]
new_locs [Role]
tc_roles [TcType]
tys1 [TcType]
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 -> [(TcType, EvTerm)] -> TcS [CtEvidence]
newGivenEvVars CtLoc
loc ([(TcType, EvTerm)] -> TcS [CtEvidence])
-> [(TcType, EvTerm)] -> TcS [CtEvidence]
forall a b. (a -> b) -> a -> b
$
[ ( Role -> TcType -> TcType -> TcType
mkPrimEqPredRole Role
r TcType
ty1 TcType
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, TcType
ty1, TcType
ty2, Int
i) <- [Role]
-> [TcType] -> [TcType] -> [Int] -> [(Role, TcType, TcType, Int)]
forall a b c d. [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip4 [Role]
tc_roles [TcType]
tys1 [TcType]
tys2 [Int
0..]
, Role
r Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
/= Role
Phantom
, Bool -> Bool
not (TcType -> Bool
isCoercionTy TcType
ty1) Bool -> Bool -> Bool
&& Bool -> Bool
not (TcType -> Bool
isCoercionTy TcType
ty2) ]
; [CtEvidence] -> TcS ()
emitWorkNC [CtEvidence]
given_evs }
; CtEvidence -> String -> TcS (StopOrContinue Ct)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Decomposed TyConApp" }
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 -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqFailure CtEvidence
ev EqRel
NomEq TcType
ty1 TcType
ty2
= CtEvidence -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev TcType
ty1 TcType
ty2
canEqFailure CtEvidence
ev EqRel
ReprEq TcType
ty1 TcType
ty2
= do { (TcType
xi1, TcCoercion
co1) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev TcType
ty1
; (TcType
xi2, TcCoercion
co2) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_FlattenAll CtEvidence
ev TcType
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, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
xi1, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
xi2 ]
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped TcType
xi1 TcType
xi2 TcCoercion
co1 TcCoercion
co2
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
OtherCIS CtEvidence
new_ev) }
canEqHardFailure :: CtEvidence
-> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure :: CtEvidence -> TcType -> TcType -> TcS (StopOrContinue Ct)
canEqHardFailure CtEvidence
ev TcType
ty1 TcType
ty2
= do { String -> SDoc -> TcS ()
traceTcS String
"canEqHardFailure" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty1 SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty2)
; (TcType
s1, TcCoercion
co1) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev TcType
ty1
; (TcType
s2, TcCoercion
co2) <- FlattenMode -> CtEvidence -> TcType -> TcS (TcType, TcCoercion)
flatten FlattenMode
FM_SubstOnly CtEvidence
ev TcType
ty2
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped TcType
s1 TcType
s2 TcCoercion
co1 TcCoercion
co2
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
InsolubleCIS CtEvidence
new_ev) }
canCFunEqCan :: CtEvidence
-> TyCon -> [TcType]
-> TcTyVar
-> TcS (StopOrContinue Ct)
canCFunEqCan :: CtEvidence
-> TyCon -> [TcType] -> TcTyVar -> TcS (StopOrContinue Ct)
canCFunEqCan CtEvidence
ev TyCon
fn [TcType]
tys TcTyVar
fsk
= do { ([TcType]
tys', [TcCoercion]
cos, TcCoercion
kind_co) <- CtEvidence
-> TyCon -> [TcType] -> TcS ([TcType], [TcCoercion], TcCoercion)
flattenArgsNom CtEvidence
ev TyCon
fn [TcType]
tys
; let lhs_co :: TcCoercion
lhs_co = Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTcTyConAppCo Role
Nominal TyCon
fn [TcCoercion]
cos
new_lhs :: TcType
new_lhs = TyCon -> [TcType] -> TcType
mkTyConApp TyCon
fn [TcType]
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" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
new_lhs)
; let fsk_ty :: TcType
fsk_ty = TcTyVar -> TcType
mkTyVarTy TcTyVar
fsk
; CtEvidence
ev' <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
NotSwapped TcType
new_lhs TcType
fsk_ty
TcCoercion
lhs_co (TcType -> TcCoercion
mkTcNomReflCo TcType
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
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TcTyVar -> TcType
tyVarKind TcTyVar
fsk)
, String -> SDoc
text String
"LHS:" SDoc -> SDoc -> SDoc
<+> SDoc -> Int -> SDoc -> SDoc
hang (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [TcType] -> TcType
mkTyConApp TyCon
fn [TcType]
tys))
Int
2 (SDoc
dcolon SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind (TyCon -> [TcType] -> TcType
mkTyConApp TyCon
fn [TcType]
tys)))
, String -> SDoc
text String
"New LHS" SDoc -> SDoc -> SDoc
<+> SDoc -> Int -> SDoc -> SDoc
hang (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
new_lhs)
Int
2 (SDoc
dcolon SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
new_lhs)) ]
; (CtEvidence
ev', TcCoercion
new_co, TcTyVar
new_fsk)
<- CtFlavour
-> CtLoc
-> TyCon
-> [TcType]
-> TcS (CtEvidence, TcCoercion, TcTyVar)
newFlattenSkolem CtFlavour
flav (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) TyCon
fn [TcType]
tys'
; let xi :: TcType
xi = TcTyVar -> TcType
mkTyVarTy TcTyVar
new_fsk TcType -> TcCoercion -> TcType
`mkCastTy` TcCoercion
kind_co
co :: TcCoercion
co = TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
lhs_co TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo`
Role -> TcType -> TcCoercion -> TcCoercion -> TcCoercion
mkTcCoherenceRightCo Role
Nominal
(TcTyVar -> TcType
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 -> TcType -> TcS ()
dischargeFunEq CtEvidence
ev TcTyVar
fsk TcCoercion
co TcType
xi
; (CtEvidence, TcTyVar) -> TcS (CtEvidence, TcTyVar)
forall (m :: * -> *) a. Monad m => a -> m a
return (CtEvidence
ev', TcTyVar
new_fsk) }
; TyCon -> [TcType] -> (TcCoercion, TcType, CtFlavour) -> TcS ()
extendFlatCache TyCon
fn [TcType]
tys' (HasDebugCallStack => CtEvidence -> TcCoercion
CtEvidence -> TcCoercion
ctEvCoercion CtEvidence
ev', TcTyVar -> TcType
mkTyVarTy TcTyVar
fsk', CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev')
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CFunEqCan :: CtEvidence -> TyCon -> [TcType] -> TcTyVar -> Ct
CFunEqCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
ev', cc_fun :: TyCon
cc_fun = TyCon
fn
, cc_tyargs :: [TcType]
cc_tyargs = [TcType]
tys', cc_fsk :: TcTyVar
cc_fsk = TcTyVar
fsk' }) }
canEqTyVar :: CtEvidence
-> EqRel -> SwapFlag
-> TcTyVar
-> TcType
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar :: CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi1 TcType
xi2 TcType
ps_xi2
| TcType
k1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
k2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi1 TcType
xi2 TcType
ps_xi2
| Bool
otherwise
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHetero CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi1 TcType
k1 TcType
xi2 TcType
ps_xi2 TcType
k2
where
k1 :: TcType
k1 = TcTyVar -> TcType
tyVarKind TcTyVar
tv1
k2 :: TcType
k2 = HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
xi2
canEqTyVarHetero :: CtEvidence
-> EqRel -> SwapFlag
-> TcTyVar -> TcType
-> TcKind
-> TcType -> TcType
-> TcKind
-> TcS (StopOrContinue Ct)
canEqTyVarHetero :: CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHetero CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_tv1 TcType
ki1 TcType
xi2 TcType
ps_xi2 TcType
ki2
= do { TcCoercion
kind_co <- TcS TcCoercion
emit_kind_co
; let
rhs' :: TcType
rhs' = TcType
xi2 TcType -> TcCoercion -> TcType
`mkCastTy` TcCoercion
kind_co
ps_rhs' :: TcType
ps_rhs' = TcType
ps_xi2 TcType -> TcCoercion -> TcType
`mkCastTy` TcCoercion
kind_co
rhs_co :: TcCoercion
rhs_co = Role -> TcType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role TcType
xi2 TcCoercion
kind_co
lhs' :: TcType
lhs' = TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1
lhs_co :: TcCoercion
lhs_co = Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
lhs'
; String -> SDoc -> TcS ()
traceTcS String
"Hetero equality gives rise to kind equality"
(TcCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcCoercion
kind_co SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> [SDoc] -> SDoc
sep [ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ki2, String -> SDoc
text String
"~#", TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ki1 ])
; CtEvidence
type_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
lhs' TcType
rhs' TcCoercion
lhs_co TcCoercion
rhs_co
; CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
type_ev EqRel
eq_rel SwapFlag
NotSwapped TcTyVar
tv1 TcType
ps_tv1 TcType
rhs' TcType
ps_rhs' }
where
emit_kind_co :: TcS CoercionN
emit_kind_co :: TcS TcCoercion
emit_kind_co
| CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
evar } <- CtEvidence
ev
= do { let kind_co :: TcCoercion
kind_co = TcCoercion -> TcCoercion
maybe_sym (TcCoercion -> TcCoercion) -> TcCoercion -> TcCoercion
forall a b. (a -> b) -> a -> b
$ TcCoercion -> TcCoercion
mkTcKindCo (TcTyVar -> TcCoercion
mkTcCoVarCo TcTyVar
evar)
; CtEvidence
kind_ev <- CtLoc -> (TcType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
kind_loc (TcType
kind_pty, TcCoercion -> EvTerm
evCoercion TcCoercion
kind_co)
; [CtEvidence] -> TcS ()
emitWorkNC [CtEvidence
kind_ev]
; TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (HasDebugCallStack => CtEvidence -> TcCoercion
CtEvidence -> TcCoercion
ctEvCoercion CtEvidence
kind_ev) }
| Bool
otherwise
= CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
kind_loc Role
Nominal TcType
ki2 TcType
ki1
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctev_loc CtEvidence
ev
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
kind_loc :: CtLoc
kind_loc = TcType -> TcType -> CtLoc -> CtLoc
mkKindLoc (TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1) TcType
xi2 CtLoc
loc
kind_pty :: TcType
kind_pty = TcType -> TcType -> TcType -> TcType -> TcType
mkHeteroPrimEqPred TcType
liftedTypeKind TcType
liftedTypeKind TcType
ki2 TcType
ki1
maybe_sym :: TcCoercion -> TcCoercion
maybe_sym = case SwapFlag
swapped of
SwapFlag
IsSwapped -> TcCoercion -> TcCoercion
forall a. a -> a
id
SwapFlag
NotSwapped -> TcCoercion -> TcCoercion
mkTcSymCo
canEqTyVarHomo :: CtEvidence
-> EqRel -> SwapFlag
-> TcTyVar
-> TcType
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo :: CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVarHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi1 TcType
xi2 TcType
_
| Just (TcTyVar
tv2, TcCoercion
_) <- TcType -> Maybe (TcTyVar, TcCoercion)
tcGetCastedTyVar_maybe TcType
xi2
, TcTyVar
tv1 TcTyVar -> TcTyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TcTyVar
tv2
= CtEvidence -> EqRel -> TcType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel (TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1)
| Just (TcTyVar
tv2, TcCoercion
co2) <- TcType -> Maybe (TcTyVar, TcCoercion)
tcGetCastedTyVar_maybe TcType
xi2
, Bool -> TcTyVar -> TcTyVar -> Bool
swapOverTyVars (CtEvidence -> Bool
isGiven CtEvidence
ev) 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 :: TcType
ty1 = TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1
new_lhs :: TcType
new_lhs = TcType
ty1 TcType -> TcCoercion -> TcType
`mkCastTy` TcCoercion
sym_co2
lhs_co :: TcCoercion
lhs_co = Role -> TcType -> TcCoercion -> TcCoercion
mkTcGReflLeftCo Role
role TcType
ty1 TcCoercion
sym_co2
new_rhs :: TcType
new_rhs = TcTyVar -> TcType
mkTyVarTy TcTyVar
tv2
rhs_co :: TcCoercion
rhs_co = Role -> TcType -> TcCoercion -> TcCoercion
mkTcGReflRightCo Role
role TcType
new_rhs TcCoercion
co2
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
new_lhs TcType
new_rhs TcCoercion
lhs_co TcCoercion
rhs_co
; DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar2 DynFlags
dflags CtEvidence
new_ev EqRel
eq_rel SwapFlag
IsSwapped TcTyVar
tv2 (TcType
ps_xi1 TcType -> TcCoercion -> TcType
`mkCastTy` TcCoercion
sym_co2) }
canEqTyVarHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
_ TcType
_ TcType
ps_xi2
= do { DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar2 DynFlags
dflags CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi2 }
canEqTyVar2 :: DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar2 :: DynFlags
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TcS (StopOrContinue Ct)
canEqTyVar2 DynFlags
dflags CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
rhs
| MTVU_OK TcType
rhs' <- MetaTyVarUpdateResult TcType
mtvu
= do { CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
lhs TcType
rhs' TcCoercion
rewrite_co1 TcCoercion
rewrite_co2
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CTyEqCan :: CtEvidence -> TcTyVar -> TcType -> EqRel -> Ct
CTyEqCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_ev, cc_tyvar :: TcTyVar
cc_tyvar = TcTyVar
tv1
, cc_rhs :: TcType
cc_rhs = TcType
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
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs)
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
lhs TcType
rhs TcCoercion
rewrite_co1 TcCoercion
rewrite_co2
; let status :: CtIrredStatus
status | EqRel -> TcTyVar -> TcType -> Bool
isInsolubleOccursCheck EqRel
eq_rel TcTyVar
tv1 TcType
rhs
= CtIrredStatus
InsolubleCIS
| MetaTyVarUpdateResult TcType
MTVU_HoleBlocker <- MetaTyVarUpdateResult TcType
mtvu
= CtIrredStatus
BlockedCIS
| Bool
otherwise
= CtIrredStatus
OtherCIS
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredStatus -> CtEvidence -> Ct
mkIrredCt CtIrredStatus
status CtEvidence
new_ev) }
where
mtvu :: MetaTyVarUpdateResult TcType
mtvu = DynFlags -> TcTyVar -> TcType -> MetaTyVarUpdateResult TcType
metaTyVarUpdateOK DynFlags
dflags TcTyVar
tv1 TcType
rhs
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
lhs :: TcType
lhs = TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1
rewrite_co1 :: TcCoercion
rewrite_co1 = Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
lhs
rewrite_co2 :: TcCoercion
rewrite_co2 = Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
rhs
canEqReflexive :: CtEvidence
-> EqRel
-> TcType
-> TcS (StopOrContinue Ct)
canEqReflexive :: CtEvidence -> EqRel -> TcType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel TcType
ty
= do { CtEvidence -> EvTerm -> TcS ()
setEvBindIfWanted CtEvidence
ev (TcCoercion -> EvTerm
evCoercion (TcCoercion -> EvTerm) -> TcCoercion -> EvTerm
forall a b. (a -> b) -> a -> b
$
Role -> TcType -> TcCoercion
mkTcReflCo (EqRel -> Role
eqRelRole EqRel
eq_rel) TcType
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 ((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
<$ :: forall a b. a -> StopOrContinue b -> StopOrContinue a
$c<$ :: forall a b. a -> StopOrContinue b -> StopOrContinue a
fmap :: forall a b. (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 :: forall a. 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 :: forall a. 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 :: forall a b.
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
-> TcType -> TcCoercion -> TcS (StopOrContinue CtEvidence)
rewriteEvidence old_ev :: CtEvidence
old_ev@(CtDerived {}) TcType
new_pred TcCoercion
_co
=
CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence
old_ev { ctev_pred :: TcType
ctev_pred = TcType
new_pred })
rewriteEvidence CtEvidence
old_ev TcType
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 :: TcType
ctev_pred = TcType
new_pred })
rewriteEvidence ev :: CtEvidence
ev@(CtGiven { ctev_evar :: CtEvidence -> TcTyVar
ctev_evar = TcTyVar
old_evar, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc }) TcType
new_pred TcCoercion
co
= do { CtEvidence
new_ev <- CtLoc -> (TcType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc (TcType
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 }) TcType
new_pred TcCoercion
co
= do { MaybeNew
mb_new_ev <- ShadowInfo -> CtLoc -> TcType -> TcS MaybeNew
newWanted_SI ShadowInfo
si CtLoc
loc TcType
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
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
old_ev SwapFlag
swapped TcType
nlhs TcType
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 :: TcType
ctev_pred = TcType
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 :: TcType
ctev_pred = TcType
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 -> (TcType, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc' (TcType
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
= case TcEvDest
dest of
HoleDest CoercionHole
hole ->
do { (CtEvidence
new_ev, TcCoercion
hole_co) <- BlockSubstFlag
-> ShadowInfo
-> CtLoc
-> Role
-> TcType
-> TcType
-> TcS (CtEvidence, TcCoercion)
newWantedEq_SI (CoercionHole -> BlockSubstFlag
ch_blocker CoercionHole
hole) ShadowInfo
si CtLoc
loc'
(CtEvidence -> Role
ctEvRole CtEvidence
old_ev) TcType
nlhs TcType
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, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
nlhs, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
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 }
TcEvDest
_ -> String -> TcS CtEvidence
forall a. String -> a
panic String
"rewriteEqEvidence"
#if __GLASGOW_HASKELL__ <= 810
| otherwise
= panic "rewriteEvidence"
#endif
where
new_pred :: TcType
new_pred = CtEvidence -> TcType -> TcType -> TcType
mkTcEqPredLikeEv CtEvidence
old_ev TcType
nlhs TcType
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 -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Phantom TcType
ty1 TcType
ty2
= do { TcCoercion
kind_co <- CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Nominal (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
ty1) (HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
ty2)
; TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (TcCoercion -> TcType -> TcType -> TcCoercion
mkPhantomCo TcCoercion
kind_co TcType
ty1 TcType
ty2) }
unifyWanted CtLoc
loc Role
role TcType
orig_ty1 TcType
orig_ty2
= TcType -> TcType -> TcS TcCoercion
go TcType
orig_ty1 TcType
orig_ty2
where
go :: TcType -> TcType -> TcS TcCoercion
go TcType
ty1 TcType
ty2 | Just TcType
ty1' <- TcType -> Maybe TcType
tcView TcType
ty1 = TcType -> TcType -> TcS TcCoercion
go TcType
ty1' TcType
ty2
go TcType
ty1 TcType
ty2 | Just TcType
ty2' <- TcType -> Maybe TcType
tcView TcType
ty2 = TcType -> TcType -> TcS TcCoercion
go TcType
ty1 TcType
ty2'
go (FunTy AnonArgFlag
_ TcType
w1 TcType
s1 TcType
t1) (FunTy AnonArgFlag
_ TcType
w2 TcType
s2 TcType
t2)
= do { TcCoercion
co_s <- CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
role TcType
s1 TcType
s2
; TcCoercion
co_t <- CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
role TcType
t1 TcType
t2
; TcCoercion
co_w <- CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc Role
Nominal TcType
w1 TcType
w2
; TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcCoercion -> TcCoercion -> TcCoercion -> TcCoercion
mkFunCo Role
role TcCoercion
co_w TcCoercion
co_s TcCoercion
co_t) }
go (TyConApp TyCon
tc1 [TcType]
tys1) (TyConApp TyCon
tc2 [TcType]
tys2)
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2, [TcType]
tys1 [TcType] -> [TcType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [TcType]
tys2
, TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc1 Role
role
= do { [TcCoercion]
cos <- (Role -> TcType -> TcType -> TcS TcCoercion)
-> [Role] -> [TcType] -> [TcType] -> TcS [TcCoercion]
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m [d]
zipWith3M (CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
unifyWanted CtLoc
loc)
(Role -> TyCon -> [Role]
tyConRolesX Role
role TyCon
tc1) [TcType]
tys1 [TcType]
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 :: TcType
ty1@(TyVarTy TcTyVar
tv) TcType
ty2
= do { Maybe TcType
mb_ty <- TcTyVar -> TcS (Maybe TcType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe TcType
mb_ty of
Just TcType
ty1' -> TcType -> TcType -> TcS TcCoercion
go TcType
ty1' TcType
ty2
Maybe TcType
Nothing -> TcType -> TcType -> TcS TcCoercion
bale_out TcType
ty1 TcType
ty2}
go TcType
ty1 ty2 :: TcType
ty2@(TyVarTy TcTyVar
tv)
= do { Maybe TcType
mb_ty <- TcTyVar -> TcS (Maybe TcType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe TcType
mb_ty of
Just TcType
ty2' -> TcType -> TcType -> TcS TcCoercion
go TcType
ty1 TcType
ty2'
Maybe TcType
Nothing -> TcType -> TcType -> TcS TcCoercion
bale_out TcType
ty1 TcType
ty2 }
go ty1 :: TcType
ty1@(CoercionTy {}) (CoercionTy {})
= TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcType -> TcCoercion
mkReflCo Role
role TcType
ty1)
go TcType
ty1 TcType
ty2 = TcType -> TcType -> TcS TcCoercion
bale_out TcType
ty1 TcType
ty2
bale_out :: TcType -> TcType -> TcS TcCoercion
bale_out TcType
ty1 TcType
ty2
| TcType
ty1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
ty2 = TcCoercion -> TcS TcCoercion
forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
ty1)
| Bool
otherwise = CtLoc -> Role -> TcType -> TcType -> TcS TcCoercion
emitNewWantedEq CtLoc
loc Role
role TcType
orig_ty1 TcType
orig_ty2
unifyDeriveds :: CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
unifyDeriveds :: CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
unifyDeriveds CtLoc
loc [Role]
roles [TcType]
tys1 [TcType]
tys2 = (Role -> TcType -> TcType -> TcS ())
-> [Role] -> [TcType] -> [TcType] -> TcS ()
forall (m :: * -> *) a b c d.
Monad m =>
(a -> b -> c -> m d) -> [a] -> [b] -> [c] -> m ()
zipWith3M_ (CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived CtLoc
loc) [Role]
roles [TcType]
tys1 [TcType]
tys2
unifyDerived :: CtLoc -> Role -> Pair TcType -> TcS ()
unifyDerived :: CtLoc -> Role -> Pair TcType -> TcS ()
unifyDerived CtLoc
loc Role
role (Pair TcType
ty1 TcType
ty2) = CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived CtLoc
loc Role
role TcType
ty1 TcType
ty2
unify_derived :: CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived :: CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived CtLoc
_ Role
Phantom TcType
_ TcType
_ = () -> TcS ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
unify_derived CtLoc
loc Role
role TcType
orig_ty1 TcType
orig_ty2
= TcType -> TcType -> TcS ()
go TcType
orig_ty1 TcType
orig_ty2
where
go :: TcType -> TcType -> TcS ()
go TcType
ty1 TcType
ty2 | Just TcType
ty1' <- TcType -> Maybe TcType
tcView TcType
ty1 = TcType -> TcType -> TcS ()
go TcType
ty1' TcType
ty2
go TcType
ty1 TcType
ty2 | Just TcType
ty2' <- TcType -> Maybe TcType
tcView TcType
ty2 = TcType -> TcType -> TcS ()
go TcType
ty1 TcType
ty2'
go (FunTy AnonArgFlag
_ TcType
w1 TcType
s1 TcType
t1) (FunTy AnonArgFlag
_ TcType
w2 TcType
s2 TcType
t2)
= do { CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived CtLoc
loc Role
role TcType
s1 TcType
s2
; CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived CtLoc
loc Role
role TcType
t1 TcType
t2
; CtLoc -> Role -> TcType -> TcType -> TcS ()
unify_derived CtLoc
loc Role
Nominal TcType
w1 TcType
w2 }
go (TyConApp TyCon
tc1 [TcType]
tys1) (TyConApp TyCon
tc2 [TcType]
tys2)
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2, [TcType]
tys1 [TcType] -> [TcType] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [TcType]
tys2
, TyCon -> Role -> Bool
isInjectiveTyCon TyCon
tc1 Role
role
= CtLoc -> [Role] -> [TcType] -> [TcType] -> TcS ()
unifyDeriveds CtLoc
loc (Role -> TyCon -> [Role]
tyConRolesX Role
role TyCon
tc1) [TcType]
tys1 [TcType]
tys2
go ty1 :: TcType
ty1@(TyVarTy TcTyVar
tv) TcType
ty2
= do { Maybe TcType
mb_ty <- TcTyVar -> TcS (Maybe TcType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe TcType
mb_ty of
Just TcType
ty1' -> TcType -> TcType -> TcS ()
go TcType
ty1' TcType
ty2
Maybe TcType
Nothing -> TcType -> TcType -> TcS ()
bale_out TcType
ty1 TcType
ty2 }
go TcType
ty1 ty2 :: TcType
ty2@(TyVarTy TcTyVar
tv)
= do { Maybe TcType
mb_ty <- TcTyVar -> TcS (Maybe TcType)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe TcType
mb_ty of
Just TcType
ty2' -> TcType -> TcType -> TcS ()
go TcType
ty1 TcType
ty2'
Maybe TcType
Nothing -> TcType -> TcType -> TcS ()
bale_out TcType
ty1 TcType
ty2 }
go TcType
ty1 TcType
ty2 = TcType -> TcType -> TcS ()
bale_out TcType
ty1 TcType
ty2
bale_out :: TcType -> TcType -> TcS ()
bale_out TcType
ty1 TcType
ty2
| TcType
ty1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
ty2 = () -> TcS ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = CtLoc -> Role -> TcType -> TcType -> TcS ()
emitNewDerivedEq CtLoc
loc Role
role TcType
orig_ty1 TcType
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