{-# LANGUAGE RecursiveDo #-}
module GHC.Tc.Solver.Solve (
     solveSimpleGivens,   
     solveSimpleWanteds   
  ) 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 )
import GHC.Tc.Errors.Types
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.Evidence
import GHC.Tc.Types
import GHC.Tc.Types.Origin
import GHC.Tc.Types.Constraint
import GHC.Tc.Solver.InertSet
import GHC.Tc.Solver.Monad
import GHC.Core.Predicate
import GHC.Core.Reduction
import GHC.Core.Coercion
import GHC.Core.Class( classHasSCs )
import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.Basic ( IntWithInf, intGtLimit )
import GHC.Data.Bag
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Utils.Panic.Plain
import GHC.Utils.Misc
import GHC.Driver.Session
import Data.List( deleteFirstsBy )
import Control.Monad
import Data.Semigroup as S
import Data.Void( Void )
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
       ; String -> SDoc -> TcS ()
traceTcS String
"End solveSimpleGivens }" SDoc
forall doc. IsOutput doc => doc
empty }
  where
    go :: [Ct] -> TcS ()
go [Ct]
givens = do { Cts -> TcS ()
solveSimples ([Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
givens)
                   ; [Ct]
new_givens <- TcS [Ct]
runTcPluginsGiven
                   ; Bool -> TcS () -> TcS ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Ct] -> Bool
forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull [Ct]
new_givens) (TcS () -> TcS ()) -> TcS () -> TcS ()
forall a b. (a -> b) -> a -> b
$
                     [Ct] -> TcS ()
go [Ct]
new_givens }
solveSimpleWanteds :: Cts -> TcS WantedConstraints
solveSimpleWanteds :: Cts -> TcS WantedConstraints
solveSimpleWanteds Cts
simples
  = do { String -> SDoc -> TcS ()
traceTcS String
"solveSimpleWanteds {" (Cts -> SDoc
forall a. Outputable a => a -> SDoc
ppr Cts
simples)
       ; DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
       ; (Int
n,WantedConstraints
wc) <- Int
-> IntWithInf -> WantedConstraints -> TcS (Int, WantedConstraints)
go Int
1 (DynFlags -> IntWithInf
solverIterations DynFlags
dflags) (WantedConstraints
emptyWC { wc_simple = simples })
       ; String -> SDoc -> TcS ()
traceTcS String
"solveSimpleWanteds end }" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
             [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"iterations =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n
                  , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"residual =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wc ]
       ; WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc }
  where
    go :: Int -> IntWithInf -> WantedConstraints -> TcS (Int, WantedConstraints)
    
    go :: Int
-> IntWithInf -> WantedConstraints -> TcS (Int, WantedConstraints)
go Int
n IntWithInf
limit WantedConstraints
wc
      | Int
n Int -> IntWithInf -> Bool
`intGtLimit` IntWithInf
limit
      = TcRnMessage -> TcS (Int, WantedConstraints)
forall a. TcRnMessage -> TcS a
failTcS (TcRnMessage -> TcS (Int, WantedConstraints))
-> TcRnMessage -> TcS (Int, WantedConstraints)
forall a b. (a -> b) -> a -> b
$ Cts -> IntWithInf -> WantedConstraints -> TcRnMessage
TcRnSimplifierTooManyIterations Cts
simples IntWithInf
limit WantedConstraints
wc
     | Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag (WantedConstraints -> Cts
wc_simple WantedConstraints
wc)
     = (Int, WantedConstraints) -> TcS (Int, WantedConstraints)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n,WantedConstraints
wc)
     | Bool
otherwise
     = do { 
            WantedConstraints
wc1 <- WantedConstraints -> TcS WantedConstraints
solve_simple_wanteds WantedConstraints
wc
            
          ; (Bool
rerun_plugin, WantedConstraints
wc2) <- WantedConstraints -> TcS (Bool, WantedConstraints)
runTcPluginsWanted WantedConstraints
wc1
          ; if Bool
rerun_plugin
            then do { String -> SDoc -> TcS ()
traceTcS String
"solveSimple going round again:" (Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
rerun_plugin)
                    ; Int
-> IntWithInf -> WantedConstraints -> TcS (Int, WantedConstraints)
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) IntWithInf
limit WantedConstraints
wc2 }   
            else (Int, WantedConstraints) -> TcS (Int, WantedConstraints)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
