{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE MultiWayIf #-}
module GHC.Tc.Solver.Canonical(
canonicalize,
unifyDerived,
makeSuperClasses,
StopOrContinue(..), stopWith, continueWith, andWhenContinue,
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
import GHC.Tc.Utils.TcType
import GHC.Core.Type
import GHC.Tc.Solver.Rewrite
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.Coercion.Axiom
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, anyVarSet )
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Builtin.Types ( anyTypeOfKind )
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, isNothing )
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" #-}
CtEvidence -> TcS (StopOrContinue Ct)
canNC 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 })
= CtEvidence -> TcS (StopOrContinue Ct)
canNC 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 (CEqCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ev
, cc_lhs :: Ct -> CanEqLHS
cc_lhs = CanEqLHS
lhs
, cc_rhs :: Ct -> TcType
cc_rhs = TcType
rhs
, 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 (CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs) TcType
rhs
canNC :: CtEvidence -> TcS (StopOrContinue Ct)
canNC :: CtEvidence -> TcS (StopOrContinue Ct)
canNC CtEvidence
ev =
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)
CtEvidence -> TcS (StopOrContinue Ct)
canIrred CtEvidence
ev
ForAllPred [TcTyVar]
tvs [TcType]
th 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]
th TcType
p
where
pred :: TcType
pred = CtEvidence -> TcType
ctEvPred CtEvidence
ev
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) <- CtEvidence -> TyCon -> [TcType] -> TcS ([TcType], [TcCoercion])
rewriteArgsNom CtEvidence
ev TyCon
cls_tc [TcType]
tys
; 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 { 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)
splitForAllTyCoVars 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
| Bool
otherwise
= CtLoc
loc { ctl_origin :: CtOrigin
ctl_origin = CtOrigin
new_orig }
where
new_orig :: CtOrigin
new_orig = case CtLoc -> CtOrigin
ctLocOrigin CtLoc
loc of
InstSCOrigin Int
sc_depth TypeSize
n -> Int -> TypeSize -> CtOrigin
InstSCOrigin (Int
sc_depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (TypeSize
n TypeSize -> TypeSize -> TypeSize
forall a. Ord a => a -> a -> a
`max` TypeSize
size)
OtherSCOrigin Int
sc_depth SkolemInfo
si -> Int -> SkolemInfo -> CtOrigin
OtherSCOrigin (Int
sc_depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) SkolemInfo
si
GivenOrigin SkolemInfo
InstSkol -> Int -> TypeSize -> CtOrigin
InstSCOrigin Int
1 TypeSize
size
GivenOrigin SkolemInfo
other_skol -> Int -> SkolemInfo -> CtOrigin
OtherSCOrigin Int
1 SkolemInfo
other_skol
CtOrigin
other_orig -> String -> SDoc -> CtOrigin
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Given constraint without given origin" (SDoc -> CtOrigin) -> SDoc -> CtOrigin
forall a b. (a -> b) -> a -> b
$
TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
evar SDoc -> SDoc -> SDoc
$$ CtOrigin -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtOrigin
other_orig
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 { 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 { 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 :: CtEvidence -> TcS (StopOrContinue Ct)
canIrred :: CtEvidence -> TcS (StopOrContinue Ct)
canIrred 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) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite 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
ForAllPred [TcTyVar]
tvs [TcType]
th 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]
th TcType
p
IrredPred {} -> 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
$
CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
IrredShapeReason 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) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite 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 { 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 { 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
rewritten 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
rewritten, 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
rewritten 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 ty1 :: TcType
ty1@(TyConApp TyCon
tc1 []) TcType
_ps_ty1 (TyConApp TyCon
tc2 []) TcType
_ps_ty2
| TyCon
tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tc2
= CtEvidence -> EqRel -> TcType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel TcType
ty1
can_eq_nc' Bool
rewritten 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
rewritten 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
rewritten 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
_rewritten 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
rewritten GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel (CastTy TcType
ty1 TcCoercion
co1) TcType
_ TcType
ty2 TcType
ps_ty2
| Maybe CanEqLHS -> Bool
forall a. Maybe a -> Bool
isNothing (TcType -> Maybe CanEqLHS
canEqLHS_maybe TcType
ty2)
= Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcCoercion
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCast Bool
rewritten CtEvidence
ev EqRel
eq_rel SwapFlag
NotSwapped TcType
ty1 TcCoercion
co1 TcType
ty2 TcType
ps_ty2
can_eq_nc' Bool
rewritten GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ps_ty1 (CastTy TcType
ty2 TcCoercion
co2) TcType
_
| Maybe CanEqLHS -> Bool
forall a. Maybe a -> Bool
isNothing (TcType -> Maybe CanEqLHS
canEqLHS_maybe TcType
ty1)
= Bool
-> CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcCoercion
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCast Bool
rewritten CtEvidence
ev EqRel
eq_rel SwapFlag
IsSwapped TcType
ty2 TcCoercion
co2 TcType
ty1 TcType
ps_ty1
can_eq_nc' Bool
_rewritten 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
_rewritten 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
_ps_ty1
(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
_ps_ty2
| 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
_rewritten GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
_ TcType
ty2 TcType
_
| Just (TyCon
tc1, [TcType]
tys1) <- HasCallStack => TcType -> Maybe (TyCon, [TcType])
TcType -> Maybe (TyCon, [TcType])
tcSplitTyConApp_maybe TcType
ty1
, Just (TyCon
tc2, [TcType]
tys2) <- HasCallStack => TcType -> Maybe (TyCon, [TcType])
TcType -> Maybe (TyCon, [TcType])
tcSplitTyConApp_maybe TcType
ty2
, 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
_rewritten GlobalRdrEnv
_rdr_env (FamInstEnv, FamInstEnv)
_envs CtEvidence
ev EqRel
eq_rel
s1 :: TcType
s1@(ForAllTy (Bndr TcTyVar
_ ArgFlag
vis1) TcType
_) TcType
_
s2 :: TcType
s2@(ForAllTy (Bndr TcTyVar
_ ArgFlag
vis2) TcType
_) TcType
_
| ArgFlag
vis1 ArgFlag -> ArgFlag -> Bool
`sameVis` ArgFlag
vis2
= 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
NomEq TcType
ty1 TcType
_ TcType
ty2 TcType
_
| Just (TcType
t1, TcType
s1) <- TcType -> Maybe (TcType, TcType)
tcSplitAppTy_maybe TcType
ty1
, 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
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) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite CtEvidence
ev TcType
ps_ty1
; (TcType
xi2, TcCoercion
co2) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite 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
ty1 TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
| Just CanEqLHS
can_eq_lhs1 <- TcType -> Maybe CanEqLHS
canEqLHS_maybe TcType
ty1
= CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHS CtEvidence
ev EqRel
eq_rel SwapFlag
NotSwapped CanEqLHS
can_eq_lhs1 TcType
ps_ty1 TcType
ty2 TcType
ps_ty2
| Just CanEqLHS
can_eq_lhs2 <- TcType -> Maybe CanEqLHS
canEqLHS_maybe TcType
ty2
= CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHS CtEvidence
ev EqRel
eq_rel SwapFlag
IsSwapped CanEqLHS
can_eq_lhs2 TcType
ps_ty2 TcType
ty1 TcType
ps_ty1
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 (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
ReprEqReason CtEvidence
ev)
EqRel
NomEq -> Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
ShapeMismatchReason 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)
tcSplitForAllTyVarBinders TcType
s1
([TyVarBinder]
bndrs2, TcType
phi2) = TcType -> ([TyVarBinder], TcType)
tcSplitForAllTyVarBinders 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])
tcRepSplitTyConApp_maybe TcType
ty1
, Just (TyCon
tc2, [TcType]
tys2) <- HasDebugCallStack => TcType -> Maybe (TyCon, [TcType])
TcType -> Maybe (TyCon, [TcType])
tcRepSplitTyConApp_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)
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)
give_up
where
give_up :: TcS (Either (Pair TcType) TcType)
give_up = 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 (Pair TcType -> Either (Pair TcType) TcType)
-> Pair TcType -> Either (Pair TcType) TcType
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
greMangledName [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
rewritten 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
rewritten 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 (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
AbstractTyConReason 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
isInvisibleTyConBinder 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) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite CtEvidence
ev TcType
ty1
; (TcType
xi2, TcCoercion
co2) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite 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 (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
ReprEqReason 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) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite CtEvidence
ev TcType
ty1
; (TcType
s2, TcCoercion
co2) <- CtEvidence -> TcType -> TcS (TcType, TcCoercion)
rewrite 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 (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
ShapeMismatchReason CtEvidence
new_ev) }
canEqCanLHS :: CtEvidence
-> EqRel -> SwapFlag
-> CanEqLHS
-> TcType
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHS :: CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHS CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 TcType
xi2 TcType
ps_xi2
| TcType
k1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
k2
= CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 TcType
xi2 TcType
ps_xi2
| Bool
otherwise
= CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSHetero CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 TcType
k1 TcType
xi2 TcType
ps_xi2 TcType
k2
where
k1 :: TcType
k1 = CanEqLHS -> TcType
canEqLHSKind CanEqLHS
lhs1
k2 :: TcType
k2 = HasDebugCallStack => TcType -> TcType
TcType -> TcType
tcTypeKind TcType
xi2
canEqCanLHSHetero :: CtEvidence
-> EqRel -> SwapFlag
-> CanEqLHS -> TcType
-> TcKind
-> TcType -> TcType
-> TcKind
-> TcS (StopOrContinue Ct)
canEqCanLHSHetero :: CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSHetero CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 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_co :: TcCoercion
lhs_co = Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
xi1
; 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
xi1 TcType
rhs' TcCoercion
lhs_co TcCoercion
rhs_co
; CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSHomo CtEvidence
type_ev EqRel
eq_rel SwapFlag
NotSwapped CanEqLHS
lhs1 TcType
ps_xi1 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
xi1 :: TcType
xi1 = CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs1
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 TcType
xi1 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
canEqCanLHSHomo :: CtEvidence
-> EqRel -> SwapFlag
-> CanEqLHS
-> TcType
-> TcType -> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSHomo :: CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcType
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSHomo CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 TcType
xi2 TcType
ps_xi2
| (TcType
xi2', MCoercion
mco) <- TcType -> (TcType, MCoercion)
split_cast_ty TcType
xi2
, Just CanEqLHS
lhs2 <- TcType -> Maybe CanEqLHS
canEqLHS_maybe TcType
xi2'
= CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> CanEqLHS
-> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqCanLHS2 CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 CanEqLHS
lhs2 (TcType
ps_xi2 TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion -> MCoercion
mkTcSymMCo MCoercion
mco) MCoercion
mco
| Bool
otherwise
= CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi2
where
split_cast_ty :: TcType -> (TcType, MCoercion)
split_cast_ty (CastTy TcType
ty TcCoercion
co) = (TcType
ty, TcCoercion -> MCoercion
MCo TcCoercion
co)
split_cast_ty TcType
other = (TcType
other, MCoercion
MRefl)
canEqCanLHS2 :: CtEvidence
-> EqRel -> SwapFlag
-> CanEqLHS
-> TcType
-> CanEqLHS
-> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqCanLHS2 :: CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> CanEqLHS
-> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqCanLHS2 CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 TcType
ps_xi1 CanEqLHS
lhs2 TcType
ps_xi2 MCoercion
mco
| CanEqLHS
lhs1 CanEqLHS -> CanEqLHS -> Bool
`eqCanEqLHS` CanEqLHS
lhs2
= CtEvidence -> EqRel -> TcType -> TcS (StopOrContinue Ct)
canEqReflexive CtEvidence
ev EqRel
eq_rel (CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs1)
| TyVarLHS TcTyVar
tv1 <- CanEqLHS
lhs1
, TyVarLHS TcTyVar
tv2 <- CanEqLHS
lhs2
, Bool -> TcTyVar -> TcTyVar -> Bool
swapOverTyVars (CtEvidence -> Bool
isGiven CtEvidence
ev) TcTyVar
tv1 TcTyVar
tv2
= do { String -> SDoc -> TcS ()
traceTcS String
"canEqLHS2 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)
; CtEvidence
new_ev <- TcS CtEvidence
do_swap
; CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
new_ev EqRel
eq_rel SwapFlag
IsSwapped (TcTyVar -> CanEqLHS
TyVarLHS TcTyVar
tv2)
(TcType
ps_xi1 TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion
sym_mco) }
| TyVarLHS TcTyVar
tv1 <- CanEqLHS
lhs1
, TyFamLHS TyCon
fun_tc2 [TcType]
fun_args2 <- CanEqLHS
lhs2
= CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TyCon
-> [TcType]
-> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqTyVarFunEq CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi1 TyCon
fun_tc2 [TcType]
fun_args2 TcType
ps_xi2 MCoercion
mco
| TyFamLHS TyCon
fun_tc1 [TcType]
fun_args1 <- CanEqLHS
lhs1
, TyVarLHS TcTyVar
tv2 <- CanEqLHS
lhs2
= do { CtEvidence
new_ev <- TcS CtEvidence
do_swap
; CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TyCon
-> [TcType]
-> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqTyVarFunEq CtEvidence
new_ev EqRel
eq_rel SwapFlag
IsSwapped TcTyVar
tv2 TcType
ps_xi2
TyCon
fun_tc1 [TcType]
fun_args1 TcType
ps_xi1 MCoercion
sym_mco }
| TyFamLHS TyCon
fun_tc1 [TcType]
fun_args1 <- CanEqLHS
lhs1
, TyFamLHS TyCon
fun_tc2 [TcType]
fun_args2 <- CanEqLHS
lhs2
= do { String -> SDoc -> TcS ()
traceTcS String
"canEqCanLHS2 two type families" (CanEqLHS -> SDoc
forall a. Outputable a => a -> SDoc
ppr CanEqLHS
lhs1 SDoc -> SDoc -> SDoc
$$ CanEqLHS -> SDoc
forall a. Outputable a => a -> SDoc
ppr CanEqLHS
lhs2)
; let inj_eqns :: [TypeEqn]
inj_eqns :: [Pair TcType]
inj_eqns
| EqRel
ReprEq <- EqRel
eq_rel = []
| TyCon
fun_tc1 TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
/= TyCon
fun_tc2 = []
| Injective [Bool]
inj <- TyCon -> Injectivity
tyConInjectivityInfo TyCon
fun_tc1
= [ TcType -> TcType -> Pair TcType
forall a. a -> a -> Pair a
Pair TcType
arg1 TcType
arg2
| (TcType
arg1, TcType
arg2, Bool
True) <- [TcType] -> [TcType] -> [Bool] -> [(TcType, TcType, Bool)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [TcType]
fun_args1 [TcType]
fun_args2 [Bool]
inj ]
| Just BuiltInSynFamily
ops <- TyCon -> Maybe BuiltInSynFamily
isBuiltInSynFamTyCon_maybe TyCon
fun_tc1
= let ki1 :: TcType
ki1 = CanEqLHS -> TcType
canEqLHSKind CanEqLHS
lhs1
ki2 :: TcType
ki2 | MCoercion
MRefl <- MCoercion
mco
= TcType
ki1
| Bool
otherwise
= CanEqLHS -> TcType
canEqLHSKind CanEqLHS
lhs2
fake_rhs1 :: TcType
fake_rhs1 = TcType -> TcType
anyTypeOfKind TcType
ki1
fake_rhs2 :: TcType
fake_rhs2 = TcType -> TcType
anyTypeOfKind TcType
ki2
in
BuiltInSynFamily
-> [TcType] -> TcType -> [TcType] -> TcType -> [Pair TcType]
sfInteractInert BuiltInSynFamily
ops [TcType]
fun_args1 TcType
fake_rhs1 [TcType]
fun_args2 TcType
fake_rhs2
| Bool
otherwise
= []
; Bool -> TcS () -> TcS ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CtEvidence -> Bool
isGiven CtEvidence
ev) (TcS () -> TcS ()) -> TcS () -> TcS ()
forall a b. (a -> b) -> a -> b
$
(Pair TcType -> TcS ()) -> [Pair TcType] -> TcS ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (CtLoc -> Role -> Pair TcType -> TcS ()
unifyDerived (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) Role
Nominal) [Pair TcType]
inj_eqns
; TcLevel
tclvl <- TcS TcLevel
getTcLevel
; DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let tvs1 :: VarSet
tvs1 = [TcType] -> VarSet
tyCoVarsOfTypes [TcType]
fun_args1
tvs2 :: VarSet
tvs2 = [TcType] -> VarSet
tyCoVarsOfTypes [TcType]
fun_args2
swap_for_rewriting :: Bool
swap_for_rewriting = (TcTyVar -> Bool) -> VarSet -> Bool
anyVarSet (TcLevel -> TcTyVar -> Bool
isTouchableMetaTyVar TcLevel
tclvl) VarSet
tvs2 Bool -> Bool -> Bool
&&
Bool -> Bool
not ((TcTyVar -> Bool) -> VarSet -> Bool
anyVarSet (TcLevel -> TcTyVar -> Bool
isTouchableMetaTyVar TcLevel
tclvl) VarSet
tvs1)
swap_for_occurs :: Bool
swap_for_occurs
| CheckTyEqResult -> Bool
cterHasNoProblem (CheckTyEqResult -> Bool) -> CheckTyEqResult -> Bool
forall a b. (a -> b) -> a -> b
$ DynFlags -> TyCon -> [TcType] -> TcType -> CheckTyEqResult
checkTyFamEq DynFlags
dflags TyCon
fun_tc2 [TcType]
fun_args2
(TyCon -> [TcType] -> TcType
mkTyConApp TyCon
fun_tc1 [TcType]
fun_args1)
, CheckTyEqResult -> Bool
cterHasOccursCheck (CheckTyEqResult -> Bool) -> CheckTyEqResult -> Bool
forall a b. (a -> b) -> a -> b
$ DynFlags -> TyCon -> [TcType] -> TcType -> CheckTyEqResult
checkTyFamEq DynFlags
dflags TyCon
fun_tc1 [TcType]
fun_args1
(TyCon -> [TcType] -> TcType
mkTyConApp TyCon
fun_tc2 [TcType]
fun_args2)
= Bool
True
| Bool
otherwise
= Bool
False
; if Bool
swap_for_rewriting Bool -> Bool -> Bool
|| Bool
swap_for_occurs
then do { CtEvidence
new_ev <- TcS CtEvidence
do_swap
; CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
new_ev EqRel
eq_rel SwapFlag
IsSwapped CanEqLHS
lhs2 (TcType
ps_xi1 TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion
sym_mco) }
else TcS (StopOrContinue Ct)
finish_without_swapping }
| Bool
otherwise
= TcS (StopOrContinue Ct)
finish_without_swapping
where
sym_mco :: MCoercion
sym_mco = MCoercion -> MCoercion
mkTcSymMCo MCoercion
mco
do_swap :: TcS CtEvidence
do_swap = CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcType
-> MCoercion
-> TcS CtEvidence
rewriteCastedEquality CtEvidence
ev EqRel
eq_rel SwapFlag
swapped (CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs1) (CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs2) MCoercion
mco
finish_without_swapping :: TcS (StopOrContinue Ct)
finish_without_swapping = CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs1 (TcType
ps_xi2 TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion
mco)
canEqTyVarFunEq :: CtEvidence
-> EqRel -> SwapFlag
-> TyVar -> TcType
-> TyCon -> [Xi] -> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqTyVarFunEq :: CtEvidence
-> EqRel
-> SwapFlag
-> TcTyVar
-> TcType
-> TyCon
-> [TcType]
-> TcType
-> MCoercion
-> TcS (StopOrContinue Ct)
canEqTyVarFunEq CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcTyVar
tv1 TcType
ps_xi1 TyCon
fun_tc2 [TcType]
fun_args2 TcType
ps_xi2 MCoercion
mco
= do { TouchabilityTestResult
is_touchable <- CtFlavour -> TcTyVar -> TcType -> TcS TouchabilityTestResult
touchabilityTest (CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev) TcTyVar
tv1 TcType
rhs
; DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; if | case TouchabilityTestResult
is_touchable of { TouchabilityTestResult
Untouchable -> Bool
False; TouchabilityTestResult
_ -> Bool
True }
, CheckTyEqResult -> Bool
cterHasNoProblem (CheckTyEqResult -> Bool) -> CheckTyEqResult -> Bool
forall a b. (a -> b) -> a -> b
$
DynFlags -> TcTyVar -> TcType -> CheckTyEqResult
checkTyVarEq DynFlags
dflags TcTyVar
tv1 TcType
rhs CheckTyEqResult -> CheckTyEqProblem -> CheckTyEqResult
`cterRemoveProblem` CheckTyEqProblem
cteTypeFamily
-> CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
ev EqRel
eq_rel SwapFlag
swapped (TcTyVar -> CanEqLHS
TyVarLHS TcTyVar
tv1) TcType
rhs
| Bool
otherwise
-> do { CtEvidence
new_ev <- CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcType
-> MCoercion
-> TcS CtEvidence
rewriteCastedEquality CtEvidence
ev EqRel
eq_rel SwapFlag
swapped
(TcTyVar -> TcType
mkTyVarTy TcTyVar
tv1) (TyCon -> [TcType] -> TcType
mkTyConApp TyCon
fun_tc2 [TcType]
fun_args2)
MCoercion
mco
; CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
new_ev EqRel
eq_rel SwapFlag
IsSwapped
(TyCon -> [TcType] -> CanEqLHS
TyFamLHS TyCon
fun_tc2 [TcType]
fun_args2)
(TcType
ps_xi1 TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion
sym_mco) } }
where
sym_mco :: MCoercion
sym_mco = MCoercion -> MCoercion
mkTcSymMCo MCoercion
mco
rhs :: TcType
rhs = TcType
ps_xi2 TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion
mco
canEqCanLHSFinish :: CtEvidence
-> EqRel -> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish :: CtEvidence
-> EqRel
-> SwapFlag
-> CanEqLHS
-> TcType
-> TcS (StopOrContinue Ct)
canEqCanLHSFinish CtEvidence
ev EqRel
eq_rel SwapFlag
swapped CanEqLHS
lhs TcType
rhs
= do { DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; CtEvidence
new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
ev SwapFlag
swapped TcType
lhs_ty TcType
rhs TcCoercion
rewrite_co1 TcCoercion
rewrite_co2
; MASSERT(canEqLHSKind lhs `eqType` tcTypeKind rhs)
; MASSERT(not bad_newtype)
; let result0 :: CheckTyEqResult
result0 = DynFlags -> CanEqLHS -> TcType -> CheckTyEqResult
checkTypeEq DynFlags
dflags CanEqLHS
lhs TcType
rhs CheckTyEqResult -> CheckTyEqProblem -> CheckTyEqResult
`cterRemoveProblem` CheckTyEqProblem
cteTypeFamily
result :: CheckTyEqResult
result = case EqRel
eq_rel of
EqRel
NomEq -> CheckTyEqResult
result0
EqRel
ReprEq -> CheckTyEqResult -> CheckTyEqResult
cterSetOccursCheckSoluble CheckTyEqResult
result0
reason :: CtIrredReason
reason | CheckTyEqResult
result CheckTyEqResult -> CheckTyEqProblem -> Bool
`cterHasOnlyProblem` CheckTyEqProblem
cteHoleBlocker
= HoleSet -> CtIrredReason
HoleBlockerReason (TcType -> HoleSet
coercionHolesOfType TcType
rhs)
| Bool
otherwise
= CheckTyEqResult -> CtIrredReason
NonCanonicalReason CheckTyEqResult
result
; if CheckTyEqResult -> Bool
cterHasNoProblem CheckTyEqResult
result
then do { String -> SDoc -> TcS ()
traceTcS String
"CEqCan" (CanEqLHS -> SDoc
forall a. Outputable a => a -> SDoc
ppr CanEqLHS
lhs SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs)
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CEqCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_ev, cc_lhs :: CanEqLHS
cc_lhs = CanEqLHS
lhs
, cc_rhs :: TcType
cc_rhs = TcType
rhs, cc_eq_rel :: EqRel
cc_eq_rel = EqRel
eq_rel }) }
else do { Maybe (TcCoercion, TcType)
m_stuff <- CtEvidence
-> CheckTyEqResult
-> CanEqLHS
-> TcType
-> TcS (Maybe (TcCoercion, TcType))
breakTyEqCycle_maybe CtEvidence
ev CheckTyEqResult
result CanEqLHS
lhs TcType
rhs
; case Maybe (TcCoercion, TcType)
m_stuff of
{ Maybe (TcCoercion, TcType)
Nothing ->
do { String -> SDoc -> TcS ()
traceTcS String
"canEqCanLHSFinish can't make a canonical"
(CanEqLHS -> SDoc
forall a. Outputable a => a -> SDoc
ppr CanEqLHS
lhs SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs)
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
reason CtEvidence
new_ev) }
; Just (TcCoercion
co, TcType
new_rhs) ->
do { String -> SDoc -> TcS ()
traceTcS String
"canEqCanLHSFinish breaking a cycle" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
CanEqLHS -> SDoc
forall a. Outputable a => a -> SDoc
ppr CanEqLHS
lhs SDoc -> SDoc -> SDoc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs
; String -> SDoc -> TcS ()
traceTcS String
"new RHS:" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
new_rhs)
; if CheckTyEqResult -> Bool
cterHasOccursCheck (DynFlags -> CanEqLHS -> TcType -> CheckTyEqResult
checkTypeEq DynFlags
dflags CanEqLHS
lhs TcType
new_rhs)
then do { String -> SDoc -> TcS ()
traceTcS String
"Note [Type equality cycles] Detail (1)"
(TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
new_rhs)
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtIrredReason -> CtEvidence -> Ct
mkIrredCt CtIrredReason
reason CtEvidence
new_ev) }
else do {
CtEvidence
new_new_ev <- CtEvidence
-> SwapFlag
-> TcType
-> TcType
-> TcCoercion
-> TcCoercion
-> TcS CtEvidence
rewriteEqEvidence CtEvidence
new_ev SwapFlag
NotSwapped
TcType
lhs_ty TcType
new_rhs
(TcType -> TcCoercion
mkTcNomReflCo TcType
lhs_ty) TcCoercion
co
; Ct -> TcS (StopOrContinue Ct)
forall a. a -> TcS (StopOrContinue a)
continueWith (CEqCan { cc_ev :: CtEvidence
cc_ev = CtEvidence
new_new_ev
, cc_lhs :: CanEqLHS
cc_lhs = CanEqLHS
lhs
, cc_rhs :: TcType
cc_rhs = TcType
new_rhs
, cc_eq_rel :: EqRel
cc_eq_rel = EqRel
eq_rel }) }}}}}
where
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
lhs_ty :: TcType
lhs_ty = CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs
rewrite_co1 :: TcCoercion
rewrite_co1 = Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
lhs_ty
rewrite_co2 :: TcCoercion
rewrite_co2 = Role -> TcType -> TcCoercion
mkTcReflCo Role
role TcType
rhs
bad_newtype :: Bool
bad_newtype | EqRel
ReprEq <- EqRel
eq_rel
, Just TyCon
tc <- TcType -> Maybe TyCon
tyConAppTyCon_maybe TcType
rhs
= TyCon -> Bool
isNewTyCon TyCon
tc
| Bool
otherwise
= Bool
False
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" }
rewriteCastedEquality :: CtEvidence
-> EqRel -> SwapFlag
-> TcType
-> TcType
-> MCoercion
-> TcS CtEvidence
rewriteCastedEquality :: CtEvidence
-> EqRel
-> SwapFlag
-> TcType
-> TcType
-> MCoercion
-> TcS CtEvidence
rewriteCastedEquality CtEvidence
ev EqRel
eq_rel SwapFlag
swapped TcType
lhs TcType
rhs MCoercion
mco
= 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
where
new_lhs :: TcType
new_lhs = TcType
lhs TcType -> MCoercion -> TcType
`mkCastTyMCo` MCoercion
sym_mco
lhs_co :: TcCoercion
lhs_co = Role -> TcType -> MCoercion -> TcCoercion
mkTcGReflLeftMCo Role
role TcType
lhs MCoercion
sym_mco
new_rhs :: TcType
new_rhs = TcType
rhs
rhs_co :: TcCoercion
rhs_co = Role -> TcType -> MCoercion -> TcCoercion
mkTcGReflRightMCo Role
role TcType
rhs MCoercion
mco
sym_mco :: MCoercion
sym_mco = MCoercion -> MCoercion
mkTcSymMCo MCoercion
mco
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
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
maybeTcSymCo 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
= do { (CtEvidence
new_ev, TcCoercion
hole_co) <- ShadowInfo
-> CtLoc
-> Role
-> TcType
-> TcType
-> TcS (CtEvidence, TcCoercion)
newWantedEq_SI ShadowInfo
si CtLoc
loc'
(CtEvidence -> Role
ctEvRole CtEvidence
old_ev) TcType
nlhs TcType
nrhs
; let co :: TcCoercion
co = SwapFlag -> TcCoercion -> TcCoercion
maybeTcSymCo 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 }
#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