{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE RecursiveDo #-}
module GHC.Tc.Solver.Solve (
simplifyWantedsTcM,
solveWanteds,
solveSimpleGivens,
solveSimpleWanteds,
trySolveImplication,
setImplicationStatus
) where
import GHC.Prelude
import GHC.Tc.Solver.Dict
import GHC.Tc.Solver.Equality( solveEquality )
import GHC.Tc.Solver.Irred( solveIrred )
import GHC.Tc.Solver.Rewrite( rewrite, rewriteType )
import GHC.Tc.Errors.Types
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.Evidence
import GHC.Tc.Types.CtLoc( ctLocEnv, ctLocOrigin, setCtLocOrigin )
import GHC.Tc.Types
import GHC.Tc.Types.Origin
import GHC.Tc.Types.Constraint
import GHC.Tc.Types.CtLoc( mkGivenLoc )
import GHC.Tc.Solver.InertSet
import GHC.Tc.Solver.Monad
import GHC.Tc.Utils.Monad as TcM
import GHC.Tc.Zonk.TcType as TcM
import GHC.Tc.Solver.Monad as TcS
import GHC.Core.Predicate
import GHC.Core.Reduction
import GHC.Core.Coercion
import GHC.Core.TyCo.FVs( coVarsOfCos )
import GHC.Core.Class( classHasSCs )
import GHC.Types.Id( idType )
import GHC.Types.Var( EvVar, tyVarKind )
import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.Basic ( IntWithInf, intGtLimit )
import GHC.Types.Unique.Set( nonDetStrictFoldUniqSet )
import GHC.Data.Bag
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Utils.Misc
import GHC.Driver.Session
import Control.Monad
import Data.List( deleteFirstsBy )
import Data.Maybe ( mapMaybe )
import qualified Data.Semigroup as S
import Data.Void( Void )
simplifyWantedsTcM :: [CtEvidence] -> TcM WantedConstraints
simplifyWantedsTcM :: [CtEvidence] -> TcM WantedConstraints
simplifyWantedsTcM [CtEvidence]
wanted
= do { String -> SDoc -> TcRn ()
traceTc String
"simplifyWantedsTcM {" ([CtEvidence] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CtEvidence]
wanted)
; (result, _) <- TcS WantedConstraints -> TcM (WantedConstraints, EvBindMap)
forall a. TcS a -> TcM (a, EvBindMap)
runTcS (WantedConstraints -> TcS WantedConstraints
solveWanteds ([CtEvidence] -> WantedConstraints
mkSimpleWC [CtEvidence]
wanted))
; result <- TcM.liftZonkM $ TcM.zonkWC result
; traceTc "simplifyWantedsTcM }" (ppr result)
; return result }
solveWanteds :: WantedConstraints -> TcS WantedConstraints
solveWanteds :: WantedConstraints -> TcS WantedConstraints
solveWanteds wc :: WantedConstraints
wc@(WC { wc_errors :: WantedConstraints -> Bag DelayedError
wc_errors = Bag DelayedError
errs })
= do { cur_lvl <- TcS TcLevel
TcS.getTcLevel
; traceTcS "solveWanteds {" $
vcat [ text "Level =" <+> ppr cur_lvl
, ppr wc ]
; dflags <- getDynFlags
; solved_wc <- simplify_loop 0 (solverIterations dflags) True wc
; errs' <- simplifyDelayedErrors errs
; let final_wc = WantedConstraints
solved_wc { wc_errors = errs' }
; ev_binds_var <- getTcEvBindsVar
; bb <- TcS.getTcEvBindsMap ev_binds_var
; traceTcS "solveWanteds }" $
vcat [ text "final wc =" <+> ppr final_wc
, text "ev_binds_var =" <+> ppr ev_binds_var
, text "current evbinds =" <+> ppr (evBindMapBinds bb) ]
; return final_wc }
simplify_loop :: Int -> IntWithInf -> Bool
-> WantedConstraints -> TcS WantedConstraints
simplify_loop :: Int
-> IntWithInf -> Bool -> WantedConstraints -> TcS WantedConstraints
simplify_loop Int
n IntWithInf
limit Bool
definitely_redo_implications
wc :: WantedConstraints
wc@(WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics })
| WantedConstraints -> Bool
isSolvedWC WantedConstraints
wc
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
| Bool
otherwise
= do { SDoc -> TcS ()
csTraceTcS (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"simplify_loop iteration=" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
n
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"definitely_redo =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
definitely_redo_implications SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
, Int -> SDoc
forall doc. IsLine doc => Int -> doc
int (Cts -> Int
forall a. Bag a -> Int
lengthBag Cts
simples) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"simples to solve" ])
; String -> SDoc -> TcS ()
traceTcS String
"simplify_loop: wc =" (WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wc)
; (unifs1, simples1) <- TcS Cts -> TcS (Int, Cts)
forall a. TcS a -> TcS (Int, a)
reportUnifications (TcS Cts -> TcS (Int, Cts)) -> TcS Cts -> TcS (Int, Cts)
forall a b. (a -> b) -> a -> b
$
Cts -> TcS Cts
solveSimpleWanteds Cts
simples
; wc2 <- if not definitely_redo_implications
&& unifs1 == 0
then return (wc { wc_simple = simples1 })
else do { implics1 <- solveNestedImplications implics
; return (wc { wc_simple = simples1
, wc_impl = implics1 }) }
; unif_happened <- resetUnificationFlag
; csTraceTcS $ text "unif_happened" <+> ppr unif_happened
; maybe_simplify_again (n+1) limit unif_happened wc2 }
maybe_simplify_again :: Int -> IntWithInf -> Bool
-> WantedConstraints -> TcS WantedConstraints
maybe_simplify_again :: Int
-> IntWithInf -> Bool -> WantedConstraints -> TcS WantedConstraints
maybe_simplify_again Int
n IntWithInf
limit Bool
unif_happened wc :: WantedConstraints
wc@(WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples })
| Int
n Int -> IntWithInf -> Bool
`intGtLimit` IntWithInf
limit
= do {
TcRnMessage -> TcS ()
addErrTcS (TcRnMessage -> TcS ()) -> TcRnMessage -> TcS ()
forall a b. (a -> b) -> a -> b
$ Cts -> IntWithInf -> WantedConstraints -> TcRnMessage
TcRnSimplifierTooManyIterations Cts
simples IntWithInf
limit WantedConstraints
wc
; WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc }
| Bool
unif_happened
= Int
-> IntWithInf -> Bool -> WantedConstraints -> TcS WantedConstraints
simplify_loop Int
n IntWithInf
limit Bool
True WantedConstraints
wc
| WantedConstraints -> Bool
superClassesMightHelp WantedConstraints
wc
=
do { pending_given <- TcS [Ct]
getPendingGivenScs
; let (pending_wanted, simples1) = getPendingWantedScs simples
; if null pending_given && null pending_wanted
then return wc
else
do { new_given <- makeSuperClasses pending_given
; new_wanted <- makeSuperClasses pending_wanted
; solveSimpleGivens new_given
; traceTcS "maybe_simplify_again" (vcat [ text "pending_given" <+> ppr pending_given
, text "new_given" <+> ppr new_given
, text "pending_wanted" <+> ppr pending_wanted
, text "new_wanted" <+> ppr new_wanted ])
; simplify_loop n limit (not (null pending_given)) $
wc { wc_simple = simples1 `unionBags` listToBag new_wanted } } }
| Bool
otherwise
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
solveNestedImplications :: Bag Implication
-> TcS (Bag Implication)
solveNestedImplications :: Bag Implication -> TcS (Bag Implication)
solveNestedImplications Bag Implication
implics
| Bag Implication -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag Implication
implics
= Bag Implication -> TcS (Bag Implication)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bag Implication
forall a. Bag a
emptyBag)
| Bool
otherwise
= do { String -> SDoc -> TcS ()
traceTcS String
"solveNestedImplications starting {" SDoc
forall doc. IsOutput doc => doc
empty
; unsolved_implics <- (Implication -> TcS Implication)
-> Bag Implication -> TcS (Bag Implication)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Bag a -> m (Bag b)
mapBagM Implication -> TcS Implication
solveImplication Bag Implication
implics
; traceTcS "solveNestedImplications end }" $
vcat [ text "unsolved_implics =" <+> ppr unsolved_implics ]
; return unsolved_implics }
trySolveImplication :: Implication -> TcS Bool
trySolveImplication :: Implication -> TcS Bool
trySolveImplication (Implic { ic_tclvl :: Implication -> TcLevel
ic_tclvl = TcLevel
tclvl
, ic_binds :: Implication -> EvBindsVar
ic_binds = EvBindsVar
ev_binds_var
, ic_given :: Implication -> [TcTyVar]
ic_given = [TcTyVar]
given_ids
, ic_wanted :: Implication -> WantedConstraints
ic_wanted = WantedConstraints
wanteds
, ic_env :: Implication -> CtLocEnv
ic_env = CtLocEnv
ct_loc_env
, ic_info :: Implication -> SkolemInfoAnon
ic_info = SkolemInfoAnon
info })
= EvBindsVar -> TcLevel -> TcS Bool -> TcS Bool
forall a. EvBindsVar -> TcLevel -> TcS a -> TcS a
nestImplicTcS EvBindsVar
ev_binds_var TcLevel
tclvl (TcS Bool -> TcS Bool) -> TcS Bool -> TcS Bool
forall a b. (a -> b) -> a -> b
$
do { let loc :: CtLoc
loc = TcLevel -> SkolemInfoAnon -> CtLocEnv -> CtLoc
mkGivenLoc TcLevel
tclvl SkolemInfoAnon
info CtLocEnv
ct_loc_env
givens :: [Ct]
givens = CtLoc -> [TcTyVar] -> [Ct]
mkGivens CtLoc
loc [TcTyVar]
given_ids
; [Ct] -> TcS ()
solveSimpleGivens [Ct]
givens
; residual_wanted <- WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
wanteds
; return (isSolvedWC residual_wanted) }
solveImplication :: Implication
-> TcS Implication
solveImplication :: Implication -> TcS Implication
solveImplication imp :: Implication
imp@(Implic { ic_tclvl :: Implication -> TcLevel
ic_tclvl = TcLevel
tclvl
, ic_binds :: Implication -> EvBindsVar
ic_binds = EvBindsVar
ev_binds_var
, ic_given :: Implication -> [TcTyVar]
ic_given = [TcTyVar]
given_ids
, ic_wanted :: Implication -> WantedConstraints
ic_wanted = WantedConstraints
wanteds
, ic_info :: Implication -> SkolemInfoAnon
ic_info = SkolemInfoAnon
info
, ic_env :: Implication -> CtLocEnv
ic_env = CtLocEnv
ct_loc_env
, ic_status :: Implication -> ImplicStatus
ic_status = ImplicStatus
status })
| ImplicStatus -> Bool
isSolvedStatus ImplicStatus
status
= Implication -> TcS Implication
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Implication
imp
| Bool
otherwise
= do { inerts <- TcS InertSet
getInertSet
; traceTcS "solveImplication {" (ppr imp $$ text "Inerts" <+> ppr inerts)
; (has_given_eqs, given_insols, residual_wanted)
<- nestImplicTcS ev_binds_var tclvl $
do { let loc = TcLevel -> SkolemInfoAnon -> CtLocEnv -> CtLoc
mkGivenLoc TcLevel
tclvl SkolemInfoAnon
info CtLocEnv
ct_loc_env
givens = CtLoc -> [TcTyVar] -> [Ct]
mkGivens CtLoc
loc [TcTyVar]
given_ids
; solveSimpleGivens givens
; residual_wanted <- solveWanteds wanteds
; (has_eqs, given_insols) <- getHasGivenEqs tclvl
; return (has_eqs, given_insols, residual_wanted) }
; traceTcS "solveImplication 2"
(ppr given_insols $$ ppr residual_wanted)
; let final_wanted = WantedConstraints
residual_wanted WantedConstraints -> InertIrreds -> WantedConstraints
`addInsols` InertIrreds
given_insols
; res_implic <- setImplicationStatus (imp { ic_given_eqs = has_given_eqs
, ic_wanted = final_wanted })
; evbinds <- TcS.getTcEvBindsMap ev_binds_var
; tcvs <- TcS.getTcEvTyCoVars ev_binds_var
; traceTcS "solveImplication end }" $ vcat
[ text "has_given_eqs =" <+> ppr has_given_eqs
, text "res_implic =" <+> ppr res_implic
, text "implication evbinds =" <+> ppr (evBindMapBinds evbinds)
, text "implication tvcs =" <+> ppr tcvs ]
; return res_implic }
setImplicationStatus :: Implication -> TcS Implication
setImplicationStatus :: Implication -> TcS Implication
setImplicationStatus implic :: Implication
implic@(Implic { ic_status :: Implication -> ImplicStatus
ic_status = ImplicStatus
old_status
, ic_info :: Implication -> SkolemInfoAnon
ic_info = SkolemInfoAnon
info
, ic_wanted :: Implication -> WantedConstraints
ic_wanted = WantedConstraints
wc })
= Bool -> SDoc -> TcS Implication -> TcS Implication
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (Bool -> Bool
not (ImplicStatus -> Bool
isSolvedStatus ImplicStatus
old_status)) (SkolemInfoAnon -> SDoc
forall a. Outputable a => a -> SDoc
ppr SkolemInfoAnon
info) (TcS Implication -> TcS Implication)
-> TcS Implication -> TcS Implication
forall a b. (a -> b) -> a -> b
$
do { String -> SDoc -> TcS ()
traceTcS String
"setImplicationStatus {" (Implication -> SDoc
forall a. Outputable a => a -> SDoc
ppr Implication
implic)
; let solved :: Bool
solved = WantedConstraints -> Bool
isSolvedWC WantedConstraints
wc
; new_implic <- Implication -> TcS Implication
neededEvVars Implication
implic
; bad_telescope <- if solved then checkBadTelescope implic
else return False
; let new_status | WantedConstraints -> Bool
insolubleWC WantedConstraints
wc = ImplicStatus
IC_Insoluble
| Bool -> Bool
not Bool
solved = ImplicStatus
IC_Unsolved
| Bool
bad_telescope = ImplicStatus
IC_BadTelescope
| Bool
otherwise = IC_Solved { ics_dead :: [TcTyVar]
ics_dead = [TcTyVar]
dead_givens }
dead_givens = Implication -> [TcTyVar]
findRedundantGivens Implication
new_implic
new_wc = WantedConstraints -> WantedConstraints
pruneImplications WantedConstraints
wc
final_implic = Implication
new_implic { ic_status = new_status
, ic_wanted = new_wc }
; traceTcS "setImplicationStatus }" (ppr final_implic)
; return final_implic }
pruneImplications :: WantedConstraints -> WantedConstraints
pruneImplications :: WantedConstraints -> WantedConstraints
pruneImplications wc :: WantedConstraints
wc@(WC { wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics })
= WantedConstraints
wc { wc_impl = filterBag keep_me implics }
where
keep_me :: Implication -> Bool
keep_me :: Implication -> Bool
keep_me (Implic { ic_status :: Implication -> ImplicStatus
ic_status = ImplicStatus
status, ic_wanted :: Implication -> WantedConstraints
ic_wanted = WantedConstraints
wanted })
| IC_Solved { ics_dead :: ImplicStatus -> [TcTyVar]
ics_dead = [TcTyVar]
dead_givens } <- ImplicStatus
status
, [TcTyVar] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcTyVar]
dead_givens
, Bag Implication -> Bool
forall a. Bag a -> Bool
isEmptyBag (WantedConstraints -> Bag Implication
wc_impl WantedConstraints
wanted)
= Bool
False
| Bool
otherwise
= Bool
True
findRedundantGivens :: Implication -> [EvVar]
findRedundantGivens :: Implication -> [TcTyVar]
findRedundantGivens (Implic { ic_info :: Implication -> SkolemInfoAnon
ic_info = SkolemInfoAnon
info, ic_need :: Implication -> EvNeedSet
ic_need = EvNeedSet
need, ic_given :: Implication -> [TcTyVar]
ic_given = [TcTyVar]
givens })
| Bool -> Bool
not (SkolemInfoAnon -> Bool
warnRedundantGivens SkolemInfoAnon
info)
= []
| Bool -> Bool
not ([TcTyVar] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcTyVar]
unused_givens)
= [TcTyVar]
unused_givens
| Bool
otherwise
= [TcTyVar]
redundant_givens
where
in_instance_decl :: Bool
in_instance_decl = case SkolemInfoAnon
info of { InstSkol {} -> Bool
True; SkolemInfoAnon
_ -> Bool
False }
unused_givens :: [TcTyVar]
unused_givens = (TcTyVar -> Bool) -> [TcTyVar] -> [TcTyVar]
forall a. (a -> Bool) -> [a] -> [a]
filterOut TcTyVar -> Bool
is_used [TcTyVar]
givens
needed_givens_ignoring_default_methods :: CoVarSet
needed_givens_ignoring_default_methods = EvNeedSet -> CoVarSet
ens_fvs EvNeedSet
need
is_used :: TcTyVar -> Bool
is_used TcTyVar
given = TcTyVar -> Bool
is_type_error TcTyVar
given
Bool -> Bool -> Bool
|| TcTyVar
given TcTyVar -> CoVarSet -> Bool
`elemVarSet` CoVarSet
needed_givens_ignoring_default_methods
Bool -> Bool -> Bool
|| (Bool
in_instance_decl Bool -> Bool -> Bool
&& TcType -> Bool
is_improving (TcTyVar -> TcType
idType TcTyVar
given))
minimal_givens :: [TcTyVar]
minimal_givens = (TcTyVar -> TcType) -> [TcTyVar] -> [TcTyVar]
forall a. (a -> TcType) -> [a] -> [a]
mkMinimalBySCs TcTyVar -> TcType
evVarPred [TcTyVar]
givens
is_minimal :: TcTyVar -> Bool
is_minimal = (TcTyVar -> CoVarSet -> Bool
`elemVarSet` [TcTyVar] -> CoVarSet
mkVarSet [TcTyVar]
minimal_givens)
redundant_givens :: [TcTyVar]
redundant_givens
| Bool
in_instance_decl = []
| Bool
otherwise = (TcTyVar -> Bool) -> [TcTyVar] -> [TcTyVar]
forall a. (a -> Bool) -> [a] -> [a]
filterOut TcTyVar -> Bool
is_minimal [TcTyVar]
givens
is_type_error :: TcTyVar -> Bool
is_type_error TcTyVar
id = TcType -> Bool
isTopLevelUserTypeError (TcTyVar -> TcType
idType TcTyVar
id)
is_improving :: TcType -> Bool
is_improving TcType
pred
= (TcType -> Bool) -> [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TcType -> Bool
isImprovementPred (TcType
pred TcType -> [TcType] -> [TcType]
forall a. a -> [a] -> [a]
: TcType -> [TcType]
transSuperClasses TcType
pred)
warnRedundantGivens :: SkolemInfoAnon -> Bool
warnRedundantGivens :: SkolemInfoAnon -> Bool
warnRedundantGivens (SigSkol UserTypeCtxt
ctxt TcType
_ [(Name, TcTyVar)]
_)
= case UserTypeCtxt
ctxt of
FunSigCtxt Name
_ ReportRedundantConstraints
rrc -> ReportRedundantConstraints -> Bool
reportRedundantConstraints ReportRedundantConstraints
rrc
ExprSigCtxt ReportRedundantConstraints
rrc -> ReportRedundantConstraints -> Bool
reportRedundantConstraints ReportRedundantConstraints
rrc
UserTypeCtxt
_ -> Bool
False
warnRedundantGivens (InstSkol ClsInstOrQC
from PatersonSize
_)
= case ClsInstOrQC
from of
IsQC {} -> Bool
False
IsClsInst {} -> Bool
True
warnRedundantGivens SkolemInfoAnon
_ = Bool
False
checkBadTelescope :: Implication -> TcS Bool
checkBadTelescope :: Implication -> TcS Bool
checkBadTelescope (Implic { ic_info :: Implication -> SkolemInfoAnon
ic_info = SkolemInfoAnon
info
, ic_skols :: Implication -> [TcTyVar]
ic_skols = [TcTyVar]
skols })
| SkolemInfoAnon -> Bool
checkTelescopeSkol SkolemInfoAnon
info
= do{ skols <- (TcTyVar -> TcS TcTyVar) -> [TcTyVar] -> TcS [TcTyVar]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM TcTyVar -> TcS TcTyVar
TcS.zonkTyCoVarKind [TcTyVar]
skols
; return (go emptyVarSet (reverse skols))}
| Bool
otherwise
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
where
go :: TyVarSet
-> [TcTyVar]
-> Bool
go :: CoVarSet -> [TcTyVar] -> Bool
go CoVarSet
_ [] = Bool
False
go CoVarSet
later_skols (TcTyVar
one_skol : [TcTyVar]
earlier_skols)
| TcType -> CoVarSet
tyCoVarsOfType (TcTyVar -> TcType
tyVarKind TcTyVar
one_skol) CoVarSet -> CoVarSet -> Bool
`intersectsVarSet` CoVarSet
later_skols
= Bool
True
| Bool
otherwise
= CoVarSet -> [TcTyVar] -> Bool
go (CoVarSet
later_skols CoVarSet -> TcTyVar -> CoVarSet
`extendVarSet` TcTyVar
one_skol) [TcTyVar]
earlier_skols
neededEvVars :: Implication -> TcS Implication
neededEvVars :: Implication -> TcS Implication
neededEvVars implic :: Implication
implic@(Implic { ic_info :: Implication -> SkolemInfoAnon
ic_info = SkolemInfoAnon
info
, ic_binds :: Implication -> EvBindsVar
ic_binds = EvBindsVar
ev_binds_var
, ic_wanted :: Implication -> WantedConstraints
ic_wanted = WC { wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics }
, ic_need_implic :: Implication -> EvNeedSet
ic_need_implic = EvNeedSet
old_need_implic
})
= do { ev_binds <- EvBindsVar -> TcS EvBindMap
TcS.getTcEvBindsMap EvBindsVar
ev_binds_var
; used_cos <- TcS.getTcEvTyCoVars ev_binds_var
; let
new_need_implic@(ENS { ens_dms = dm_seeds, ens_fvs = other_seeds })
= foldr add_implic old_need_implic implics
used_covars = [TcCoercion] -> CoVarSet
coVarsOfCos [TcCoercion]
used_cos
seeds_w = (EvBind -> CoVarSet -> CoVarSet)
-> CoVarSet -> EvBindMap -> CoVarSet
forall a. (EvBind -> a -> a) -> a -> EvBindMap -> a
nonDetStrictFoldEvBindMap EvBind -> CoVarSet -> CoVarSet
add_wanted CoVarSet
used_covars EvBindMap
ev_binds
need_ignoring_dms = EvBindMap -> CoVarSet -> CoVarSet
findNeededGivenEvVars EvBindMap
ev_binds (CoVarSet
other_seeds CoVarSet -> CoVarSet -> CoVarSet
`unionVarSet` CoVarSet
seeds_w)
need_from_dms = EvBindMap -> CoVarSet -> CoVarSet
findNeededGivenEvVars EvBindMap
ev_binds CoVarSet
dm_seeds
need_full = CoVarSet
need_ignoring_dms CoVarSet -> CoVarSet -> CoVarSet
`unionVarSet` CoVarSet
need_from_dms
need | SkolemInfoAnon -> Bool
is_dm_skol SkolemInfoAnon
info = ENS { ens_dms :: CoVarSet
ens_dms = EvBindMap -> CoVarSet -> CoVarSet
trim EvBindMap
ev_binds CoVarSet
need_full
, ens_fvs :: CoVarSet
ens_fvs = CoVarSet
emptyVarSet }
| Bool
otherwise = ENS { ens_dms :: CoVarSet
ens_dms = EvBindMap -> CoVarSet -> CoVarSet
trim EvBindMap
ev_binds CoVarSet
need_from_dms
, ens_fvs :: CoVarSet
ens_fvs = EvBindMap -> CoVarSet -> CoVarSet
trim EvBindMap
ev_binds CoVarSet
need_ignoring_dms }
; let live_ev_binds = (EvBind -> Bool) -> EvBindMap -> EvBindMap
filterEvBindMap (CoVarSet -> EvBind -> Bool
needed_ev_bind CoVarSet
need_full) EvBindMap
ev_binds
; TcS.setTcEvBindsMap ev_binds_var live_ev_binds
; traceTcS "neededEvVars" $
vcat [ text "old_need_implic:" <+> ppr old_need_implic
, text "new_need_implic:" <+> ppr new_need_implic
, text "used_covars:" <+> ppr used_covars
, text "need_ignoring_dms:" <+> ppr need_ignoring_dms
, text "need_from_dms:" <+> ppr need_from_dms
, text "need:" <+> ppr need
, text "ev_binds:" <+> ppr ev_binds
, text "live_ev_binds:" <+> ppr live_ev_binds ]
; return (implic { ic_need = need
, ic_need_implic = new_need_implic }) }
where
trim :: EvBindMap -> VarSet -> VarSet
trim :: EvBindMap -> CoVarSet -> CoVarSet
trim EvBindMap
ev_binds CoVarSet
needs = CoVarSet
needs CoVarSet -> EvBindMap -> CoVarSet
`varSetMinusEvBindMap` EvBindMap
ev_binds
add_implic :: Implication -> EvNeedSet -> EvNeedSet
add_implic :: Implication -> EvNeedSet -> EvNeedSet
add_implic (Implic { ic_given :: Implication -> [TcTyVar]
ic_given = [TcTyVar]
givens, ic_need :: Implication -> EvNeedSet
ic_need = EvNeedSet
need }) EvNeedSet
acc
= (EvNeedSet
need EvNeedSet -> [TcTyVar] -> EvNeedSet
`delGivensFromEvNeedSet` [TcTyVar]
givens) EvNeedSet -> EvNeedSet -> EvNeedSet
`unionEvNeedSet` EvNeedSet
acc
needed_ev_bind :: CoVarSet -> EvBind -> Bool
needed_ev_bind CoVarSet
needed (EvBind { eb_lhs :: EvBind -> TcTyVar
eb_lhs = TcTyVar
ev_var, eb_info :: EvBind -> EvBindInfo
eb_info = EvBindInfo
info })
| EvBindGiven{} <- EvBindInfo
info = TcTyVar
ev_var TcTyVar -> CoVarSet -> Bool
`elemVarSet` CoVarSet
needed
| Bool
otherwise = Bool
True
add_wanted :: EvBind -> VarSet -> VarSet
add_wanted :: EvBind -> CoVarSet -> CoVarSet
add_wanted (EvBind { eb_info :: EvBind -> EvBindInfo
eb_info = EvBindInfo
info, eb_rhs :: EvBind -> EvTerm
eb_rhs = EvTerm
rhs }) CoVarSet
needs
| EvBindGiven{} <- EvBindInfo
info = CoVarSet
needs
| Bool
otherwise = EvTerm -> CoVarSet
nestedEvIdsOfTerm EvTerm
rhs CoVarSet -> CoVarSet -> CoVarSet
`unionVarSet` CoVarSet
needs
is_dm_skol :: SkolemInfoAnon -> Bool
is_dm_skol :: SkolemInfoAnon -> Bool
is_dm_skol (MethSkol Name
_ Bool
is_dm) = Bool
is_dm
is_dm_skol SkolemInfoAnon
_ = Bool
False
findNeededGivenEvVars :: EvBindMap -> VarSet -> VarSet
findNeededGivenEvVars :: EvBindMap -> CoVarSet -> CoVarSet
findNeededGivenEvVars EvBindMap
ev_binds CoVarSet
seeds
= (CoVarSet -> CoVarSet) -> CoVarSet -> CoVarSet
transCloVarSet CoVarSet -> CoVarSet
also_needs CoVarSet
seeds
where
also_needs :: VarSet -> VarSet
also_needs :: CoVarSet -> CoVarSet
also_needs CoVarSet
needs = (TcTyVar -> CoVarSet -> CoVarSet)
-> CoVarSet -> CoVarSet -> CoVarSet
forall elt a. (elt -> a -> a) -> a -> UniqSet elt -> a
nonDetStrictFoldUniqSet TcTyVar -> CoVarSet -> CoVarSet
add CoVarSet
emptyVarSet CoVarSet
needs
add :: Var -> VarSet -> VarSet
add :: TcTyVar -> CoVarSet -> CoVarSet
add TcTyVar
v CoVarSet
needs
| Just EvBind
ev_bind <- EvBindMap -> TcTyVar -> Maybe EvBind
lookupEvBind EvBindMap
ev_binds TcTyVar
v
, EvBind { eb_info :: EvBind -> EvBindInfo
eb_info = EvBindInfo
EvBindGiven, eb_rhs :: EvBind -> EvTerm
eb_rhs = EvTerm
rhs } <- EvBind
ev_bind
= EvTerm -> CoVarSet
nestedEvIdsOfTerm EvTerm
rhs CoVarSet -> CoVarSet -> CoVarSet
`unionVarSet` CoVarSet
needs
| Bool
otherwise
= CoVarSet
needs
simplifyDelayedErrors :: Bag DelayedError -> TcS (Bag DelayedError)
simplifyDelayedErrors :: Bag DelayedError -> TcS (Bag DelayedError)
simplifyDelayedErrors = (DelayedError -> TcS (Maybe DelayedError))
-> Bag DelayedError -> TcS (Bag DelayedError)
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> Bag a -> m (Bag b)
mapMaybeBagM DelayedError -> TcS (Maybe DelayedError)
simpl_err
where
simpl_err :: DelayedError -> TcS (Maybe DelayedError)
simpl_err :: DelayedError -> TcS (Maybe DelayedError)
simpl_err (DE_Hole Hole
hole) = DelayedError -> Maybe DelayedError
forall a. a -> Maybe a
Just (DelayedError -> Maybe DelayedError)
-> (Hole -> DelayedError) -> Hole -> Maybe DelayedError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hole -> DelayedError
DE_Hole (Hole -> Maybe DelayedError)
-> TcS Hole -> TcS (Maybe DelayedError)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Hole -> TcS Hole
simpl_hole Hole
hole
simpl_err err :: DelayedError
err@(DE_NotConcrete {}) = Maybe DelayedError -> TcS (Maybe DelayedError)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe DelayedError -> TcS (Maybe DelayedError))
-> Maybe DelayedError -> TcS (Maybe DelayedError)
forall a b. (a -> b) -> a -> b
$ DelayedError -> Maybe DelayedError
forall a. a -> Maybe a
Just DelayedError
err
simpl_err (DE_Multiplicity TcCoercion
mult_co CtLoc
loc)
= do { mult_co' <- TcCoercion -> TcS TcCoercion
TcS.zonkCo TcCoercion
mult_co
; if isReflexiveCo mult_co' then
return Nothing
else
return $ Just (DE_Multiplicity mult_co' loc) }
simpl_hole :: Hole -> TcS Hole
simpl_hole :: Hole -> TcS Hole
simpl_hole h :: Hole
h@(Hole { hole_sort :: Hole -> HoleSort
hole_sort = HoleSort
ConstraintHole }) = Hole -> TcS Hole
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Hole
h
simpl_hole h :: Hole
h@(Hole { hole_ty :: Hole -> TcType
hole_ty = TcType
ty, hole_loc :: Hole -> CtLoc
hole_loc = CtLoc
loc })
= do { ty' <- CtLoc -> TcType -> TcS TcType
rewriteType CtLoc
loc TcType
ty
; traceTcS "simpl_hole" (ppr ty $$ ppr ty')
; return (h { hole_ty = ty' }) }
solveSimpleGivens :: [Ct] -> TcS ()
solveSimpleGivens :: [Ct] -> TcS ()
solveSimpleGivens [Ct]
givens
| [Ct] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Ct]
givens
= () -> TcS ()
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do { String -> SDoc -> TcS ()
traceTcS String
"solveSimpleGivens {" ([Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Ct]
givens)
; [Ct] -> TcS ()
go [Ct]
givens
; (InertSet -> InertSet) -> TcS ()
updInertSet (\InertSet
is -> InertSet
is { inert_givens = inert_cans is })
; cans <- TcS InertCans
getInertCans
; traceTcS "End solveSimpleGivens }" (ppr cans) }
where
go :: [Ct] -> TcS ()
go [Ct]
givens = do { Cts -> TcS ()
solveSimples ([Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
givens)
; new_givens <- TcS [Ct]
runTcPluginsGiven
; when (notNull new_givens) $
go new_givens }
solveSimpleWanteds :: Cts -> TcS Cts
solveSimpleWanteds :: Cts -> TcS Cts
solveSimpleWanteds Cts
simples
= do { mode <- TcS TcSMode
getTcSMode
; dflags <- getDynFlags
; inerts <- getInertSet
; traceTcS "solveSimpleWanteds {" $
vcat [ text "Mode:" <+> ppr mode
, text "Inerts:" <+> ppr inerts
, text "Wanteds to solve:" <+> ppr simples ]
; (n,wc) <- go 1 (solverIterations dflags) simples
; traceTcS "solveSimpleWanteds end }" $
vcat [ text "iterations =" <+> ppr n
, text "residual =" <+> ppr wc ]
; return wc }
where
go :: Int -> IntWithInf -> Cts -> TcS (Int, Cts)
go :: Int -> IntWithInf -> Cts -> TcS (Int, Cts)
go Int
n IntWithInf
limit Cts
wc
| Int
n Int -> IntWithInf -> Bool
`intGtLimit` IntWithInf
limit
= TcRnMessage -> TcS (Int, Cts)
forall a. TcRnMessage -> TcS a
failTcS (TcRnMessage -> TcS (Int, Cts)) -> TcRnMessage -> TcS (Int, Cts)
forall a b. (a -> b) -> a -> b
$ Cts -> IntWithInf -> WantedConstraints -> TcRnMessage
TcRnSimplifierTooManyIterations
Cts
simples IntWithInf
limit (WantedConstraints
emptyWC { wc_simple = wc })
| Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag Cts
wc
= (Int, Cts) -> TcS (Int, Cts)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n,Cts
wc)
| Bool
otherwise
= do {
wc1 <- Cts -> TcS Cts
solve_simple_wanteds Cts
wc
; (rerun_plugin, wc2) <- runTcPluginsWanted wc1
; if rerun_plugin
then do { traceTcS "solveSimple going round again:" (ppr rerun_plugin)
; go (n+1) limit wc2 }
else return (n, wc2) }
solve_simple_wanteds :: Cts -> TcS Cts
solve_simple_wanteds :: Cts -> TcS Cts
solve_simple_wanteds Cts
simples
= TcS Cts -> TcS Cts
forall a. TcS a -> TcS a
nestTcS (TcS Cts -> TcS Cts) -> TcS Cts -> TcS Cts
forall a b. (a -> b) -> a -> b
$ do { Cts -> TcS ()
solveSimples Cts
simples
; TcS Cts
getUnsolvedInerts }
solveSimples :: Cts -> TcS ()
solveSimples :: Cts -> TcS ()
solveSimples Cts
cts
= {-# SCC "solveSimples" #-}
do { Cts -> TcS ()
emitWork Cts
cts; TcS ()
solve_loop }
where
solve_loop :: TcS ()
solve_loop
= {-# SCC "solve_loop" #-}
do { sel <- TcS (Maybe Ct)
selectNextWorkItem
; case sel of
Maybe Ct
Nothing -> () -> TcS ()
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just Ct
ct -> do { Ct -> TcS ()
solveOne Ct
ct
; TcS ()
solve_loop } }
solveOne :: Ct -> TcS ()
solveOne :: Ct -> TcS ()
solveOne Ct
workItem
= do { wl <- TcS WorkList
getWorkList
; inerts <- getInertSet
; tclevel <- TcS.getTcLevel
; traceTcS "----------------------------- " empty
; traceTcS "Start solver pipeline {" $
vcat [ text "tclevel =" <+> ppr tclevel
, text "work item =" <+> ppr workItem
, text "inerts =" <+> ppr inerts
, text "rest of worklist =" <+> ppr wl ]
; bumpStepCountTcS
; solve workItem }
where
solve :: Ct -> TcS ()
solve :: Ct -> TcS ()
solve Ct
ct
= do { String -> SDoc -> TcS ()
traceTcS String
"solve {" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"workitem = " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Ct -> SDoc
forall a. Outputable a => a -> SDoc
ppr Ct
ct)
; res <- SolverStage Void -> TcS (StopOrContinue Void)
forall a. SolverStage a -> TcS (StopOrContinue a)
runSolverStage (Ct -> SolverStage Void
solveCt Ct
ct)
; traceTcS "end solve }" (ppr res)
; case res of
StartAgain Ct
ct -> do { String -> SDoc -> TcS ()
traceTcS String
"Go round again" (Ct -> SDoc
forall a. Outputable a => a -> SDoc
ppr Ct
ct)
; Ct -> TcS ()
solve Ct
ct }
Stop CtEvidence
ev SDoc
s -> do { CtEvidence -> SDoc -> TcS ()
traceFireTcS CtEvidence
ev SDoc
s
; String -> SDoc -> TcS ()
traceTcS String
"End solver pipeline }" SDoc
forall doc. IsOutput doc => doc
empty
; () -> TcS ()
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return () }
}
solveCt :: Ct -> SolverStage Void
solveCt :: Ct -> SolverStage Void
solveCt (CNonCanonical CtEvidence
ev) = CtEvidence -> SolverStage Void
solveNC CtEvidence
ev
solveCt (CIrredCan (IrredCt { ir_ev :: IrredCt -> CtEvidence
ir_ev = CtEvidence
ev })) = CtEvidence -> SolverStage Void
solveNC CtEvidence
ev
solveCt (CEqCan (EqCt { eq_ev :: EqCt -> CtEvidence
eq_ev = CtEvidence
ev, eq_eq_rel :: EqCt -> EqRel
eq_eq_rel = EqRel
eq_rel
, eq_lhs :: EqCt -> CanEqLHS
eq_lhs = CanEqLHS
lhs, eq_rhs :: EqCt -> TcType
eq_rhs = TcType
rhs }))
= CtEvidence -> EqRel -> TcType -> TcType -> SolverStage Void
solveEquality CtEvidence
ev EqRel
eq_rel (CanEqLHS -> TcType
canEqLHSType CanEqLHS
lhs) TcType
rhs
solveCt (CQuantCan qci :: QCInst
qci@(QCI { qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev }))
= do { ev' <- CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
; case classifyPredType (ctEvPred ev') of
ForAllPred [TcTyVar]
tvs [TcType]
theta TcType
body_pred
-> QCInst -> SolverStage Void
solveForAll (QCInst
qci { qci_ev = ev', qci_tvs = tvs
, qci_theta = theta, qci_body = body_pred })
Pred
_ -> String -> SDoc -> SolverStage Void
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"SolveCt" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev) }
solveCt (CDictCan (DictCt { di_ev :: DictCt -> CtEvidence
di_ev = CtEvidence
ev, di_pend_sc :: DictCt -> Int
di_pend_sc = Int
pend_sc }))
= do { ev <- CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
; case classifyPredType (ctEvPred ev) of
ClassPred Class
cls [TcType]
tys
-> DictCt -> SolverStage Void
solveDict (DictCt { di_ev :: CtEvidence
di_ev = CtEvidence
ev, di_cls :: Class
di_cls = Class
cls
, di_tys :: [TcType]
di_tys = [TcType]
tys, di_pend_sc :: Int
di_pend_sc = Int
pend_sc })
Pred
_ -> String -> SDoc -> SolverStage Void
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"solveCt" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev) }
solveNC :: CtEvidence -> SolverStage Void
solveNC :: CtEvidence -> SolverStage Void
solveNC CtEvidence
ev
=
case HasDebugCallStack => TcType -> Pred
TcType -> Pred
classifyPredType (CtEvidence -> TcType
ctEvPred CtEvidence
ev) of {
EqPred EqRel
eq_rel TcType
ty1 TcType
ty2 -> CtEvidence -> EqRel -> TcType -> TcType -> SolverStage Void
solveEquality CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ty2 ;
Pred
_ ->
do { ev <- CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
; case classifyPredType (ctEvPred ev) of
ClassPred Class
cls [TcType]
tys -> CtEvidence -> Class -> [TcType] -> SolverStage Void
solveDictNC CtEvidence
ev Class
cls [TcType]
tys
ForAllPred [TcTyVar]
tvs [TcType]
th TcType
p -> CtEvidence -> [TcTyVar] -> [TcType] -> TcType -> SolverStage Void
solveForAllNC CtEvidence
ev [TcTyVar]
tvs [TcType]
th TcType
p
IrredPred {} -> IrredCt -> SolverStage Void
solveIrred (IrredCt { ir_ev :: CtEvidence
ir_ev = CtEvidence
ev, ir_reason :: CtIrredReason
ir_reason = CtIrredReason
IrredShapeReason })
EqPred EqRel
eq_rel TcType
ty1 TcType
ty2 -> CtEvidence -> EqRel -> TcType -> TcType -> SolverStage Void
solveEquality CtEvidence
ev EqRel
eq_rel TcType
ty1 TcType
ty2
}}
solveForAllNC :: CtEvidence -> [TcTyVar] -> TcThetaType -> TcPredType
-> SolverStage Void
solveForAllNC :: CtEvidence -> [TcTyVar] -> [TcType] -> TcType -> SolverStage Void
solveForAllNC CtEvidence
ev [TcTyVar]
tvs [TcType]
theta TcType
body_pred
= do { fuel <- TcS Int -> SolverStage Int
forall a. TcS a -> SolverStage a
simpleStage TcS Int
mk_super_classes
; solveForAll (QCI { qci_ev = ev, qci_tvs = tvs, qci_theta = theta
, qci_body = body_pred, qci_pend_sc = fuel }) }
where
mk_super_classes :: TcS ExpansionFuel
mk_super_classes :: TcS Int
mk_super_classes
| Just (Class
cls,[TcType]
tys) <- TcType -> Maybe (Class, [TcType])
getClassPredTys_maybe TcType
body_pred
, Class -> Bool
classHasSCs Class
cls
= do { dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; if isGiven ev
then
do { sc_cts <- mkStrictSuperClasses (givensFuel dflags) ev tvs theta cls tys
; emitWork (listToBag sc_cts)
; return doNotExpand }
else
return (qcsFuel dflags)
}
| Bool
otherwise
= Int -> TcS Int
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
doNotExpand
solveForAll :: QCInst -> SolverStage Void
solveForAll :: QCInst -> SolverStage Void
solveForAll qci :: QCInst
qci@(QCI { qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev, qci_tvs :: QCInst -> [TcTyVar]
qci_tvs = [TcTyVar]
tvs, qci_theta :: QCInst -> [TcType]
qci_theta = [TcType]
theta, qci_body :: QCInst -> TcType
qci_body = TcType
pred })
= case CtEvidence
ev of
CtGiven {} ->
do { TcS () -> SolverStage ()
forall a. TcS a -> SolverStage a
simpleStage (QCInst -> TcS ()
addInertForAll QCInst
qci)
; CtEvidence -> String -> SolverStage Void
forall a. CtEvidence -> String -> SolverStage a
stopWithStage CtEvidence
ev String
"Given forall-constraint" }
CtWanted WantedCtEvidence
wtd ->
do { QCInst -> SolverStage ()
tryInertQCs QCInst
qci
; QCInst
-> [TcTyVar]
-> [TcType]
-> TcType
-> WantedCtEvidence
-> SolverStage Void
solveWantedForAll QCInst
qci [TcTyVar]
tvs [TcType]
theta TcType
pred WantedCtEvidence
wtd }
tryInertQCs :: QCInst -> SolverStage ()
tryInertQCs :: QCInst -> SolverStage ()
tryInertQCs QCInst
qc
= TcS (StopOrContinue ()) -> SolverStage ()
forall a. TcS (StopOrContinue a) -> SolverStage a
Stage (TcS (StopOrContinue ()) -> SolverStage ())
-> TcS (StopOrContinue ()) -> SolverStage ()
forall a b. (a -> b) -> a -> b
$
do { inerts <- TcS InertCans
getInertCans
; try_inert_qcs qc (inert_insts inerts) }
try_inert_qcs :: QCInst -> [QCInst] -> TcS (StopOrContinue ())
try_inert_qcs :: QCInst -> [QCInst] -> TcS (StopOrContinue ())
try_inert_qcs (QCI { qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev_w }) [QCInst]
inerts =
case (QCInst -> Maybe CtEvidence) -> [QCInst] -> [CtEvidence]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe QCInst -> Maybe CtEvidence
matching_inert [QCInst]
inerts of
[] -> do { String -> SDoc -> TcS ()
traceTcS String
"tryInertQCs:nothing" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev_w SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ [QCInst] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [QCInst]
inerts)
; () -> TcS (StopOrContinue ())
forall a. a -> TcS (StopOrContinue a)
continueWith () }
CtEvidence
ev_i:[CtEvidence]
_ ->
do { String -> SDoc -> TcS ()
traceTcS String
"tryInertQCs:KeepInert" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev_i)
; CtEvidence -> CanonicalEvidence -> EvTerm -> TcS ()
setEvBindIfWanted CtEvidence
ev_w CanonicalEvidence
EvCanonical (CtEvidence -> EvTerm
ctEvTerm CtEvidence
ev_i)
; CtEvidence -> String -> TcS (StopOrContinue ())
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev_w String
"Solved Wanted forall-constraint from inert" }
where
matching_inert :: QCInst -> Maybe CtEvidence
matching_inert (QCI { qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev_i })
| CtEvidence -> TcType
ctEvPred CtEvidence
ev_i HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` CtEvidence -> TcType
ctEvPred CtEvidence
ev_w
= CtEvidence -> Maybe CtEvidence
forall a. a -> Maybe a
Just CtEvidence
ev_i
| Bool
otherwise
= Maybe CtEvidence
forall a. Maybe a
Nothing
solveWantedForAll :: QCInst -> [TcTyVar] -> TcThetaType -> PredType
-> WantedCtEvidence -> SolverStage Void
solveWantedForAll :: QCInst
-> [TcTyVar]
-> [TcType]
-> TcType
-> WantedCtEvidence
-> SolverStage Void
solveWantedForAll QCInst
qci [TcTyVar]
tvs [TcType]
theta TcType
body_pred
wtd :: WantedCtEvidence
wtd@(WantedCt { ctev_dest :: WantedCtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest, ctev_loc :: WantedCtEvidence -> CtLoc
ctev_loc = CtLoc
ct_loc
, ctev_rewriters :: WantedCtEvidence -> RewriterSet
ctev_rewriters = RewriterSet
rewriters })
= TcS (StopOrContinue Void) -> SolverStage Void
forall a. TcS (StopOrContinue a) -> SolverStage a
Stage (TcS (StopOrContinue Void) -> SolverStage Void)
-> TcS (StopOrContinue Void) -> SolverStage Void
forall a b. (a -> b) -> a -> b
$
RealSrcSpan
-> TcS (StopOrContinue Void) -> TcS (StopOrContinue Void)
forall a. RealSrcSpan -> TcS a -> TcS a
TcS.setSrcSpan (CtLocEnv -> RealSrcSpan
getCtLocEnvLoc CtLocEnv
loc_env) (TcS (StopOrContinue Void) -> TcS (StopOrContinue Void))
-> TcS (StopOrContinue Void) -> TcS (StopOrContinue Void)
forall a b. (a -> b) -> a -> b
$
do {
rec { skol_info <- mkSkolemInfo skol_info_anon
; (subst, skol_tvs) <- tcInstSkolTyVarsX skol_info empty_subst tvs
; let inst_pred = HasDebugCallStack => Subst -> TcType -> TcType
Subst -> TcType -> TcType
substTy Subst
subst TcType
body_pred
inst_theta = HasDebugCallStack => Subst -> [TcType] -> [TcType]
Subst -> [TcType] -> [TcType]
substTheta Subst
subst [TcType]
theta
skol_info_anon = ClsInstOrQC -> PatersonSize -> SkolemInfoAnon
InstSkol ClsInstOrQC
is_qc (TcType -> PatersonSize
pSizeHead TcType
inst_pred) }
; given_ev_vars <- mapM newEvVar inst_theta
; (lvl, (w_id, wanteds))
<- pushLevelNoWorkList (ppr skol_info) $
do { let ct_loc' = CtLoc -> CtOrigin -> CtLoc
setCtLocOrigin CtLoc
ct_loc (ClsInstOrQC -> NakedScFlag -> CtOrigin
ScOrigin ClsInstOrQC
is_qc NakedScFlag
NakedSc)
; wanted_ev <- newWantedNC ct_loc' rewriters inst_pred
; return ( wantedCtEvEvId wanted_ev
, unitBag (mkNonCanonical $ CtWanted wanted_ev)) }
; traceTcS "solveForAll {" (ppr skol_tvs $$ ppr given_ev_vars $$ ppr wanteds $$ ppr w_id)
; ev_binds_var <- TcS.newTcEvBinds
; solved <- trySolveImplication $
(implicationPrototype loc_env)
{ ic_tclvl = lvl
, ic_binds = ev_binds_var
, ic_info = skol_info_anon
, ic_warn_inaccessible = False
, ic_skols = skol_tvs
, ic_given = given_ev_vars
, ic_wanted = emptyWC { wc_simple = wanteds } }
; traceTcS "solveForAll }" (ppr solved)
; if not solved
then do {
addInertForAll qci
; stopWith (CtWanted wtd) "Wanted forall-constraint:unsolved" }
else do {
evbs <- TcS.getTcEvBindsMap ev_binds_var
; setWantedEvTerm dest EvCanonical $
EvFun { et_tvs = skol_tvs, et_given = given_ev_vars
, et_binds = evBindMapBinds evbs, et_body = w_id }
; stopWith (CtWanted wtd) "Wanted forall-constraint:solved" } }
where
loc_env :: CtLocEnv
loc_env = CtLoc -> CtLocEnv
ctLocEnv CtLoc
ct_loc
is_qc :: ClsInstOrQC
is_qc = CtOrigin -> ClsInstOrQC
IsQC (CtLoc -> CtOrigin
ctLocOrigin CtLoc
ct_loc)
empty_subst :: Subst
empty_subst = InScopeSet -> Subst
mkEmptySubst (InScopeSet -> Subst) -> InScopeSet -> Subst
forall a b. (a -> b) -> a -> b
$ CoVarSet -> InScopeSet
mkInScopeSet (CoVarSet -> InScopeSet) -> CoVarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$
[TcType] -> CoVarSet
tyCoVarsOfTypes (TcType
body_predTcType -> [TcType] -> [TcType]
forall a. a -> [a] -> [a]
:[TcType]
theta) CoVarSet -> [TcTyVar] -> CoVarSet
`delVarSetList` [TcTyVar]
tvs
rewriteEvidence :: CtEvidence -> SolverStage CtEvidence
rewriteEvidence :: CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
= TcS (StopOrContinue CtEvidence) -> SolverStage CtEvidence
forall a. TcS (StopOrContinue a) -> SolverStage a
Stage (TcS (StopOrContinue CtEvidence) -> SolverStage CtEvidence)
-> TcS (StopOrContinue CtEvidence) -> SolverStage CtEvidence
forall a b. (a -> b) -> a -> b
$ do { String -> SDoc -> TcS ()
traceTcS String
"rewriteEvidence" (CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ev)
; (redn, rewriters) <- CtEvidence -> TcType -> TcS (Reduction, RewriterSet)
rewrite CtEvidence
ev (CtEvidence -> TcType
ctEvPred CtEvidence
ev)
; finish_rewrite ev redn rewriters }
finish_rewrite :: CtEvidence
-> Reduction
-> RewriterSet
-> TcS (StopOrContinue CtEvidence)
finish_rewrite :: CtEvidence
-> Reduction -> RewriterSet -> TcS (StopOrContinue CtEvidence)
finish_rewrite CtEvidence
old_ev (Reduction TcCoercion
co TcType
new_pred) RewriterSet
rewriters
| TcCoercion -> Bool
isReflCo TcCoercion
co
= Bool
-> TcS (StopOrContinue CtEvidence)
-> TcS (StopOrContinue CtEvidence)
forall a. HasCallStack => Bool -> a -> a
assert (RewriterSet -> Bool
isEmptyRewriterSet RewriterSet
rewriters) (TcS (StopOrContinue CtEvidence)
-> TcS (StopOrContinue CtEvidence))
-> TcS (StopOrContinue CtEvidence)
-> TcS (StopOrContinue CtEvidence)
forall a b. (a -> b) -> a -> b
$
CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith (HasDebugCallStack => CtEvidence -> TcType -> CtEvidence
CtEvidence -> TcType -> CtEvidence
setCtEvPredType CtEvidence
old_ev TcType
new_pred)
finish_rewrite
ev :: CtEvidence
ev@(CtGiven (GivenCt { ctev_evar :: GivenCtEvidence -> TcTyVar
ctev_evar = TcTyVar
old_evar }))
(Reduction TcCoercion
co TcType
new_pred)
RewriterSet
rewriters
= Bool
-> TcS (StopOrContinue CtEvidence)
-> TcS (StopOrContinue CtEvidence)
forall a. HasCallStack => Bool -> a -> a
assert (RewriterSet -> Bool
isEmptyRewriterSet RewriterSet
rewriters) (TcS (StopOrContinue CtEvidence)
-> TcS (StopOrContinue CtEvidence))
-> TcS (StopOrContinue CtEvidence)
-> TcS (StopOrContinue CtEvidence)
forall a b. (a -> b) -> a -> b
$
do { let loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
ev_rw_role :: Role
ev_rw_role = HasDebugCallStack => CtEvidence -> Role
CtEvidence -> Role
ctEvRewriteRole CtEvidence
ev
new_tm :: EvTerm
new_tm = Bool
-> (EvExpr -> TcCoercion -> EvTerm)
-> EvExpr
-> TcCoercion
-> EvTerm
forall a. HasCallStack => Bool -> a -> a
assert (TcCoercion -> Role
coercionRole TcCoercion
co Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== Role
ev_rw_role)
EvExpr -> TcCoercion -> EvTerm
evCast (TcTyVar -> EvExpr
evId TcTyVar
old_evar) (TcCoercion -> EvTerm) -> TcCoercion -> EvTerm
forall a b. (a -> b) -> a -> b
$
Role -> Role -> TcCoercion -> TcCoercion
downgradeRole Role
Representational Role
ev_rw_role TcCoercion
co
; new_ev <- CtLoc -> (TcType, EvTerm) -> TcS GivenCtEvidence
newGivenEvVar CtLoc
loc (TcType
new_pred, EvTerm
new_tm)
; continueWith $ CtGiven new_ev }
finish_rewrite
ev :: CtEvidence
ev@(CtWanted (WantedCt { ctev_rewriters :: WantedCtEvidence -> RewriterSet
ctev_rewriters = RewriterSet
rewriters, ctev_dest :: WantedCtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest }))
(Reduction TcCoercion
co TcType
new_pred)
RewriterSet
new_rewriters
= do { let loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev
rewriters' :: RewriterSet
rewriters' = RewriterSet
rewriters RewriterSet -> RewriterSet -> RewriterSet
forall a. Semigroup a => a -> a -> a
S.<> RewriterSet
new_rewriters
ev_rw_role :: Role
ev_rw_role = HasDebugCallStack => CtEvidence -> Role
CtEvidence -> Role
ctEvRewriteRole CtEvidence
ev
; mb_new_ev <- CtLoc -> RewriterSet -> TcType -> TcS MaybeNew
newWanted CtLoc
loc RewriterSet
rewriters' TcType
new_pred
; massert (coercionRole co == ev_rw_role)
; setWantedEvTerm dest EvCanonical $
evCast (getEvExpr mb_new_ev) $
downgradeRole Representational ev_rw_role (mkSymCo co)
; case mb_new_ev of
Fresh WantedCtEvidence
new_ev -> CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a. a -> TcS (StopOrContinue a)
continueWith (CtEvidence -> TcS (StopOrContinue CtEvidence))
-> CtEvidence -> TcS (StopOrContinue CtEvidence)
forall a b. (a -> b) -> a -> b
$ WantedCtEvidence -> CtEvidence
CtWanted WantedCtEvidence
new_ev
Cached EvExpr
_ -> CtEvidence -> String -> TcS (StopOrContinue CtEvidence)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Cached wanted" }
runTcPluginsGiven :: TcS [Ct]
runTcPluginsGiven :: TcS [Ct]
runTcPluginsGiven
= do { solvers <- TcS [TcPluginSolver]
getTcPluginSolvers
; if null solvers then return [] else
do { givens <- getInertGivens
; if null givens then return [] else
do { traceTcS "runTcPluginsGiven {" (ppr givens)
; p <- runTcPluginSolvers solvers (givens,[])
; let (solved_givens, _) = pluginSolvedCts p
insols = (Ct -> IrredCt) -> [Ct] -> [IrredCt]
forall a b. (a -> b) -> [a] -> [b]
map (CtIrredReason -> Ct -> IrredCt
ctIrredCt CtIrredReason
PluginReason) (TcPluginProgress -> [Ct]
pluginBadCts TcPluginProgress
p)
; updInertCans (removeInertCts solved_givens .
updIrreds (addIrreds insols) )
; traceTcS "runTcPluginsGiven }" $
vcat [ text "solved_givens:" <+> ppr solved_givens
, text "insols:" <+> ppr insols
, text "new:" <+> ppr (pluginNewCts p) ]
; return (pluginNewCts p) } } }
runTcPluginsWanted :: Cts -> TcS (Bool, Cts)
runTcPluginsWanted :: Cts -> TcS (Bool, Cts)
runTcPluginsWanted Cts
wanted
| Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag Cts
wanted
= (Bool, Cts) -> TcS (Bool, Cts)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Cts
wanted)
| Bool
otherwise
= do { solvers <- TcS [TcPluginSolver]
getTcPluginSolvers
; if null solvers then return (False, wanted) else
do {
mode <- getTcSMode
; given <- case mode of
TcSMode
TcSShortCut -> [Ct] -> TcS [Ct]
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return []
TcSMode
_ -> TcS [Ct]
getInertGivens
; zonked_wanted <- TcS.zonkSimples wanted
; traceTcS "Running plugins {" (vcat [ text "Given:" <+> ppr given
, text "Wanted:" <+> ppr zonked_wanted ])
; p <- runTcPluginSolvers solvers (given, bagToList zonked_wanted)
; let (_, solved_wanted) = pluginSolvedCts p
(_, unsolved_wanted) = pluginInputCts p
new_wanted = TcPluginProgress -> [Ct]
pluginNewCts TcPluginProgress
p
insols = TcPluginProgress -> [Ct]
pluginBadCts TcPluginProgress
p
all_new_wanted = [Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
new_wanted Cts -> Cts -> Cts
`andCts`
[Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
unsolved_wanted Cts -> Cts -> Cts
`andCts`
[Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
insols
; mapM_ setEv solved_wanted
; traceTcS "Finished plugins }" (ppr new_wanted)
; return ( notNull (pluginNewCts p), all_new_wanted ) } }
where
setEv :: (EvTerm,Ct) -> TcS ()
setEv :: (EvTerm, Ct) -> TcS ()
setEv (EvTerm
ev,Ct
ct) = case Ct -> CtEvidence
ctEvidence Ct
ct of
CtWanted (WantedCt { ctev_dest :: WantedCtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest }) -> TcEvDest -> CanonicalEvidence -> EvTerm -> TcS ()
setWantedEvTerm TcEvDest
dest CanonicalEvidence
EvCanonical EvTerm
ev
CtEvidence
_ -> String -> TcS ()
forall a. HasCallStack => String -> a
panic String
"runTcPluginsWanted.setEv: attempt to solve non-wanted!"
type SplitCts = ([Ct], [Ct])
type SolvedCts = ([Ct], [(EvTerm,Ct)])
data TcPluginProgress = TcPluginProgress
{ TcPluginProgress -> SplitCts
pluginInputCts :: SplitCts
, TcPluginProgress -> ([Ct], [(EvTerm, Ct)])
pluginSolvedCts :: SolvedCts
, TcPluginProgress -> [Ct]
pluginBadCts :: [Ct]
, TcPluginProgress -> [Ct]
pluginNewCts :: [Ct]
}
getTcPluginSolvers :: TcS [TcPluginSolver]
getTcPluginSolvers :: TcS [TcPluginSolver]
getTcPluginSolvers
= do { tcg_env <- TcS TcGblEnv
TcS.getGblEnv; return (tcg_tc_plugin_solvers tcg_env) }
runTcPluginSolvers :: [TcPluginSolver] -> SplitCts -> TcS TcPluginProgress
runTcPluginSolvers :: [TcPluginSolver] -> SplitCts -> TcS TcPluginProgress
runTcPluginSolvers [TcPluginSolver]
solvers SplitCts
all_cts
= do { ev_binds_var <- TcS EvBindsVar
getTcEvBindsVar
; foldM (do_plugin ev_binds_var) initialProgress solvers }
where
do_plugin :: EvBindsVar -> TcPluginProgress -> TcPluginSolver -> TcS TcPluginProgress
do_plugin :: EvBindsVar
-> TcPluginProgress -> TcPluginSolver -> TcS TcPluginProgress
do_plugin EvBindsVar
ev_binds_var TcPluginProgress
p TcPluginSolver
solver = do
result <- TcPluginM TcPluginSolveResult -> TcS TcPluginSolveResult
forall a. TcPluginM a -> TcS a
runTcPluginTcS (([Ct] -> [Ct] -> TcPluginM TcPluginSolveResult)
-> SplitCts -> TcPluginM TcPluginSolveResult
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (TcPluginSolver
solver EvBindsVar
ev_binds_var) (TcPluginProgress -> SplitCts
pluginInputCts TcPluginProgress
p))
return $ progress p result
progress :: TcPluginProgress -> TcPluginSolveResult -> TcPluginProgress
progress :: TcPluginProgress -> TcPluginSolveResult -> TcPluginProgress
progress TcPluginProgress
p
(TcPluginSolveResult
{ tcPluginInsolubleCts :: TcPluginSolveResult -> [Ct]
tcPluginInsolubleCts = [Ct]
bad_cts
, tcPluginSolvedCts :: TcPluginSolveResult -> [(EvTerm, Ct)]
tcPluginSolvedCts = [(EvTerm, Ct)]
solved_cts
, tcPluginNewCts :: TcPluginSolveResult -> [Ct]
tcPluginNewCts = [Ct]
new_cts
}
) =
TcPluginProgress
p { pluginInputCts = discard (bad_cts ++ map snd solved_cts) (pluginInputCts p)
, pluginSolvedCts = add solved_cts (pluginSolvedCts p)
, pluginNewCts = new_cts ++ pluginNewCts p
, pluginBadCts = bad_cts ++ pluginBadCts p
}
initialProgress :: TcPluginProgress
initialProgress = SplitCts
-> ([Ct], [(EvTerm, Ct)]) -> [Ct] -> [Ct] -> TcPluginProgress
TcPluginProgress SplitCts
all_cts ([], []) [] []
discard :: [Ct] -> SplitCts -> SplitCts
discard :: [Ct] -> SplitCts -> SplitCts
discard [Ct]
cts ([Ct]
xs, [Ct]
ys) =
([Ct]
xs [Ct] -> [Ct] -> [Ct]
`without` [Ct]
cts, [Ct]
ys [Ct] -> [Ct] -> [Ct]
`without` [Ct]
cts)
without :: [Ct] -> [Ct] -> [Ct]
without :: [Ct] -> [Ct] -> [Ct]
without = (Ct -> Ct -> Bool) -> [Ct] -> [Ct] -> [Ct]
forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
deleteFirstsBy Ct -> Ct -> Bool
eq_ct
eq_ct :: Ct -> Ct -> Bool
eq_ct :: Ct -> Ct -> Bool
eq_ct Ct
c Ct
c' = Ct -> CtFlavour
ctFlavour Ct
c CtFlavour -> CtFlavour -> Bool
forall a. Eq a => a -> a -> Bool
== Ct -> CtFlavour
ctFlavour Ct
c'
Bool -> Bool -> Bool
&& Ct -> TcType
ctPred Ct
c HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` Ct -> TcType
ctPred Ct
c'
add :: [(EvTerm,Ct)] -> SolvedCts -> SolvedCts
add :: [(EvTerm, Ct)] -> ([Ct], [(EvTerm, Ct)]) -> ([Ct], [(EvTerm, Ct)])
add [(EvTerm, Ct)]
xs ([Ct], [(EvTerm, Ct)])
scs = (([Ct], [(EvTerm, Ct)]) -> (EvTerm, Ct) -> ([Ct], [(EvTerm, Ct)]))
-> ([Ct], [(EvTerm, Ct)])
-> [(EvTerm, Ct)]
-> ([Ct], [(EvTerm, Ct)])
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ([Ct], [(EvTerm, Ct)]) -> (EvTerm, Ct) -> ([Ct], [(EvTerm, Ct)])
addOne ([Ct], [(EvTerm, Ct)])
scs [(EvTerm, Ct)]
xs
addOne :: SolvedCts -> (EvTerm,Ct) -> SolvedCts
addOne :: ([Ct], [(EvTerm, Ct)]) -> (EvTerm, Ct) -> ([Ct], [(EvTerm, Ct)])
addOne ([Ct]
givens, [(EvTerm, Ct)]
wanteds) (EvTerm
ev,Ct
ct) = case Ct -> CtEvidence
ctEvidence Ct
ct of
CtGiven {} -> (Ct
ctCt -> [Ct] -> [Ct]
forall a. a -> [a] -> [a]
:[Ct]
givens, [(EvTerm, Ct)]
wanteds)
CtWanted {} -> ([Ct]
givens, (EvTerm
ev,Ct
ct)(EvTerm, Ct) -> [(EvTerm, Ct)] -> [(EvTerm, Ct)]
forall a. a -> [a] -> [a]
:[(EvTerm, Ct)]
wanteds)