n, WantedConstraints
wc2) }           
solve_simple_wanteds :: WantedConstraints -> TcS WantedConstraints
solve_simple_wanteds :: WantedConstraints -> TcS WantedConstraints
solve_simple_wanteds (WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples1, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics1, wc_errors :: WantedConstraints -> Bag DelayedError
wc_errors = Bag DelayedError
errs })
  = TcS WantedConstraints -> TcS WantedConstraints
forall a. TcS a -> TcS a
nestTcS (TcS WantedConstraints -> TcS WantedConstraints)
-> TcS WantedConstraints -> TcS WantedConstraints
forall a b. (a -> b) -> a -> b
$
    do { Cts -> TcS ()
solveSimples Cts
simples1
       ; (Bag Implication
implics2, Cts
unsolved) <- TcS (Bag Implication, Cts)
getUnsolvedInerts
       ; WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (WC { wc_simple :: Cts
wc_simple = Cts
unsolved
                    , wc_impl :: Bag Implication
wc_impl   = Bag Implication
implics1 Bag Implication -> Bag Implication -> Bag Implication
forall a. Bag a -> Bag a -> Bag a
`unionBags` Bag Implication
implics2
                    , wc_errors :: Bag DelayedError
wc_errors = Bag DelayedError
errs }) }
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 { Maybe Ct
sel <- TcS (Maybe Ct)
selectNextWorkItem
           ; case Maybe Ct
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 { WorkList
wl      <- TcS WorkList
getWorkList
       ; InertSet
inerts  <- TcS InertSet
getInertSet
       ; TcLevel
tclevel <- TcS TcLevel
getTcLevel
       ; String -> SDoc -> TcS ()
traceTcS String
"----------------------------- " SDoc
forall doc. IsOutput doc => doc
empty
       ; String -> SDoc -> TcS ()
traceTcS String
"Start solver pipeline {" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
                  [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"tclevel =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TcLevel -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcLevel
tclevel
                       , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"work item =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Ct -> SDoc
forall a. Outputable a => a -> SDoc
ppr Ct
workItem
                       , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"inerts =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> InertSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr InertSet
inerts
                       , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"rest of worklist =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> WorkList -> SDoc
forall a. Outputable a => a -> SDoc
ppr WorkList
wl ]
       ; TcS ()
bumpStepCountTcS    
       ; Ct -> TcS ()
solve Ct
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)
           ; StopOrContinue Void
res <- SolverStage Void -> TcS (StopOrContinue Void)
forall a. SolverStage a -> TcS (StopOrContinue a)
runSolverStage (Ct -> SolverStage Void
solveCt Ct
ct)
           ; String -> SDoc -> TcS ()
traceTcS String
"end solve }" (StopOrContinue Void -> SDoc
forall a. Outputable a => a -> SDoc
ppr StopOrContinue Void
res)
           ; case StopOrContinue Void
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 -> Xi
eq_rhs = Xi
rhs }))
  = CtEvidence -> EqRel -> Xi -> Xi -> SolverStage Void
solveEquality CtEvidence
ev EqRel
eq_rel (CanEqLHS -> Xi
canEqLHSType CanEqLHS
lhs) Xi
rhs
solveCt (CQuantCan (QCI { qci_ev :: QCInst -> CtEvidence
qci_ev = CtEvidence
ev, qci_pend_sc :: QCInst -> Int
qci_pend_sc = Int
pend_sc }))
  = do { CtEvidence
ev <- CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
         
         
         
       ; case Xi -> Pred
classifyPredType (CtEvidence -> Xi
ctEvPred CtEvidence
ev) of
           ForAllPred [TyVar]
tvs [Xi]
th Xi
p -> 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
$ CtEvidence
-> [TyVar] -> [Xi] -> Xi -> Int -> TcS (StopOrContinue Void)
solveForAll CtEvidence
ev [TyVar]
tvs [Xi]
th Xi
p 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) }
solveCt (CDictCan (DictCt { di_ev :: DictCt -> CtEvidence
di_ev = CtEvidence
ev, di_pend_sc :: DictCt -> Int
di_pend_sc = Int
pend_sc }))
  = do { CtEvidence
ev <- CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
         
         
         
       ; case Xi -> Pred
classifyPredType (CtEvidence -> Xi
ctEvPred CtEvidence
ev) of
           ClassPred Class
cls [Xi]
tys
             -> DictCt -> SolverStage Void
solveDict (DictCt { di_ev :: CtEvidence
di_ev = CtEvidence
ev, di_cls :: Class
di_cls = Class
cls
                                  , di_tys :: [Xi]
di_tys = [Xi]
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 Xi -> Pred
classifyPredType (CtEvidence -> Xi
ctEvPred CtEvidence
ev) of {
        EqPred EqRel
eq_rel Xi
ty1 Xi
ty2 -> CtEvidence -> EqRel -> Xi -> Xi -> SolverStage Void
solveEquality CtEvidence
ev EqRel
eq_rel Xi
ty1 Xi
ty2 ;
        Pred
_ ->
    
    do { CtEvidence
ev <- CtEvidence -> SolverStage CtEvidence
rewriteEvidence CtEvidence
ev
       ; let irred :: IrredCt
irred = IrredCt { ir_ev :: CtEvidence
ir_ev = CtEvidence
ev, ir_reason :: CtIrredReason
ir_reason = CtIrredReason
IrredShapeReason }
    
       ; case Xi -> Pred
classifyPredType (CtEvidence -> Xi
ctEvPred CtEvidence
ev) of
           ClassPred Class
cls [Xi]
tys     -> CtEvidence -> Class -> [Xi] -> SolverStage Void
solveDictNC CtEvidence
ev Class
cls [Xi]
tys
           ForAllPred [TyVar]
tvs [Xi]
th Xi
p   -> 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
$ CtEvidence -> [TyVar] -> [Xi] -> Xi -> TcS (StopOrContinue Void)
solveForAllNC CtEvidence
ev [TyVar]
tvs [Xi]
th Xi
p
           IrredPred {}          -> IrredCt -> SolverStage Void
solveIrred IrredCt
irred
           EqPred EqRel
eq_rel Xi
ty1 Xi
ty2 -> CtEvidence -> EqRel -> Xi -> Xi -> SolverStage Void
solveEquality CtEvidence
ev EqRel
eq_rel Xi
ty1 Xi
ty2
              
              
    }}
solveForAllNC :: CtEvidence -> [TcTyVar] -> TcThetaType -> TcPredType
              -> TcS (StopOrContinue Void)
solveForAllNC :: CtEvidence -> [TyVar] -> [Xi] -> Xi -> TcS (StopOrContinue Void)
solveForAllNC CtEvidence
ev [TyVar]
tvs [Xi]
theta Xi
pred
  | CtEvidence -> Bool
isGiven CtEvidence
ev  
  , Just (Class
cls, [Xi]
tys) <- Maybe (Class, [Xi])
cls_pred_tys_maybe
  = do { DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
       ; [Ct]
sc_cts <- Int -> CtEvidence -> [TyVar] -> [Xi] -> Class -> [Xi] -> TcS [Ct]
mkStrictSuperClasses (DynFlags -> Int
givensFuel DynFlags
dflags) CtEvidence
ev [TyVar]
tvs [Xi]
theta Class
cls [Xi]
tys
       
       ; Cts -> TcS ()
emitWork ([Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
sc_cts)
       ; CtEvidence
-> [TyVar] -> [Xi] -> Xi -> Int -> TcS (StopOrContinue Void)
solveForAll CtEvidence
ev [TyVar]
tvs [Xi]
theta Xi
pred Int
doNotExpand }
       
  | Bool
otherwise
  = do { DynFlags
dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
       ; let fuel :: Int
fuel | Just (Class
cls, [Xi]
_) <- Maybe (Class, [Xi])
cls_pred_tys_maybe
                  , Class -> Bool
classHasSCs Class
cls = DynFlags -> Int
qcsFuel DynFlags
dflags
                  
                  
                  
                  | Bool
otherwise = Int
doNotExpand
       ; CtEvidence
-> [TyVar] -> [Xi] -> Xi -> Int -> TcS (StopOrContinue Void)
solveForAll CtEvidence
ev [TyVar]
tvs [Xi]
theta Xi
pred Int
fuel }
  where
    cls_pred_tys_maybe :: Maybe (Class, [Xi])
cls_pred_tys_maybe = Xi -> Maybe (Class, [Xi])
getClassPredTys_maybe Xi
pred
solveForAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> ExpansionFuel
            -> TcS (StopOrContinue Void)
solveForAll :: CtEvidence
-> [TyVar] -> [Xi] -> Xi -> Int -> TcS (StopOrContinue Void)
solveForAll ev :: CtEvidence
ev@(CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest, ctev_rewriters :: CtEvidence -> RewriterSet
ctev_rewriters = RewriterSet
rewriters, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc })
            [TyVar]
tvs [Xi]
theta Xi
pred Int
_fuel
  = 
    RealSrcSpan
-> TcS (StopOrContinue Void) -> TcS (StopOrContinue Void)
forall a. RealSrcSpan -> TcS a -> TcS a
setSrcSpan (CtLocEnv -> RealSrcSpan
getCtLocEnvLoc (CtLocEnv -> RealSrcSpan) -> CtLocEnv -> RealSrcSpan
forall a b. (a -> b) -> a -> b
$ CtLoc -> CtLocEnv
ctLocEnv CtLoc
loc) (TcS (StopOrContinue Void) -> TcS (StopOrContinue Void))
-> TcS (StopOrContinue Void) -> TcS (StopOrContinue Void)
forall a b. (a -> b) -> a -> b
$
    
    
    
    do { let empty_subst :: Subst
empty_subst = InScopeSet -> Subst
mkEmptySubst (InScopeSet -> Subst) -> InScopeSet -> Subst
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet (VarSet -> InScopeSet) -> VarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$
                           [Xi] -> VarSet
tyCoVarsOfTypes (Xi
predXi -> [Xi] -> [Xi]
forall a. a -> [a] -> [a]
:[Xi]
theta) VarSet -> [TyVar] -> VarSet
`delVarSetList` [TyVar]
tvs
             is_qc :: ClsInstOrQC
is_qc = CtOrigin -> ClsInstOrQC
IsQC (CtLoc -> CtOrigin
ctLocOrigin CtLoc
loc)
         
         
         
       ; rec { SkolemInfo
skol_info <- SkolemInfoAnon -> TcS SkolemInfo
forall (m :: * -> *). MonadIO m => SkolemInfoAnon -> m SkolemInfo
mkSkolemInfo SkolemInfoAnon
skol_info_anon
             ; (Subst
subst, [TyVar]
skol_tvs) <- SkolemInfo -> Subst -> [TyVar] -> TcS (Subst, [TyVar])
tcInstSkolTyVarsX SkolemInfo
skol_info Subst
empty_subst [TyVar]
tvs
             ; let inst_pred :: Xi
inst_pred  = HasDebugCallStack => Subst -> Xi -> Xi
Subst -> Xi -> Xi
substTy    Subst
subst Xi
pred
                   inst_theta :: [Xi]
inst_theta = HasDebugCallStack => Subst -> [Xi] -> [Xi]
Subst -> [Xi] -> [Xi]
substTheta Subst
subst [Xi]
theta
                   skol_info_anon :: SkolemInfoAnon
skol_info_anon = ClsInstOrQC -> PatersonSize -> SkolemInfoAnon
InstSkol ClsInstOrQC
is_qc (Xi -> PatersonSize
get_size Xi
inst_pred) }
       ; [TyVar]
given_ev_vars <- (Xi -> TcS TyVar) -> [Xi] -> TcS [TyVar]
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 Xi -> TcS TyVar
newEvVar [Xi]
inst_theta
       ; (TcLevel
lvl, (TyVar
w_id, Cts
wanteds))
             <- SDoc -> TcS (TyVar, Cts) -> TcS (TcLevel, (TyVar, Cts))
forall a. SDoc -> TcS a -> TcS (TcLevel, a)
pushLevelNoWorkList (SkolemInfo -> SDoc
forall a. Outputable a => a -> SDoc
ppr SkolemInfo
skol_info) (TcS (TyVar, Cts) -> TcS (TcLevel, (TyVar, Cts)))
-> TcS (TyVar, Cts) -> TcS (TcLevel, (TyVar, Cts))
forall a b. (a -> b) -> a -> b
$
                do { let loc' :: CtLoc
loc' = CtLoc -> CtOrigin -> CtLoc
setCtLocOrigin CtLoc
loc (ClsInstOrQC -> NakedScFlag -> CtOrigin
ScOrigin ClsInstOrQC
is_qc NakedScFlag
NakedSc)
                         
                         
                         
                   ; CtEvidence
wanted_ev <- CtLoc -> RewriterSet -> Xi -> TcS CtEvidence
newWantedEvVarNC CtLoc
loc' RewriterSet
rewriters Xi
inst_pred
                   ; (TyVar, Cts) -> TcS (TyVar, Cts)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return ( CtEvidence -> TyVar
ctEvEvId CtEvidence
wanted_ev
                            , Ct -> Cts
forall a. a -> Bag a
unitBag (CtEvidence -> Ct
mkNonCanonical CtEvidence
wanted_ev)) }
      ; TcEvBinds
ev_binds <- TcLevel
-> SkolemInfoAnon -> [TyVar] -> [TyVar] -> Cts -> TcS TcEvBinds
emitImplicationTcS TcLevel
lvl SkolemInfoAnon
skol_info_anon [TyVar]
skol_tvs [TyVar]
given_ev_vars Cts
wanteds
      ; TcEvDest -> Bool -> EvTerm -> TcS ()
setWantedEvTerm TcEvDest
dest Bool
True (EvTerm -> TcS ()) -> EvTerm -> TcS ()
forall a b. (a -> b) -> a -> b
$
        EvFun { et_tvs :: [TyVar]
et_tvs = [TyVar]
skol_tvs, et_given :: [TyVar]
et_given = [TyVar]
given_ev_vars
              , et_binds :: TcEvBinds
et_binds = TcEvBinds
ev_binds, et_body :: TyVar
et_body = TyVar
w_id }
      ; CtEvidence -> String -> TcS (StopOrContinue Void)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Wanted forall-constraint" }
  where
    
    
    get_size :: Xi -> PatersonSize
get_size Xi
pred = case Xi -> Pred
classifyPredType Xi
pred of
                      ClassPred Class
cls [Xi]
tys -> Class -> [Xi] -> PatersonSize
pSizeClassPred Class
cls [Xi]
tys
                      Pred
_                 -> Xi -> PatersonSize
pSizeType Xi
pred
 
solveForAll ev :: CtEvidence
ev@(CtGiven {}) [TyVar]
tvs [Xi]
_theta Xi
pred Int
fuel
  = do { QCInst -> TcS ()
addInertForAll QCInst
qci
       ; CtEvidence -> String -> TcS (StopOrContinue Void)
forall a. CtEvidence -> String -> TcS (StopOrContinue a)
stopWith CtEvidence
ev String
"Given forall-constraint" }
  where
    qci :: QCInst
qci = QCI { qci_ev :: CtEvidence
qci_ev = CtEvidence
ev, qci_tvs :: [TyVar]
qci_tvs = [TyVar]
tvs
              , qci_pred :: Xi
qci_pred = Xi
pred, qci_pend_sc :: Int
qci_pend_sc = Int
fuel }
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)
               ; (Reduction
redn, RewriterSet
rewriters) <- CtEvidence -> Xi -> TcS (Reduction, RewriterSet)
rewrite CtEvidence
ev (CtEvidence -> Xi
ctEvPred CtEvidence
ev)
               ; CtEvidence
-> Reduction -> RewriterSet -> TcS (StopOrContinue CtEvidence)
finish_rewrite CtEvidence
ev Reduction
redn RewriterSet
rewriters }
finish_rewrite :: CtEvidence   
               -> Reduction    
               -> RewriterSet  
                               
               -> TcS (StopOrContinue CtEvidence)
finish_rewrite :: CtEvidence
-> Reduction -> RewriterSet -> TcS (StopOrContinue CtEvidence)
finish_rewrite CtEvidence
old_ev (Reduction Coercion
co Xi
new_pred) RewriterSet
rewriters
  | Coercion -> Bool
isReflCo Coercion
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 -> Xi -> CtEvidence
CtEvidence -> Xi -> CtEvidence
setCtEvPredType CtEvidence
old_ev Xi
new_pred)
finish_rewrite ev :: CtEvidence
ev@(CtGiven { ctev_evar :: CtEvidence -> TyVar
ctev_evar = TyVar
old_evar, ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc })
                (Reduction Coercion
co Xi
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 { CtEvidence
new_ev <- CtLoc -> (Xi, EvTerm) -> TcS CtEvidence
newGivenEvVar CtLoc
loc (Xi
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 -> Coercion -> EvTerm
mkEvCast (TyVar -> EvExpr
evId TyVar
old_evar)
                (Role -> Role -> Coercion -> Coercion
downgradeRole Role
Representational (CtEvidence -> Role
ctEvRole CtEvidence
ev) Coercion
co)
finish_rewrite ev :: CtEvidence
ev@(CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest
                             , ctev_loc :: CtEvidence -> CtLoc
ctev_loc = CtLoc
loc
                             , ctev_rewriters :: CtEvidence -> RewriterSet
ctev_rewriters = RewriterSet
rewriters })
                (Reduction Coercion
co Xi
new_pred) RewriterSet
new_rewriters
  = do { MaybeNew
mb_new_ev <- CtLoc -> RewriterSet -> Xi -> TcS MaybeNew
newWanted CtLoc
loc RewriterSet
rewriters' Xi
new_pred
       ; Bool -> TcS ()
forall (m :: * -> *). (HasCallStack, Applicative m) => Bool -> m ()
massert (Coercion -> Role
coercionRole Coercion
co Role -> Role -> Bool
forall a. Eq a => a -> a -> Bool
== CtEvidence -> Role
ctEvRole CtEvidence
ev)
       ; TcEvDest -> Bool -> EvTerm -> TcS ()
setWantedEvTerm TcEvDest
dest Bool
True (EvTerm -> TcS ()) -> EvTerm -> TcS ()
forall a b. (a -> b) -> a -> b
$
            EvExpr -> Coercion -> EvTerm
mkEvCast (MaybeNew -> EvExpr
getEvExpr MaybeNew
mb_new_ev)
                     (Role -> Role -> Coercion -> Coercion
downgradeRole Role
Representational (CtEvidence -> Role
ctEvRole CtEvidence
ev) (Coercion -> Coercion
mkSymCo Coercion
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" }
  where
    rewriters' :: RewriterSet
rewriters' = RewriterSet
rewriters RewriterSet -> RewriterSet -> RewriterSet
forall a. Semigroup a => a -> a -> a
S.<> RewriterSet
new_rewriters
runTcPluginsGiven :: TcS [Ct]
runTcPluginsGiven :: TcS [Ct]
runTcPluginsGiven
  = do { [TcPluginSolver]
solvers <- TcS [TcPluginSolver]
getTcPluginSolvers
       ; if [TcPluginSolver] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcPluginSolver]
solvers then [Ct] -> TcS [Ct]
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return [] else
    do { [Ct]
givens <- TcS [Ct]
getInertGivens
       ; if [Ct] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Ct]
givens then [Ct] -> TcS [Ct]
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return [] else
    do { String -> SDoc -> TcS ()
traceTcS String
"runTcPluginsGiven {" ([Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Ct]
givens)
       ; TcPluginProgress
p <- [TcPluginSolver] -> SplitCts -> TcS TcPluginProgress
runTcPluginSolvers [TcPluginSolver]
solvers ([Ct]
givens,[])
       ; let ([Ct]
solved_givens, [(EvTerm, Ct)]
_) = TcPluginProgress -> ([Ct], [(EvTerm, Ct)])
pluginSolvedCts TcPluginProgress
p
             insols :: [IrredCt]
insols             = (Ct -> IrredCt) -> [Ct] -> [IrredCt]
forall a b. (a -> b) -> [a] -> [b]
map (CtIrredReason -> Ct -> IrredCt
ctIrredCt CtIrredReason
PluginReason) (TcPluginProgress -> [Ct]
pluginBadCts TcPluginProgress
p)
       ; (InertCans -> InertCans) -> TcS ()
updInertCans ([Ct] -> InertCans -> InertCans
removeInertCts [Ct]
solved_givens (InertCans -> InertCans)
-> (InertCans -> InertCans) -> InertCans -> InertCans
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                       (InertIrreds -> InertIrreds) -> InertCans -> InertCans
updIrreds ([IrredCt] -> InertIrreds -> InertIrreds
addIrreds [IrredCt]
insols) )
       ; String -> SDoc -> TcS ()
traceTcS String
"runTcPluginsGiven }" (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
         [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"solved_givens:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Ct]
solved_givens
              , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"insols:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [IrredCt] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [IrredCt]
insols
              , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"new:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TcPluginProgress -> [Ct]
pluginNewCts TcPluginProgress
p) ]
       ; [Ct] -> TcS [Ct]
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (TcPluginProgress -> [Ct]
pluginNewCts TcPluginProgress
p) } } }
runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints)
runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints)
runTcPluginsWanted wc :: WantedConstraints
wc@(WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples1 })
  | Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag Cts
simples1
  = (Bool, WantedConstraints) -> TcS (Bool, WantedConstraints)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, WantedConstraints
wc)
  | Bool
otherwise
  = do { [TcPluginSolver]
solvers <- TcS [TcPluginSolver]
getTcPluginSolvers
       ; if [TcPluginSolver] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcPluginSolver]
solvers then (Bool, WantedConstraints) -> TcS (Bool, WantedConstraints)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, WantedConstraints
wc) else
    do { [Ct]
given <- TcS [Ct]
getInertGivens
       ; Cts
wanted <- Cts -> TcS Cts
zonkSimples Cts
simples1    
       ; String -> SDoc -> TcS ()
traceTcS String
"Running plugins (" ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Given:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Ct]
given
                                            , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Watned:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Cts -> SDoc
forall a. Outputable a => a -> SDoc
ppr Cts
wanted ])
       ; TcPluginProgress
p <- [TcPluginSolver] -> SplitCts -> TcS TcPluginProgress
runTcPluginSolvers [TcPluginSolver]
solvers ([Ct]
given, Cts -> [Ct]
forall a. Bag a -> [a]
bagToList Cts
wanted)
       ; let ([Ct]
_, [(EvTerm, Ct)]
solved_wanted)   = TcPluginProgress -> ([Ct], [(EvTerm, Ct)])
pluginSolvedCts TcPluginProgress
p
             ([Ct]
_, [Ct]
unsolved_wanted) = TcPluginProgress -> SplitCts
pluginInputCts TcPluginProgress
p
             new_wanted :: [Ct]
new_wanted     = TcPluginProgress -> [Ct]
pluginNewCts TcPluginProgress
p
             insols :: [Ct]
insols         = TcPluginProgress -> [Ct]
pluginBadCts TcPluginProgress
p
             all_new_wanted :: Cts
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
       ; ((EvTerm, Ct) -> TcS ()) -> [(EvTerm, Ct)] -> TcS ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (EvTerm, Ct) -> TcS ()
setEv [(EvTerm, Ct)]
solved_wanted
       ; String -> SDoc -> TcS ()
traceTcS String
"Finished plugins }" ([Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Ct]
new_wanted)
       ; (Bool, WantedConstraints) -> TcS (Bool, WantedConstraints)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return ( [Ct] -> Bool
forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull (TcPluginProgress -> [Ct]
pluginNewCts TcPluginProgress
p)
                , WantedConstraints
wc { wc_simple = 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 { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest } -> TcEvDest -> Bool -> EvTerm -> TcS ()
setWantedEvTerm TcEvDest
dest Bool
True 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 { TcGblEnv
tcg_env <- TcS TcGblEnv
getGblEnv; [TcPluginSolver] -> TcS [TcPluginSolver]
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (TcGblEnv -> [TcPluginSolver]
tcg_tc_plugin_solvers TcGblEnv
tcg_env) }
runTcPluginSolvers :: [TcPluginSolver] -> SplitCts -> TcS TcPluginProgress
runTcPluginSolvers :: [TcPluginSolver] -> SplitCts -> TcS TcPluginProgress
runTcPluginSolvers [TcPluginSolver]
solvers SplitCts
all_cts
  = do { EvBindsVar
ev_binds_var <- TcS EvBindsVar
getTcEvBindsVar
       ; (TcPluginProgress -> TcPluginSolver -> TcS TcPluginProgress)
-> TcPluginProgress -> [TcPluginSolver] -> TcS TcPluginProgress
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (EvBindsVar
-> TcPluginProgress -> TcPluginSolver -> TcS TcPluginProgress
do_plugin EvBindsVar
ev_binds_var) TcPluginProgress
initialProgress [TcPluginSolver]
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
        TcPluginSolveResult
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))
        TcPluginProgress -> TcS TcPluginProgress
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (TcPluginProgress -> TcS TcPluginProgress)
-> TcPluginProgress -> TcS TcPluginProgress
forall a b. (a -> b) -> a -> b
$ TcPluginProgress -> TcPluginSolveResult -> TcPluginProgress
progress TcPluginProgress
p TcPluginSolveResult
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 -> Xi
ctPred Ct
c HasDebugCallStack => Xi -> Xi -> Bool
Xi -> Xi -> Bool
`tcEqType` Ct -> Xi
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)