{-# LANGUAGE MultiWayIf, RecursiveDo, TupleSections #-}
module GHC.Tc.Solver(
InferMode(..), simplifyInfer, findInferredDiff,
growThetaTyVars,
simplifyAmbiguityCheck,
simplifyDefault,
simplifyTop, simplifyTopImplic,
simplifyInteractive,
solveEqualities,
pushLevelAndSolveEqualities, pushLevelAndSolveEqualitiesX,
reportUnsolvedEqualities,
simplifyWantedsTcM,
tcCheckGivens,
tcCheckWanteds,
tcNormalise,
captureTopConstraints,
simplifyTopWanteds,
promoteTyVarSet, simplifyAndEmitFlatConstraints,
solveWanteds,
approximateWC
) where
import GHC.Prelude
import GHC.Tc.Errors
import GHC.Tc.Errors.Types
import GHC.Tc.Types.Evidence
import GHC.Tc.Solver.Solve ( solveSimpleGivens, solveSimpleWanteds )
import GHC.Tc.Solver.Dict ( makeSuperClasses, solveCallStack )
import GHC.Tc.Solver.Rewrite ( rewriteType )
import GHC.Tc.Utils.Unify
import GHC.Tc.Utils.TcMType as TcM
import GHC.Tc.Utils.Monad as TcM
import GHC.Tc.Zonk.TcType as TcM
import GHC.Tc.Solver.InertSet
import GHC.Tc.Solver.Monad as TcS
import GHC.Tc.Types.Constraint
import GHC.Tc.Types.CtLoc( mkGivenLoc )
import GHC.Tc.Instance.FunDeps
import GHC.Tc.Types.Origin
import GHC.Tc.Utils.TcType
import GHC.Core.Class
import GHC.Core.Reduction( Reduction, reductionCoercion )
import GHC.Core
import GHC.Core.DataCon
import GHC.Core.Make
import GHC.Core.Coercion( mkNomReflCo, isReflCo )
import GHC.Core.Unify ( tcMatchTyKis )
import GHC.Core.Predicate
import GHC.Core.Type
import GHC.Core.Ppr
import GHC.Core.TyCon ( TyCon, TyConBinder, isTypeFamilyTyCon )
import GHC.Types.Name
import GHC.Types.DefaultEnv ( ClassDefaults (..), defaultList )
import GHC.Types.Unique.Set
import GHC.Types.Id
import GHC.Builtin.Utils
import GHC.Builtin.Names
import GHC.Builtin.Types
import GHC.Types.TyThing ( MonadThings(lookupId) )
import GHC.Types.Var
import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.Basic
import GHC.Types.Id.Make ( unboxedUnitExpr )
import GHC.Types.Error
import GHC.Driver.DynFlags
import GHC.Unit.Module ( getModule )
import GHC.Utils.Misc
import GHC.Utils.Panic
import GHC.Utils.Outputable
import GHC.Data.FastString
import GHC.Data.List.SetOps
import GHC.Data.Bag
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Control.Monad.Trans.Class ( lift )
import Control.Monad.Trans.State.Strict ( StateT(runStateT), put )
import Data.Foldable ( toList, traverse_ )
import Data.List ( partition, intersect )
import Data.List.NonEmpty ( NonEmpty(..), nonEmpty )
import qualified Data.List.NonEmpty as NE
import GHC.Data.Maybe ( isJust, mapMaybe, catMaybes )
import Data.Monoid ( First(..) )
captureTopConstraints :: TcM a -> TcM (a, WantedConstraints)
captureTopConstraints :: forall a. TcM a -> TcM (a, WantedConstraints)
captureTopConstraints TcM a
thing_inside
= do { static_wc_var <- WantedConstraints
-> IOEnv (Env TcGblEnv TcLclEnv) (TcRef WantedConstraints)
forall (m :: * -> *) a. MonadIO m => a -> m (TcRef a)
TcM.newTcRef WantedConstraints
emptyWC ;
; (mb_res, lie) <- TcM.updGblEnv (\TcGblEnv
env -> TcGblEnv
env { tcg_static_wc = static_wc_var } ) $
TcM.tryCaptureConstraints thing_inside
; stWC <- TcM.readTcRef static_wc_var
; case mb_res of
Just a
res -> (a, WantedConstraints)
-> IOEnv (Env TcGblEnv TcLclEnv) (a, WantedConstraints)
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
res, WantedConstraints
lie WantedConstraints -> WantedConstraints -> WantedConstraints
`andWC` WantedConstraints
stWC)
Maybe a
Nothing -> do { _ <- WantedConstraints -> TcM (Bag EvBind)
simplifyTop WantedConstraints
lie; failM } }
simplifyTopImplic :: Bag Implication -> TcM ()
simplifyTopImplic :: Bag Implication -> TcM ()
simplifyTopImplic Bag Implication
implics
= do { empty_binds <- WantedConstraints -> TcM (Bag EvBind)
simplifyTop (Bag Implication -> WantedConstraints
mkImplicWC Bag Implication
implics)
; massertPpr (isEmptyBag empty_binds) (ppr empty_binds)
; return () }
simplifyTop :: WantedConstraints -> TcM (Bag EvBind)
simplifyTop :: WantedConstraints -> TcM (Bag EvBind)
simplifyTop WantedConstraints
wanteds
= do { String -> SDoc -> TcM ()
traceTc String
"simplifyTop {" (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"wanted = " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wanteds
; ((final_wc, unsafe_ol), binds1) <- TcS (WantedConstraints, Bag DictCt)
-> TcM ((WantedConstraints, Bag DictCt), EvBindMap)
forall a. TcS a -> TcM (a, EvBindMap)
runTcS (TcS (WantedConstraints, Bag DictCt)
-> TcM ((WantedConstraints, Bag DictCt), EvBindMap))
-> TcS (WantedConstraints, Bag DictCt)
-> TcM ((WantedConstraints, Bag DictCt), EvBindMap)
forall a b. (a -> b) -> a -> b
$
do { final_wc <- WantedConstraints -> TcS WantedConstraints
simplifyTopWanteds WantedConstraints
wanteds
; unsafe_ol <- getSafeOverlapFailures
; return (final_wc, unsafe_ol) }
; traceTc "End simplifyTop }" empty
; binds2 <- reportUnsolved final_wc
; traceTc "reportUnsolved (unsafe overlapping) {" empty
; unless (isEmptyBag unsafe_ol) $ do {
; errs_var <- getErrsVar
; saved_msg <- TcM.readTcRef errs_var
; TcM.writeTcRef errs_var emptyMessages
; warnAllUnsolved $ emptyWC { wc_simple = fmap CDictCan unsafe_ol }
; whyUnsafe <- getWarningMessages <$> TcM.readTcRef errs_var
; TcM.writeTcRef errs_var saved_msg
; recordUnsafeInfer (mkMessages whyUnsafe)
}
; traceTc "reportUnsolved (unsafe overlapping) }" empty
; return (evBindMapBinds binds1 `unionBags` binds2) }
pushLevelAndSolveEqualities :: SkolemInfoAnon -> [TyConBinder] -> TcM a -> TcM a
pushLevelAndSolveEqualities :: forall a. SkolemInfoAnon -> [TyConBinder] -> TcM a -> TcM a
pushLevelAndSolveEqualities SkolemInfoAnon
skol_info_anon [TyConBinder]
tcbs TcM a
thing_inside
= do { (tclvl, wanted, res) <- String -> TcM a -> TcM (TcLevel, WantedConstraints, a)
forall a. String -> TcM a -> TcM (TcLevel, WantedConstraints, a)
pushLevelAndSolveEqualitiesX
String
"pushLevelAndSolveEqualities" TcM a
thing_inside
; report_unsolved_equalities skol_info_anon (binderVars tcbs) tclvl wanted
; return res }
pushLevelAndSolveEqualitiesX :: String -> TcM a
-> TcM (TcLevel, WantedConstraints, a)
pushLevelAndSolveEqualitiesX :: forall a. String -> TcM a -> TcM (TcLevel, WantedConstraints, a)
pushLevelAndSolveEqualitiesX String
callsite TcM a
thing_inside
= do { String -> SDoc -> TcM ()
traceTc String
"pushLevelAndSolveEqualitiesX {" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Called from" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
callsite)
; (tclvl, (wanted, res))
<- TcM (WantedConstraints, a) -> TcM (TcLevel, (WantedConstraints, a))
forall a. TcM a -> TcM (TcLevel, a)
pushTcLevelM (TcM (WantedConstraints, a)
-> TcM (TcLevel, (WantedConstraints, a)))
-> TcM (WantedConstraints, a)
-> TcM (TcLevel, (WantedConstraints, a))
forall a b. (a -> b) -> a -> b
$
do { (res, wanted) <- TcM a -> TcM (a, WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints TcM a
thing_inside
; wanted <- runTcSEqualities (simplifyTopWanteds wanted)
; return (wanted,res) }
; traceTc "pushLevelAndSolveEqualities }" (vcat [ text "Residual:" <+> ppr wanted
, text "Level:" <+> ppr tclvl ])
; return (tclvl, wanted, res) }
solveEqualities :: String -> TcM a -> TcM a
solveEqualities :: forall a. String -> TcM a -> TcM a
solveEqualities String
callsite TcM a
thing_inside
= do { String -> SDoc -> TcM ()
traceTc String
"solveEqualities {" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Called from" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
callsite)
; (res, wanted) <- TcM a -> TcM (a, WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints TcM a
thing_inside
; simplifyAndEmitFlatConstraints wanted
; traceTc "solveEqualities }" empty
; return res }
simplifyAndEmitFlatConstraints :: WantedConstraints -> TcM ()
simplifyAndEmitFlatConstraints :: WantedConstraints -> TcM ()
simplifyAndEmitFlatConstraints WantedConstraints
wanted
= do {
wanted <- TcS WantedConstraints
-> IOEnv (Env TcGblEnv TcLclEnv) WantedConstraints
forall a. TcS a -> TcM a
runTcSEqualities (WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
wanted)
; wanted <- TcM.liftZonkM $ TcM.zonkWC wanted
; traceTc "emitFlatConstraints {" (ppr wanted)
; case floatKindEqualities wanted of
Maybe (Cts, Bag DelayedError)
Nothing -> do { String -> SDoc -> TcM ()
traceTc String
"emitFlatConstraints } failing" (WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wanted)
; tclvl <- TcM TcLevel
TcM.getTcLevel
; implic <- buildTvImplication unkSkolAnon [] (pushTcLevel tclvl) wanted
; emitImplication implic
; failM }
Just (Cts
simples, Bag DelayedError
errs)
-> do { _ <- HasDebugCallStack => VarSet -> TcM Bool
VarSet -> TcM Bool
promoteTyVarSet (Cts -> VarSet
tyCoVarsOfCts Cts
simples)
; traceTc "emitFlatConstraints }" $
vcat [ text "simples:" <+> ppr simples
, text "errs: " <+> ppr errs ]
; emitDelayedErrors errs
; emitSimples simples } }
floatKindEqualities :: WantedConstraints -> Maybe (Bag Ct, Bag DelayedError)
floatKindEqualities :: WantedConstraints -> Maybe (Cts, Bag DelayedError)
floatKindEqualities WantedConstraints
wc = VarSet -> WantedConstraints -> Maybe (Cts, Bag DelayedError)
float_wc VarSet
emptyVarSet WantedConstraints
wc
where
float_wc :: TcTyCoVarSet -> WantedConstraints -> Maybe (Bag Ct, Bag DelayedError)
float_wc :: VarSet -> WantedConstraints -> Maybe (Cts, Bag DelayedError)
float_wc VarSet
trapping_tvs (WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples
, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics
, wc_errors :: WantedConstraints -> Bag DelayedError
wc_errors = Bag DelayedError
errs })
| (Ct -> Bool) -> Cts -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Ct -> Bool
is_floatable Cts
simples
= do { (inner_simples, inner_errs)
<- (Implication -> Maybe (Cts, Bag DelayedError))
-> Bag Implication -> Maybe (Cts, Bag DelayedError)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m (Bag b, Bag c)) -> Bag a -> m (Bag b, Bag c)
flatMapBagPairM (VarSet -> Implication -> Maybe (Cts, Bag DelayedError)
float_implic VarSet
trapping_tvs) Bag Implication
implics
; return ( simples `unionBags` inner_simples
, errs `unionBags` inner_errs) }
| Bool
otherwise
= Maybe (Cts, Bag DelayedError)
forall a. Maybe a
Nothing
where
is_floatable :: Ct -> Bool
is_floatable Ct
ct
| Ct -> Bool
insolubleCt Ct
ct = Bool
False
| Bool
otherwise = Ct -> VarSet
tyCoVarsOfCt Ct
ct VarSet -> VarSet -> Bool
`disjointVarSet` VarSet
trapping_tvs
float_implic :: TcTyCoVarSet -> Implication -> Maybe (Bag Ct, Bag DelayedError)
float_implic :: VarSet -> Implication -> Maybe (Cts, Bag DelayedError)
float_implic VarSet
trapping_tvs (Implic { ic_wanted :: Implication -> WantedConstraints
ic_wanted = WantedConstraints
wanted, ic_given_eqs :: Implication -> HasGivenEqs
ic_given_eqs = HasGivenEqs
given_eqs
, ic_skols :: Implication -> [TcTyVar]
ic_skols = [TcTyVar]
skols, ic_status :: Implication -> ImplicStatus
ic_status = ImplicStatus
status })
| ImplicStatus -> Bool
isInsolubleStatus ImplicStatus
status
= Maybe (Cts, Bag DelayedError)
forall a. Maybe a
Nothing
| Bool
otherwise
= do { (simples, holes) <- VarSet -> WantedConstraints -> Maybe (Cts, Bag DelayedError)
float_wc VarSet
new_trapping_tvs WantedConstraints
wanted
; when (not (isEmptyBag simples) && given_eqs == MaybeGivenEqs) $
Nothing
; return (simples, holes) }
where
new_trapping_tvs :: VarSet
new_trapping_tvs = VarSet
trapping_tvs VarSet -> [TcTyVar] -> VarSet
`extendVarSetList` [TcTyVar]
skols
reportUnsolvedEqualities :: SkolemInfo -> [TcTyVar] -> TcLevel
-> WantedConstraints -> TcM ()
reportUnsolvedEqualities :: SkolemInfo -> [TcTyVar] -> TcLevel -> WantedConstraints -> TcM ()
reportUnsolvedEqualities SkolemInfo
skol_info [TcTyVar]
skol_tvs TcLevel
tclvl WantedConstraints
wanted
= SkolemInfoAnon
-> [TcTyVar] -> TcLevel -> WantedConstraints -> TcM ()
report_unsolved_equalities (SkolemInfo -> SkolemInfoAnon
getSkolemInfo SkolemInfo
skol_info) [TcTyVar]
skol_tvs TcLevel
tclvl WantedConstraints
wanted
report_unsolved_equalities :: SkolemInfoAnon -> [TcTyVar] -> TcLevel
-> WantedConstraints -> TcM ()
report_unsolved_equalities :: SkolemInfoAnon
-> [TcTyVar] -> TcLevel -> WantedConstraints -> TcM ()
report_unsolved_equalities SkolemInfoAnon
skol_info_anon [TcTyVar]
skol_tvs TcLevel
tclvl WantedConstraints
wanted
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanted
= () -> TcM ()
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= TcM () -> TcM ()
forall r. TcM r -> TcM r
checkNoErrs (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
do { implic <- SkolemInfoAnon
-> [TcTyVar] -> TcLevel -> WantedConstraints -> TcM Implication
buildTvImplication SkolemInfoAnon
skol_info_anon [TcTyVar]
skol_tvs TcLevel
tclvl WantedConstraints
wanted
; reportAllUnsolved (mkImplicWC (unitBag implic)) }
simplifyTopWanteds :: WantedConstraints -> TcS WantedConstraints
simplifyTopWanteds :: WantedConstraints -> TcS WantedConstraints
simplifyTopWanteds WantedConstraints
wanteds
= do {
wc_first_go <- TcS WantedConstraints -> TcS WantedConstraints
forall a. TcS a -> TcS a
nestTcS (WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
wanteds)
; tryDefaulting wc_first_go }
tryDefaulting :: WantedConstraints -> TcS WantedConstraints
tryDefaulting :: WantedConstraints -> TcS WantedConstraints
tryDefaulting WantedConstraints
wc
= do { dflags <- TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; traceTcS "tryDefaulting:before" (ppr wc)
; wc1 <- tryTyVarDefaulting dflags wc
; wc2 <- tryConstraintDefaulting wc1
; wc3 <- tryTypeClassDefaulting wc2
; wc4 <- tryUnsatisfiableGivens wc3
; traceTcS "tryDefaulting:after" (ppr wc4)
; return wc4 }
solveAgainIf :: Bool -> WantedConstraints -> TcS WantedConstraints
solveAgainIf :: Bool -> WantedConstraints -> TcS WantedConstraints
solveAgainIf Bool
False WantedConstraints
wc = WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
solveAgainIf Bool
True WantedConstraints
wc = TcS WantedConstraints -> TcS WantedConstraints
forall a. TcS a -> TcS a
nestTcS (WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
wc)
tryTyVarDefaulting :: DynFlags -> WantedConstraints -> TcS WantedConstraints
tryTyVarDefaulting :: DynFlags -> WantedConstraints -> TcS WantedConstraints
tryTyVarDefaulting DynFlags
dflags WantedConstraints
wc
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wc
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
| WantedConstraints -> Bool
insolubleWC WantedConstraints
wc
, GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_PrintExplicitRuntimeReps DynFlags
dflags
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
| Bool
otherwise
= do {
; free_tvs <- [TcTyVar] -> TcS [TcTyVar]
TcS.zonkTyCoVarsAndFVList (WantedConstraints -> [TcTyVar]
tyCoVarsOfWCList WantedConstraints
wc)
; let defaultable_tvs = (TcTyVar -> Bool) -> [TcTyVar] -> [TcTyVar]
forall a. (a -> Bool) -> [a] -> [a]
filter TcTyVar -> Bool
can_default [TcTyVar]
free_tvs
can_default TcTyVar
tv
= TcTyVar -> Bool
isTyVar TcTyVar
tv
Bool -> Bool -> Bool
&& TcTyVar -> Bool
isMetaTyVar TcTyVar
tv
Bool -> Bool -> Bool
&& Bool -> Bool
not (TcTyVar
tv TcTyVar -> VarSet -> Bool
`elemVarSet` WantedConstraints -> VarSet
nonDefaultableTyVarsOfWC WantedConstraints
wc)
; unification_s <- mapM defaultTyVarTcS defaultable_tvs
; solveAgainIf (or unification_s) wc }
tryUnsatisfiableGivens :: WantedConstraints -> TcS WantedConstraints
tryUnsatisfiableGivens :: WantedConstraints -> TcS WantedConstraints
tryUnsatisfiableGivens WantedConstraints
wc =
do { (final_wc, did_work) <- (StateT Bool TcS WantedConstraints
-> Bool -> TcS (WantedConstraints, Bool)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
`runStateT` Bool
False) (StateT Bool TcS WantedConstraints
-> TcS (WantedConstraints, Bool))
-> StateT Bool TcS WantedConstraints
-> TcS (WantedConstraints, Bool)
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> StateT Bool TcS WantedConstraints
go_wc WantedConstraints
wc
; solveAgainIf did_work final_wc }
where
go_wc :: WantedConstraints -> StateT Bool TcS WantedConstraints
go_wc (WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
wtds, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
impls, wc_errors :: WantedConstraints -> Bag DelayedError
wc_errors = Bag DelayedError
errs })
= do impls' <- (Implication -> StateT Bool TcS (Maybe Implication))
-> Bag Implication -> StateT Bool TcS (Bag Implication)
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> Bag a -> m (Bag b)
mapMaybeBagM Implication -> StateT Bool TcS (Maybe Implication)
go_impl Bag Implication
impls
return $ WC { wc_simple = wtds, wc_impl = impls', wc_errors = errs }
go_impl :: Implication -> StateT Bool TcS (Maybe Implication)
go_impl Implication
impl
| ImplicStatus -> Bool
isSolvedStatus (Implication -> ImplicStatus
ic_status Implication
impl)
= Maybe Implication -> StateT Bool TcS (Maybe Implication)
forall a. a -> StateT Bool TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Implication -> StateT Bool TcS (Maybe Implication))
-> Maybe Implication -> StateT Bool TcS (Maybe Implication)
forall a b. (a -> b) -> a -> b
$ Implication -> Maybe Implication
forall a. a -> Maybe a
Just Implication
impl
| (TcTyVar, TcType)
unsat_given:[(TcTyVar, TcType)]
_ <- (TcTyVar -> Maybe (TcTyVar, TcType))
-> [TcTyVar] -> [(TcTyVar, TcType)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe TcTyVar -> Maybe (TcTyVar, TcType)
unsatisfiableEv_maybe (Implication -> [TcTyVar]
ic_given Implication
impl)
= do { Bool -> StateT Bool TcS ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put Bool
True
; TcS (Maybe Implication) -> StateT Bool TcS (Maybe Implication)
forall (m :: * -> *) a. Monad m => m a -> StateT Bool m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TcS (Maybe Implication) -> StateT Bool TcS (Maybe Implication))
-> TcS (Maybe Implication) -> StateT Bool TcS (Maybe Implication)
forall a b. (a -> b) -> a -> b
$ (TcTyVar, TcType) -> Implication -> TcS (Maybe Implication)
solveImplicationUsingUnsatGiven (TcTyVar, TcType)
unsat_given Implication
impl }
| Bool
otherwise
= do { wcs' <- WantedConstraints -> StateT Bool TcS WantedConstraints
go_wc (Implication -> WantedConstraints
ic_wanted Implication
impl)
; lift $ setImplicationStatus $ impl { ic_wanted = wcs' } }
unsatisfiableEv_maybe :: EvVar -> Maybe (EvVar, Type)
unsatisfiableEv_maybe :: TcTyVar -> Maybe (TcTyVar, TcType)
unsatisfiableEv_maybe TcTyVar
v = (TcTyVar
v,) (TcType -> (TcTyVar, TcType))
-> Maybe TcType -> Maybe (TcTyVar, TcType)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TcType -> Maybe TcType
isUnsatisfiableCt_maybe (TcTyVar -> TcType
idType TcTyVar
v)
solveImplicationUsingUnsatGiven :: (EvVar, Type) -> Implication -> TcS (Maybe Implication)
solveImplicationUsingUnsatGiven :: (TcTyVar, TcType) -> Implication -> TcS (Maybe Implication)
solveImplicationUsingUnsatGiven
unsat_given :: (TcTyVar, TcType)
unsat_given@(TcTyVar
given_ev,TcType
_)
impl :: Implication
impl@(Implic { ic_wanted :: Implication -> WantedConstraints
ic_wanted = WantedConstraints
wtd, ic_tclvl :: Implication -> TcLevel
ic_tclvl = TcLevel
tclvl, ic_binds :: Implication -> EvBindsVar
ic_binds = EvBindsVar
ev_binds_var, ic_need_inner :: Implication -> VarSet
ic_need_inner = VarSet
inner })
| EvBindsVar -> Bool
isCoEvBindsVar EvBindsVar
ev_binds_var
= Maybe Implication -> TcS (Maybe Implication)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Implication -> TcS (Maybe Implication))
-> Maybe Implication -> TcS (Maybe Implication)
forall a b. (a -> b) -> a -> b
$ Implication -> Maybe Implication
forall a. a -> Maybe a
Just Implication
impl
| Bool
otherwise
= do { wcs <- EvBindsVar
-> TcLevel -> TcS WantedConstraints -> TcS WantedConstraints
forall a. EvBindsVar -> TcLevel -> TcS a -> TcS a
nestImplicTcS EvBindsVar
ev_binds_var TcLevel
tclvl (TcS WantedConstraints -> TcS WantedConstraints)
-> TcS WantedConstraints -> TcS WantedConstraints
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> TcS WantedConstraints
go_wc WantedConstraints
wtd
; setImplicationStatus $
impl { ic_wanted = wcs
, ic_need_inner = inner `extendVarSet` given_ev } }
where
go_wc :: WantedConstraints -> TcS WantedConstraints
go_wc :: WantedConstraints -> TcS WantedConstraints
go_wc wc :: WantedConstraints
wc@(WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
wtds, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
impls })
= do { (Ct -> TcS ()) -> Cts -> TcS ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Bag a -> m ()
mapBagM_ Ct -> TcS ()
go_simple Cts
wtds
; impls <- (Implication -> TcS (Maybe Implication))
-> Bag Implication -> TcS (Bag Implication)
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> Bag a -> m (Bag b)
mapMaybeBagM ((TcTyVar, TcType) -> Implication -> TcS (Maybe Implication)
solveImplicationUsingUnsatGiven (TcTyVar, TcType)
unsat_given) Bag Implication
impls
; return $ wc { wc_simple = emptyBag, wc_impl = impls } }
go_simple :: Ct -> TcS ()
go_simple :: Ct -> TcS ()
go_simple Ct
ct = case Ct -> CtEvidence
ctEvidence Ct
ct of
CtWanted { ctev_pred :: CtEvidence -> TcType
ctev_pred = TcType
pty, ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dst }
-> do { ev_expr <- (TcTyVar, TcType) -> TcType -> TcS EvExpr
unsatisfiableEvExpr (TcTyVar, TcType)
unsat_given TcType
pty
; setWantedEvTerm dst EvNonCanonical $ EvExpr ev_expr }
CtEvidence
_ -> () -> TcS ()
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
unsatisfiableEvExpr :: (EvVar, ErrorMsgType) -> PredType -> TcS EvExpr
unsatisfiableEvExpr :: (TcTyVar, TcType) -> TcType -> TcS EvExpr
unsatisfiableEvExpr (TcTyVar
unsat_ev, TcType
given_msg) TcType
wtd_ty
= do { mod <- TcS Module
forall (m :: * -> *). HasModule m => m Module
getModule
; if mod == gHC_INTERNAL_TYPEERROR then return (Var unsat_ev) else
do { unsatisfiable_id <- tcLookupId unsatisfiableIdName
; let
fun_ty = HasDebugCallStack =>
FunTyFlag -> TcType -> TcType -> TcType -> TcType
FunTyFlag -> TcType -> TcType -> TcType -> TcType
mkFunTy FunTyFlag
visArgConstraintLike TcType
ManyTy TcType
unboxedUnitTy TcType
wtd_ty
mkDictBox = case TcType -> BoxingInfo (ZonkAny 0)
forall b. TcType -> BoxingInfo b
boxingDataCon TcType
fun_ty of
BI_Box { bi_data_con :: forall b. BoxingInfo b -> DataCon
bi_data_con = DataCon
mkDictBox } -> DataCon
mkDictBox
BoxingInfo (ZonkAny 0)
_ -> String -> SDoc -> DataCon
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"unsatisfiableEvExpr: no DictBox!" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
wtd_ty)
dictBox = DataCon -> TyCon
dataConTyCon DataCon
mkDictBox
; ev_bndr <- mkSysLocalM (fsLit "ct") ManyTy fun_ty
; let scrut_ty = TyCon -> [TcType] -> TcType
mkTyConApp TyCon
dictBox [TcType
fun_ty]
scrut =
EvExpr -> [EvExpr] -> EvExpr
mkCoreApps (TcTyVar -> EvExpr
forall b. TcTyVar -> Expr b
Var TcTyVar
unsatisfiable_id)
[ TcType -> EvExpr
forall b. TcType -> Expr b
Type TcType
liftedRepTy
, TcType -> EvExpr
forall b. TcType -> Expr b
Type TcType
given_msg
, TcType -> EvExpr
forall b. TcType -> Expr b
Type TcType
scrut_ty
, TcTyVar -> EvExpr
forall b. TcTyVar -> Expr b
Var TcTyVar
unsat_ev ]
ev_expr =
EvExpr -> Scaled TcType -> TcType -> [CoreAlt] -> EvExpr
mkWildCase EvExpr
scrut (TcType -> Scaled TcType
forall a. a -> Scaled a
unrestricted (TcType -> Scaled TcType) -> TcType -> Scaled TcType
forall a b. (a -> b) -> a -> b
$ TcType
scrut_ty) TcType
wtd_ty
[ AltCon -> [TcTyVar] -> EvExpr -> CoreAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt (DataCon -> AltCon
DataAlt DataCon
mkDictBox) [TcTyVar
ev_bndr] (EvExpr -> CoreAlt) -> EvExpr -> CoreAlt
forall a b. (a -> b) -> a -> b
$
EvExpr -> [EvExpr] -> EvExpr
mkCoreApps (TcTyVar -> EvExpr
forall b. TcTyVar -> Expr b
Var TcTyVar
ev_bndr) [EvExpr
unboxedUnitExpr]
]
; return ev_expr } }
type CtDefaultingStrategy = Ct -> TcS Bool
tryConstraintDefaulting :: WantedConstraints -> TcS WantedConstraints
tryConstraintDefaulting :: WantedConstraints -> TcS WantedConstraints
tryConstraintDefaulting WantedConstraints
wc
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wc
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
| Bool
otherwise
= do { (n_unifs, better_wc) <- TcS WantedConstraints -> TcS (Int, WantedConstraints)
forall a. TcS a -> TcS (Int, a)
reportUnifications (WantedConstraints -> TcS WantedConstraints
go_wc WantedConstraints
wc)
; solveAgainIf (n_unifs > 0) better_wc }
where
go_wc :: WantedConstraints -> TcS WantedConstraints
go_wc :: WantedConstraints -> TcS WantedConstraints
go_wc wc :: WantedConstraints
wc@(WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics })
= do { mb_simples <- (Ct -> TcS (Maybe Ct)) -> Cts -> TcS Cts
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> Bag a -> m (Bag b)
mapMaybeBagM Ct -> TcS (Maybe Ct)
go_simple Cts
simples
; mb_implics <- mapMaybeBagM go_implic implics
; return (wc { wc_simple = mb_simples, wc_impl = mb_implics }) }
go_simple :: Ct -> TcS (Maybe Ct)
go_simple :: Ct -> TcS (Maybe Ct)
go_simple Ct
ct = do { solved <- CtDefaultingStrategy
tryCtDefaultingStrategy Ct
ct
; if solved then return Nothing
else return (Just ct) }
go_implic :: Implication -> TcS (Maybe Implication)
go_implic :: Implication -> TcS (Maybe Implication)
go_implic Implication
implic
| ImplicStatus -> Bool
isSolvedStatus (Implication -> ImplicStatus
ic_status Implication
implic)
= Maybe Implication -> TcS (Maybe Implication)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Implication -> Maybe Implication
forall a. a -> Maybe a
Just Implication
implic)
| Bool
otherwise
= do { wanteds <- EvBindsVar -> TcS WantedConstraints -> TcS WantedConstraints
forall a. EvBindsVar -> TcS a -> TcS a
setEvBindsTcS (Implication -> EvBindsVar
ic_binds Implication
implic) (TcS WantedConstraints -> TcS WantedConstraints)
-> TcS WantedConstraints -> TcS WantedConstraints
forall a b. (a -> b) -> a -> b
$
WantedConstraints -> TcS WantedConstraints
go_wc (Implication -> WantedConstraints
ic_wanted Implication
implic)
; setImplicationStatus (implic { ic_wanted = wanteds }) }
tryCtDefaultingStrategy :: CtDefaultingStrategy
tryCtDefaultingStrategy :: CtDefaultingStrategy
tryCtDefaultingStrategy
= (CtDefaultingStrategy
-> CtDefaultingStrategy -> CtDefaultingStrategy)
-> [CtDefaultingStrategy] -> CtDefaultingStrategy
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 CtDefaultingStrategy
-> CtDefaultingStrategy -> CtDefaultingStrategy
combineStrategies
[ CtDefaultingStrategy
defaultCallStack
, CtDefaultingStrategy
defaultExceptionContext
, CtDefaultingStrategy
defaultEquality ]
defaultExceptionContext :: CtDefaultingStrategy
defaultExceptionContext :: CtDefaultingStrategy
defaultExceptionContext Ct
ct
| ClassPred Class
cls [TcType]
tys <- TcType -> Pred
classifyPredType (Ct -> TcType
ctPred Ct
ct)
, Maybe FastString -> Bool
forall a. Maybe a -> Bool
isJust (Class -> [TcType] -> Maybe FastString
isExceptionContextPred Class
cls [TcType]
tys)
= do { TcRnMessage -> TcS ()
warnTcS (TcRnMessage -> TcS ()) -> TcRnMessage -> TcS ()
forall a b. (a -> b) -> a -> b
$ CtLoc -> TcRnMessage
TcRnDefaultedExceptionContext (Ct -> CtLoc
ctLoc Ct
ct)
; empty_ec_id <- Name -> TcS TcTyVar
forall (m :: * -> *). MonadThings m => Name -> m TcTyVar
lookupId Name
emptyExceptionContextName
; let ev = Ct -> CtEvidence
ctEvidence Ct
ct
ev_tm = EvExpr -> TcCoercion -> EvTerm
mkEvCast (TcTyVar -> EvExpr
forall b. TcTyVar -> Expr b
Var TcTyVar
empty_ec_id) (TcType -> TcCoercion
wrapIP (CtEvidence -> TcType
ctEvPred CtEvidence
ev))
; setEvBindIfWanted ev EvCanonical ev_tm
; return True }
| Bool
otherwise
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
defaultCallStack :: CtDefaultingStrategy
defaultCallStack :: CtDefaultingStrategy
defaultCallStack Ct
ct
| ClassPred Class
cls [TcType]
tys <- TcType -> Pred
classifyPredType (Ct -> TcType
ctPred Ct
ct)
, Maybe FastString -> Bool
forall a. Maybe a -> Bool
isJust (Class -> [TcType] -> Maybe FastString
isCallStackPred Class
cls [TcType]
tys)
= do { CtEvidence -> EvCallStack -> TcS ()
solveCallStack (Ct -> CtEvidence
ctEvidence Ct
ct) EvCallStack
EvCsEmpty
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True }
| Bool
otherwise
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
defaultEquality :: CtDefaultingStrategy
defaultEquality :: CtDefaultingStrategy
defaultEquality Ct
ct
| EqPred EqRel
NomEq TcType
ty1 TcType
ty2 <- TcType -> Pred
classifyPredType (Ct -> TcType
ctPred Ct
ct)
= do {
z_ty1 <- TcType -> TcS TcType
TcS.zonkTcType TcType
ty1
; z_ty2 <- TcS.zonkTcType ty2
; case (getTyVar_maybe z_ty1, getTyVar_maybe z_ty2) of
(Just TcTyVar
z_tv1, Maybe TcTyVar
_) -> TcTyVar -> TcType -> TcS Bool
try_default_tv TcTyVar
z_tv1 TcType
z_ty2
(Maybe TcTyVar
_, Just TcTyVar
z_tv2) -> TcTyVar -> TcType -> TcS Bool
try_default_tv TcTyVar
z_tv2 TcType
z_ty1
(Maybe TcTyVar, Maybe TcTyVar)
_ -> Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False }
| Bool
otherwise
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
where
try_default_tv :: TcTyVar -> TcType -> TcS Bool
try_default_tv TcTyVar
lhs_tv TcType
rhs_ty
| MetaTv { mtv_info :: TcTyVarDetails -> MetaInfo
mtv_info = MetaInfo
info, mtv_tclvl :: TcTyVarDetails -> TcLevel
mtv_tclvl = TcLevel
lvl } <- TcTyVar -> TcTyVarDetails
tcTyVarDetails TcTyVar
lhs_tv
, TcTyVar -> TcType
tyVarKind TcTyVar
lhs_tv HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` HasDebugCallStack => TcType -> TcType
TcType -> TcType
typeKind TcType
rhs_ty
, MetaInfo -> TcType -> Bool
checkTopShape MetaInfo
info TcType
rhs_ty
= do { String -> SDoc -> TcS ()
traceTcS String
"defaultEquality 1" (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
lhs_tv SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs_ty)
; let flags :: TyEqFlags ()
flags :: TyEqFlags ()
flags = TEF { tef_foralls :: Bool
tef_foralls = Bool
False
, tef_fam_app :: TyEqFamApp ()
tef_fam_app = TyEqFamApp ()
forall a. TyEqFamApp a
TEFA_Recurse
, tef_lhs :: CanEqLHS
tef_lhs = TcTyVar -> CanEqLHS
TyVarLHS TcTyVar
lhs_tv
, tef_unifying :: AreUnifying
tef_unifying = MetaInfo -> TcLevel -> LevelCheck -> AreUnifying
Unifying MetaInfo
info TcLevel
lvl (Bool -> LevelCheck
LC_Promote Bool
True)
, tef_occurs :: CheckTyEqProblem
tef_occurs = CheckTyEqProblem
cteInsolubleOccurs }
; res :: PuResult () Reduction <- TcM (PuResult () Reduction) -> TcS (PuResult () Reduction)
forall a. TcM a -> TcS a
wrapTcS (TyEqFlags () -> TcType -> TcM (PuResult () Reduction)
forall a. TyEqFlags a -> TcType -> TcM (PuResult a Reduction)
checkTyEqRhs TyEqFlags ()
flags TcType
rhs_ty)
; case res of
PuFail {} -> String -> TcS Bool
cant_default_tv String
"checkTyEqRhs"
PuOK Bag ()
_ Reduction
redn -> Bool -> SDoc -> TcS Bool -> TcS Bool
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (TcCoercion -> Bool
isReflCo (Reduction -> TcCoercion
reductionCoercion Reduction
redn)) (Reduction -> SDoc
forall a. Outputable a => a -> SDoc
ppr Reduction
redn) (TcS Bool -> TcS Bool) -> TcS Bool -> TcS Bool
forall a b. (a -> b) -> a -> b
$
TcS Bool
default_tv }
| Bool
otherwise
= String -> TcS Bool
cant_default_tv String
"fall through"
where
cant_default_tv :: String -> TcS Bool
cant_default_tv String
msg
= do { String -> SDoc -> TcS ()
traceTcS (String
"defaultEquality fails: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
msg) (SDoc -> TcS ()) -> SDoc -> TcS ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
lhs_tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'~' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs_ty
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TcTyVar -> TcType
tyVarKind TcTyVar
lhs_tv)
, TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => TcType -> TcType
TcType -> TcType
typeKind TcType
rhs_ty) ]
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False }
default_tv :: TcS Bool
default_tv
= do { String -> SDoc -> TcS ()
traceTcS String
"defaultEquality success:" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
rhs_ty)
; TcTyVar -> TcType -> TcS ()
unifyTyVar TcTyVar
lhs_tv TcType
rhs_ty
; CtEvidence -> CanonicalEvidence -> EvTerm -> TcS ()
setEvBindIfWanted (Ct -> CtEvidence
ctEvidence Ct
ct) CanonicalEvidence
EvCanonical (EvTerm -> TcS ()) -> EvTerm -> TcS ()
forall a b. (a -> b) -> a -> b
$
TcCoercion -> EvTerm
evCoercion (TcType -> TcCoercion
mkNomReflCo TcType
rhs_ty)
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True }
combineStrategies :: CtDefaultingStrategy -> CtDefaultingStrategy -> CtDefaultingStrategy
combineStrategies :: CtDefaultingStrategy
-> CtDefaultingStrategy -> CtDefaultingStrategy
combineStrategies CtDefaultingStrategy
default1 CtDefaultingStrategy
default2 Ct
ct
= do { solved <- CtDefaultingStrategy
default1 Ct
ct
; case solved of
Bool
True -> Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Bool
False -> CtDefaultingStrategy
default2 Ct
ct
}
simplifyAmbiguityCheck :: Type -> WantedConstraints -> TcM ()
simplifyAmbiguityCheck :: TcType -> WantedConstraints -> TcM ()
simplifyAmbiguityCheck TcType
ty WantedConstraints
wc
= do { String -> SDoc -> TcM ()
traceTc String
"simplifyAmbiguityCheck {" (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$
String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type = " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"wanted = " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wc
; (final_wc, _) <- TcS WantedConstraints -> TcM (WantedConstraints, EvBindMap)
forall a. TcS a -> TcM (a, EvBindMap)
runTcS (TcS WantedConstraints -> TcM (WantedConstraints, EvBindMap))
-> TcS WantedConstraints -> TcM (WantedConstraints, EvBindMap)
forall a b. (a -> b) -> a -> b
$ do { wc1 <- WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
wc
; tryUnsatisfiableGivens wc1 }
; discardResult (reportUnsolved final_wc)
; traceTc "End simplifyAmbiguityCheck }" empty }
simplifyInteractive :: WantedConstraints -> TcM (Bag EvBind)
simplifyInteractive :: WantedConstraints -> TcM (Bag EvBind)
simplifyInteractive WantedConstraints
wanteds
= String -> SDoc -> TcM ()
traceTc String
"simplifyInteractive" SDoc
forall doc. IsOutput doc => doc
empty TcM () -> TcM (Bag EvBind) -> TcM (Bag EvBind)
forall a b.
IOEnv (Env TcGblEnv TcLclEnv) a
-> IOEnv (Env TcGblEnv TcLclEnv) b
-> IOEnv (Env TcGblEnv TcLclEnv) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
WantedConstraints -> TcM (Bag EvBind)
simplifyTop WantedConstraints
wanteds
simplifyDefault :: ThetaType
-> TcM Bool
simplifyDefault :: [TcType] -> TcM Bool
simplifyDefault [TcType]
theta
= do { String -> SDoc -> TcM ()
traceTc String
"simplifyDefault" SDoc
forall doc. IsOutput doc => doc
empty
; wanteds <- CtOrigin -> [TcType] -> TcM [CtEvidence]
newWanteds CtOrigin
DefaultOrigin [TcType]
theta
; (unsolved, _) <- runTcS (solveWanteds (mkSimpleWC wanteds))
; return (isEmptyWC unsolved) }
tcCheckGivens :: InertSet -> Bag EvVar -> TcM (Maybe InertSet)
tcCheckGivens :: InertSet -> Bag TcTyVar -> TcM (Maybe InertSet)
tcCheckGivens InertSet
inerts Bag TcTyVar
given_ids = do
(sat, new_inerts) <- InertSet -> TcS Bool -> TcM (Bool, InertSet)
forall a. InertSet -> TcS a -> TcM (a, InertSet)
runTcSInerts InertSet
inerts (TcS Bool -> TcM (Bool, InertSet))
-> TcS Bool -> TcM (Bool, InertSet)
forall a b. (a -> b) -> a -> b
$ do
String -> SDoc -> TcS ()
traceTcS String
"checkGivens {" (InertSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr InertSet
inerts SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Bag TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bag TcTyVar
given_ids)
lcl_env <- TcS TcLclEnv
TcS.getLclEnv
let given_loc = TcLevel -> SkolemInfoAnon -> CtLocEnv -> CtLoc
mkGivenLoc TcLevel
topTcLevel (SkolemInfo -> SkolemInfoAnon
getSkolemInfo SkolemInfo
HasDebugCallStack => SkolemInfo
unkSkol) (TcLclEnv -> CtLocEnv
mkCtLocEnv TcLclEnv
lcl_env)
let given_cts = CtLoc -> [TcTyVar] -> [Ct]
mkGivens CtLoc
given_loc (Bag TcTyVar -> [TcTyVar]
forall a. Bag a -> [a]
bagToList Bag TcTyVar
given_ids)
solveSimpleGivens given_cts
insols <- getInertInsols
insols <- try_harder insols
traceTcS "checkGivens }" (ppr insols)
return (isEmptyBag insols)
return $ if sat then Just new_inerts else Nothing
where
try_harder :: Cts -> TcS Cts
try_harder :: Cts -> TcS Cts
try_harder Cts
insols
| Bool -> Bool
not (Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag Cts
insols)
= Cts -> TcS Cts
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Cts
insols
| Bool
otherwise
= do { pending_given <- TcS [Ct]
getPendingGivenScs
; new_given <- makeSuperClasses pending_given
; solveSimpleGivens new_given
; getInertInsols }
tcCheckWanteds :: InertSet -> ThetaType -> TcM Bool
tcCheckWanteds :: InertSet -> [TcType] -> TcM Bool
tcCheckWanteds InertSet
inerts [TcType]
wanteds = do
cts <- CtOrigin -> [TcType] -> TcM [CtEvidence]
newWanteds CtOrigin
PatCheckOrigin [TcType]
wanteds
(sat, _new_inerts) <- runTcSInerts inerts $ do
traceTcS "checkWanteds {" (ppr inerts <+> ppr wanteds)
wcs <- solveWanteds (mkSimpleWC cts)
traceTcS "checkWanteds }" (ppr wcs)
return (isSolvedWC wcs)
return sat
tcNormalise :: InertSet -> Type -> TcM Type
tcNormalise :: InertSet -> TcType -> TcM TcType
tcNormalise InertSet
inerts TcType
ty
= do { norm_loc <- CtOrigin -> Maybe TypeOrKind -> TcM CtLoc
getCtLocM CtOrigin
PatCheckOrigin Maybe TypeOrKind
forall a. Maybe a
Nothing
; (res, _new_inerts) <- runTcSInerts inerts $
do { traceTcS "tcNormalise {" (ppr inerts)
; ty' <- rewriteType norm_loc ty
; traceTcS "tcNormalise }" (ppr ty')
; pure ty' }
; return res }
data InferMode = ApplyMR
| EagerDefaulting
| NoRestrictions
instance Outputable InferMode where
ppr :: InferMode -> SDoc
ppr InferMode
ApplyMR = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"ApplyMR"
ppr InferMode
EagerDefaulting = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"EagerDefaulting"
ppr InferMode
NoRestrictions = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"NoRestrictions"
simplifyInfer :: TcLevel
-> InferMode
-> [TcIdSigInst]
-> [(Name, TcTauType)]
-> WantedConstraints
-> TcM ([TcTyVar],
[EvVar],
TcEvBinds,
Bool)
simplifyInfer :: TcLevel
-> InferMode
-> [TcIdSigInst]
-> [(Name, TcType)]
-> WantedConstraints
-> TcM ([TcTyVar], [TcTyVar], TcEvBinds, Bool)
simplifyInfer TcLevel
rhs_tclvl InferMode
infer_mode [TcIdSigInst]
sigs [(Name, TcType)]
name_taus WantedConstraints
wanteds
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanteds
= do {
let psig_tv_tys :: [TcType]
psig_tv_tys = [ TcTyVar -> TcType
mkTyVarTy TcTyVar
tv | TcIdSigInst
sig <- [TcIdSigInst]
partial_sigs
, (Name
_,Bndr TcTyVar
tv Specificity
_) <- TcIdSigInst -> [(Name, InvisTVBinder)]
sig_inst_skols TcIdSigInst
sig ]
psig_theta :: [TcType]
psig_theta = [ TcType
pred | TcIdSigInst
sig <- [TcIdSigInst]
partial_sigs
, TcType
pred <- TcIdSigInst -> [TcType]
sig_inst_theta TcIdSigInst
sig ]
; dep_vars <- [TcType] -> TcM CandidatesQTvs
candidateQTyVarsOfTypes ([TcType]
psig_tv_tys [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ [TcType]
psig_theta [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ ((Name, TcType) -> TcType) -> [(Name, TcType)] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map (Name, TcType) -> TcType
forall a b. (a, b) -> b
snd [(Name, TcType)]
name_taus)
; skol_info <- mkSkolemInfo (InferSkol name_taus)
; qtkvs <- quantifyTyVars skol_info DefaultNonStandardTyVars dep_vars
; traceTc "simplifyInfer: empty WC" (ppr name_taus $$ ppr qtkvs)
; return (qtkvs, [], emptyTcEvBinds, False) }
| Bool
otherwise
= do { String -> SDoc -> TcM ()
traceTc String
"simplifyInfer {" (SDoc -> TcM ()) -> SDoc -> TcM ()
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
"sigs =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [TcIdSigInst] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TcIdSigInst]
sigs
, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"binds =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [(Name, TcType)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Name, TcType)]
name_taus
, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"rhs_tclvl =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TcLevel -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcLevel
rhs_tclvl
, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"infer_mode =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> InferMode -> SDoc
forall a. Outputable a => a -> SDoc
ppr InferMode
infer_mode
, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"(unzonked) wanted =" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wanteds
]
; let psig_theta :: [TcType]
psig_theta = (TcIdSigInst -> [TcType]) -> [TcIdSigInst] -> [TcType]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap TcIdSigInst -> [TcType]
sig_inst_theta [TcIdSigInst]
partial_sigs
; ev_binds_var <- TcM EvBindsVar
TcM.newTcEvBinds
; psig_evs <- newWanteds AnnOrigin psig_theta
; wanted_transformed
<- setTcLevel rhs_tclvl $
runTcSWithEvBinds ev_binds_var $
solveWanteds (mkSimpleWC psig_evs `andWC` wanteds)
; wanted_transformed <- TcM.liftZonkM $ TcM.zonkWC wanted_transformed
; let definite_error = WantedConstraints -> Bool
insolubleWC WantedConstraints
wanted_transformed
quant_pred_candidates
| Bool
definite_error = []
| Bool
otherwise = Cts -> [TcType]
ctsPreds (Bool -> WantedConstraints -> Cts
approximateWC Bool
False WantedConstraints
wanted_transformed)
; rec { (qtvs, bound_theta, co_vars) <- decideQuantification skol_info infer_mode rhs_tclvl
name_taus partial_sigs
quant_pred_candidates
; bound_theta_vars <- mapM TcM.newEvVar bound_theta
; let full_theta = (TcTyVar -> TcType) -> [TcTyVar] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map TcTyVar -> TcType
idType [TcTyVar]
bound_theta_vars
; skol_info <- mkSkolemInfo (InferSkol [ (name, mkPhiTy full_theta ty)
| (name, ty) <- name_taus ])
}
; emitResidualConstraints rhs_tclvl ev_binds_var
name_taus co_vars qtvs bound_theta_vars
wanted_transformed
; traceTc "} simplifyInfer/produced residual implication for quantification" $
vcat [ text "quant_pred_candidates =" <+> ppr quant_pred_candidates
, text "psig_theta =" <+> ppr psig_theta
, text "bound_theta =" <+> pprCoreBinders bound_theta_vars
, text "qtvs =" <+> ppr qtvs
, text "definite_error =" <+> ppr definite_error ]
; return ( qtvs, bound_theta_vars, TcEvBinds ev_binds_var, definite_error ) }
where
partial_sigs :: [TcIdSigInst]
partial_sigs = (TcIdSigInst -> Bool) -> [TcIdSigInst] -> [TcIdSigInst]
forall a. (a -> Bool) -> [a] -> [a]
filter TcIdSigInst -> Bool
isPartialSig [TcIdSigInst]
sigs
emitResidualConstraints :: TcLevel -> EvBindsVar
-> [(Name, TcTauType)]
-> CoVarSet -> [TcTyVar] -> [EvVar]
-> WantedConstraints -> TcM ()
emitResidualConstraints :: TcLevel
-> EvBindsVar
-> [(Name, TcType)]
-> VarSet
-> [TcTyVar]
-> [TcTyVar]
-> WantedConstraints
-> TcM ()
emitResidualConstraints TcLevel
rhs_tclvl EvBindsVar
ev_binds_var
[(Name, TcType)]
name_taus VarSet
co_vars [TcTyVar]
qtvs [TcTyVar]
full_theta_vars WantedConstraints
wanteds
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanteds
= () -> TcM ()
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do { wanted_simple <- ZonkM Cts -> TcM Cts
forall a. ZonkM a -> TcM a
TcM.liftZonkM (ZonkM Cts -> TcM Cts) -> ZonkM Cts -> TcM Cts
forall a b. (a -> b) -> a -> b
$ Cts -> ZonkM Cts
TcM.zonkSimples (WantedConstraints -> Cts
wc_simple WantedConstraints
wanteds)
; let (outer_simple, inner_simple) = partitionBag is_mono wanted_simple
is_mono Ct
ct
| Just TcTyVar
ct_ev_id <- Ct -> Maybe TcTyVar
wantedEvId_maybe Ct
ct
= TcTyVar
ct_ev_id TcTyVar -> VarSet -> Bool
`elemVarSet` VarSet
co_vars
| Bool
otherwise
= Bool
False
; let inner_wanted = WantedConstraints
wanteds { wc_simple = inner_simple }
; implics <- if isEmptyWC inner_wanted
then return emptyBag
else do implic1 <- newImplication
return $ unitBag $
implic1 { ic_tclvl = rhs_tclvl
, ic_skols = qtvs
, ic_given = full_theta_vars
, ic_wanted = inner_wanted
, ic_binds = ev_binds_var
, ic_given_eqs = MaybeGivenEqs
, ic_info = skol_info }
; emitConstraints (emptyWC { wc_simple = outer_simple
, wc_impl = implics }) }
where
full_theta :: [TcType]
full_theta = (TcTyVar -> TcType) -> [TcTyVar] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map TcTyVar -> TcType
idType [TcTyVar]
full_theta_vars
skol_info :: SkolemInfoAnon
skol_info = [(Name, TcType)] -> SkolemInfoAnon
InferSkol [ (Name
name, [TcType] -> TcType -> TcType
HasDebugCallStack => [TcType] -> TcType -> TcType
mkPhiTy [TcType]
full_theta TcType
ty)
| (Name
name, TcType
ty) <- [(Name, TcType)]
name_taus ]
findInferredDiff :: TcThetaType -> TcThetaType -> TcM TcThetaType
findInferredDiff :: [TcType] -> [TcType] -> TcM [TcType]
findInferredDiff [TcType]
annotated_theta [TcType]
inferred_theta
| [TcType] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
annotated_theta
= [TcType] -> TcM [TcType]
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return [TcType]
inferred_theta
| Bool
otherwise
= TcM [TcType] -> TcM [TcType]
forall r. TcM r -> TcM r
pushTcLevelM_ (TcM [TcType] -> TcM [TcType]) -> TcM [TcType] -> TcM [TcType]
forall a b. (a -> b) -> a -> b
$
do { lcl_env <- TcRnIf TcGblEnv TcLclEnv TcLclEnv
forall gbl lcl. TcRnIf gbl lcl lcl
TcM.getLclEnv
; given_ids <- mapM TcM.newEvVar annotated_theta
; wanteds <- newWanteds AnnOrigin inferred_theta
; let given_loc = TcLevel -> SkolemInfoAnon -> CtLocEnv -> CtLoc
mkGivenLoc TcLevel
topTcLevel (SkolemInfo -> SkolemInfoAnon
getSkolemInfo SkolemInfo
HasDebugCallStack => SkolemInfo
unkSkol) (TcLclEnv -> CtLocEnv
mkCtLocEnv TcLclEnv
lcl_env)
given_cts = CtLoc -> [TcTyVar] -> [Ct]
mkGivens CtLoc
given_loc [TcTyVar]
given_ids
; (residual, _) <- runTcS $
do { _ <- solveSimpleGivens given_cts
; solveSimpleWanteds (listToBag (map mkNonCanonical wanteds)) }
; return (map (box_pred . ctPred) $
bagToList $
wc_simple residual) }
where
box_pred :: PredType -> PredType
box_pred :: TcType -> TcType
box_pred TcType
pred = case TcType -> Pred
classifyPredType TcType
pred of
EqPred EqRel
rel TcType
ty1 TcType
ty2
| Just (Class
cls,[TcType]
tys) <- EqRel -> TcType -> TcType -> Maybe (Class, [TcType])
boxEqPred EqRel
rel TcType
ty1 TcType
ty2
-> Class -> [TcType] -> TcType
mkClassPred Class
cls [TcType]
tys
| Bool
otherwise
-> String -> SDoc -> TcType
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"findInferredDiff" (TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
pred)
Pred
_other -> TcType
pred
decideQuantification
:: SkolemInfo
-> InferMode
-> TcLevel
-> [(Name, TcTauType)]
-> [TcIdSigInst]
-> [PredType]
-> TcM ( [TcTyVar]
, [PredType]
, CoVarSet)
decideQuantification :: SkolemInfo
-> InferMode
-> TcLevel
-> [(Name, TcType)]
-> [TcIdSigInst]
-> [TcType]
-> TcM ([TcTyVar], [TcType], VarSet)
decideQuantification SkolemInfo
skol_info InferMode
infer_mode TcLevel
rhs_tclvl [(Name, TcType)]
name_taus [TcIdSigInst]
psigs [TcType]
candidates
= do {
; (candidates, co_vars, mono_tvs0)
<- InferMode
-> [(Name, TcType)]
-> [TcIdSigInst]
-> [TcType]
-> TcM ([TcType], VarSet, VarSet)
decidePromotedTyVars InferMode
infer_mode [(Name, TcType)]
name_taus [TcIdSigInst]
psigs [TcType]
candidates
; candidates <- defaultTyVarsAndSimplify rhs_tclvl candidates
; qtvs <- decideQuantifiedTyVars skol_info name_taus psigs candidates
; (candidates, psig_theta) <- TcM.liftZonkM $
do { candidates <- TcM.zonkTcTypes candidates
; psig_theta <- TcM.zonkTcTypes (concatMap sig_inst_theta psigs)
; return (candidates, psig_theta) }
; min_theta <- pickQuantifiablePreds (mkVarSet qtvs) mono_tvs0 candidates
; let min_psig_theta = (TcType -> TcType) -> [TcType] -> [TcType]
forall a. (a -> TcType) -> [a] -> [a]
mkMinimalBySCs TcType -> TcType
forall a. a -> a
id [TcType]
psig_theta
; theta <- if
| null psigs -> return min_theta
| not (all has_extra_constraints_wildcard psigs)
-> return min_psig_theta
| otherwise
-> do { diff <- findInferredDiff min_psig_theta min_theta
; return (min_psig_theta ++ diff) }
; traceTc "decideQuantification"
(vcat [ text "infer_mode:" <+> ppr infer_mode
, text "candidates:" <+> ppr candidates
, text "psig_theta:" <+> ppr psig_theta
, text "co_vars:" <+> ppr co_vars
, text "qtvs:" <+> ppr qtvs
, text "theta:" <+> ppr theta ])
; return (qtvs, theta, co_vars) }
where
has_extra_constraints_wildcard :: TcIdSigInst -> Bool
has_extra_constraints_wildcard (TISI { sig_inst_wcx :: TcIdSigInst -> Maybe TcType
sig_inst_wcx = Just {} }) = Bool
True
has_extra_constraints_wildcard TcIdSigInst
_ = Bool
False
decidePromotedTyVars :: InferMode
-> [(Name,TcType)]
-> [TcIdSigInst]
-> [PredType]
-> TcM ([PredType], CoVarSet, TcTyVarSet)
decidePromotedTyVars :: InferMode
-> [(Name, TcType)]
-> [TcIdSigInst]
-> [TcType]
-> TcM ([TcType], VarSet, VarSet)
decidePromotedTyVars InferMode
infer_mode [(Name, TcType)]
name_taus [TcIdSigInst]
psigs [TcType]
candidates
= do { tc_lvl <- TcM TcLevel
TcM.getTcLevel
; (no_quant, maybe_quant) <- pick infer_mode candidates
; (psig_qtvs, psig_theta, taus) <- TcM.liftZonkM $
do { psig_qtvs <- zonkTcTyVarsToTcTyVars $ binderVars $
concatMap (map snd . sig_inst_skols) psigs
; psig_theta <- mapM TcM.zonkTcType $
concatMap sig_inst_theta psigs
; taus <- mapM (TcM.zonkTcType . snd) name_taus
; return (psig_qtvs, psig_theta, taus) }
; let psig_tys = [TcTyVar] -> [TcType]
mkTyVarTys [TcTyVar]
psig_qtvs [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ [TcType]
psig_theta
co_vars = [TcType] -> VarSet
coVarsOfTypes ([TcType]
psig_tys [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ [TcType]
taus [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ [TcType]
candidates)
co_var_tvs = VarSet -> VarSet
closeOverKinds VarSet
co_vars
mono_tvs0 = (TcTyVar -> Bool) -> VarSet -> VarSet
filterVarSet (Bool -> Bool
not (Bool -> Bool) -> (TcTyVar -> Bool) -> TcTyVar -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcLevel -> TcTyVar -> Bool
isQuantifiableTv TcLevel
tc_lvl) (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
[TcType] -> VarSet
tyCoVarsOfTypes [TcType]
candidates
mono_tvs1 = VarSet
mono_tvs0 VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
co_var_tvs
non_ip_candidates = (TcType -> Bool) -> [TcType] -> [TcType]
forall a. (a -> Bool) -> [a] -> [a]
filterOut TcType -> Bool
isIPLikePred [TcType]
candidates
mono_tvs2 = [TcType] -> VarSet -> VarSet
closeWrtFunDeps [TcType]
non_ip_candidates VarSet
mono_tvs1
constrained_tvs = (TcTyVar -> Bool) -> VarSet -> VarSet
filterVarSet (TcLevel -> TcTyVar -> Bool
isQuantifiableTv TcLevel
tc_lvl) (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
[TcType] -> VarSet -> VarSet
closeWrtFunDeps [TcType]
non_ip_candidates ([TcType] -> VarSet
tyCoVarsOfTypes [TcType]
no_quant)
VarSet -> VarSet -> VarSet
`minusVarSet` VarSet
mono_tvs2
mono_tvs = (VarSet
mono_tvs2 VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
constrained_tvs)
VarSet -> [TcTyVar] -> VarSet
`delVarSetList` [TcTyVar]
psig_qtvs
; when (case infer_mode of { InferMode
ApplyMR -> Bool
True; InferMode
_ -> Bool
False}) $ do
let dia = [Name] -> TcRnMessage
TcRnMonomorphicBindings (((Name, TcType) -> Name) -> [(Name, TcType)] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map (Name, TcType) -> Name
forall a b. (a, b) -> a
fst [(Name, TcType)]
name_taus)
diagnosticTc (constrained_tvs `intersectsVarSet` tyCoVarsOfTypes taus) dia
; _ <- promoteTyVarSet mono_tvs
; traceTc "decidePromotedTyVars" $ vcat
[ text "infer_mode =" <+> ppr infer_mode
, text "psigs =" <+> ppr psigs
, text "psig_qtvs =" <+> ppr psig_qtvs
, text "mono_tvs0 =" <+> ppr mono_tvs0
, text "no_quant =" <+> ppr no_quant
, text "maybe_quant =" <+> ppr maybe_quant
, text "mono_tvs =" <+> ppr mono_tvs
, text "co_vars =" <+> ppr co_vars ]
; return (maybe_quant, co_vars, mono_tvs0) }
where
pick :: InferMode -> [PredType] -> TcM ([PredType], [PredType])
pick :: InferMode -> [TcType] -> TcM ([TcType], [TcType])
pick InferMode
ApplyMR [TcType]
cand = ([TcType], [TcType]) -> TcM ([TcType], [TcType])
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([TcType]
cand, [])
pick InferMode
NoRestrictions [TcType]
cand = ([TcType], [TcType]) -> TcM ([TcType], [TcType])
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [TcType]
cand)
pick InferMode
EagerDefaulting [TcType]
cand = do { os <- Extension -> TcM Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.OverloadedStrings
; return (partition (is_int_ct os) cand) }
is_int_ct :: Bool -> TcType -> Bool
is_int_ct Bool
ovl_strings TcType
pred
= case TcType -> Pred
classifyPredType TcType
pred of
ClassPred Class
cls [TcType]
_ -> Bool -> Class -> Bool
isInteractiveClass Bool
ovl_strings Class
cls
Pred
_ -> Bool
False
defaultTyVarsAndSimplify :: TcLevel
-> [PredType]
-> TcM [PredType]
defaultTyVarsAndSimplify :: TcLevel -> [TcType] -> TcM [TcType]
defaultTyVarsAndSimplify TcLevel
rhs_tclvl [TcType]
candidates
= do {
; DV {dv_kvs = cand_kvs, dv_tvs = cand_tvs}
<- [TcType] -> TcM CandidatesQTvs
candidateQTyVarsOfTypes [TcType]
candidates
; poly_kinds <- xoptM LangExt.PolyKinds
; let default_kv | Bool
poly_kinds = TcTyVar -> TcM Bool
default_tv
| Bool
otherwise = DefaultingStrategy -> TcTyVar -> TcM Bool
defaultTyVar DefaultingStrategy
DefaultKindVars
default_tv = DefaultingStrategy -> TcTyVar -> TcM Bool
defaultTyVar (NonStandardDefaultingStrategy -> DefaultingStrategy
NonStandardDefaulting NonStandardDefaultingStrategy
DefaultNonStandardTyVars)
; mapM_ default_kv (dVarSetElems cand_kvs)
; mapM_ default_tv (dVarSetElems (cand_tvs `minusDVarSet` cand_kvs))
; simplify_cand candidates
}
where
simplify_cand :: [TcType] -> TcM [TcType]
simplify_cand [] = [TcType] -> TcM [TcType]
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return []
simplify_cand [TcType]
candidates
= do { clone_wanteds <- CtOrigin -> [TcType] -> TcM [CtEvidence]
newWanteds CtOrigin
DefaultOrigin [TcType]
candidates
; WC { wc_simple = simples } <- setTcLevel rhs_tclvl $
simplifyWantedsTcM clone_wanteds
; let new_candidates = Cts -> [TcType]
ctsPreds Cts
simples
; traceTc "Simplified after defaulting" $
vcat [ text "Before:" <+> ppr candidates
, text "After:" <+> ppr new_candidates ]
; return new_candidates }
decideQuantifiedTyVars
:: SkolemInfo
-> [(Name,TcType)]
-> [TcIdSigInst]
-> [PredType]
-> TcM [TyVar]
decideQuantifiedTyVars :: SkolemInfo
-> [(Name, TcType)] -> [TcIdSigInst] -> [TcType] -> TcM [TcTyVar]
decideQuantifiedTyVars SkolemInfo
skol_info [(Name, TcType)]
name_taus [TcIdSigInst]
psigs [TcType]
candidates
= do {
; (psig_tv_tys, psig_theta, tau_tys) <- ZonkM ([TcType], [TcType], [TcType])
-> TcM ([TcType], [TcType], [TcType])
forall a. ZonkM a -> TcM a
TcM.liftZonkM (ZonkM ([TcType], [TcType], [TcType])
-> TcM ([TcType], [TcType], [TcType]))
-> ZonkM ([TcType], [TcType], [TcType])
-> TcM ([TcType], [TcType], [TcType])
forall a b. (a -> b) -> a -> b
$
do { psig_tv_tys <- (TcTyVar -> ZonkM TcType) -> [TcTyVar] -> ZonkM [TcType]
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 -> ZonkM TcType
TcM.zonkTcTyVar [ TcTyVar
tv | TcIdSigInst
sig <- [TcIdSigInst]
psigs
, (Name
_,Bndr TcTyVar
tv Specificity
_) <- TcIdSigInst -> [(Name, InvisTVBinder)]
sig_inst_skols TcIdSigInst
sig ]
; psig_theta <- mapM TcM.zonkTcType [ pred | sig <- psigs
, pred <- sig_inst_theta sig ]
; tau_tys <- mapM (TcM.zonkTcType . snd) name_taus
; return (psig_tv_tys, psig_theta, tau_tys) }
; let
psig_tys = [TcType]
psig_tv_tys [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ [TcType]
psig_theta
seed_tys = [TcType]
psig_tys [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ [TcType]
tau_tys
grown_tcvs = [TcType] -> VarSet -> VarSet
growThetaTyVars [TcType]
candidates ([TcType] -> VarSet
tyCoVarsOfTypes [TcType]
seed_tys)
; dv@DV {dv_kvs = cand_kvs, dv_tvs = cand_tvs} <- candidateQTyVarsOfTypes $
psig_tys ++ candidates ++ tau_tys
; let pick = (DTyVarSet -> VarSet -> DTyVarSet
`dVarSetIntersectVarSet` VarSet
grown_tcvs)
dvs_plus = CandidatesQTvs
dv { dv_kvs = pick cand_kvs, dv_tvs = pick cand_tvs }
; traceTc "decideQuantifiedTyVars" (vcat
[ text "tau_tys =" <+> ppr tau_tys
, text "candidates =" <+> ppr candidates
, text "cand_kvs =" <+> ppr cand_kvs
, text "cand_tvs =" <+> ppr cand_tvs
, text "tau_tys =" <+> ppr tau_tys
, text "seed_tys =" <+> ppr seed_tys
, text "seed_tcvs =" <+> ppr (tyCoVarsOfTypes seed_tys)
, text "grown_tcvs =" <+> ppr grown_tcvs
, text "dvs =" <+> ppr dvs_plus])
; quantifyTyVars skol_info DefaultNonStandardTyVars dvs_plus }
pickQuantifiablePreds
:: TyVarSet
-> TcTyVarSet
-> TcThetaType
-> TcM TcThetaType
pickQuantifiablePreds :: VarSet -> VarSet -> [TcType] -> TcM [TcType]
pickQuantifiablePreds VarSet
qtvs VarSet
mono_tvs0 [TcType]
theta
= do { tc_lvl <- TcM TcLevel
TcM.getTcLevel
; let is_nested = Bool -> Bool
not (TcLevel -> Bool
isTopTcLevel TcLevel
tc_lvl)
; return (mkMinimalBySCs id $
mapMaybe (pick_me is_nested) theta) }
where
pick_me :: Bool -> TcType -> Maybe TcType
pick_me Bool
is_nested TcType
pred
= let pred_tvs :: VarSet
pred_tvs = TcType -> VarSet
tyCoVarsOfType TcType
pred
mentions_qtvs :: Bool
mentions_qtvs = VarSet
pred_tvs VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
qtvs
in case TcType -> Pred
classifyPredType TcType
pred of
ClassPred Class
cls [TcType]
tys
| Just {} <- Class -> [TcType] -> Maybe FastString
isCallStackPred Class
cls [TcType]
tys
-> Maybe TcType
forall a. Maybe a
Nothing
| Class -> Bool
isIPClass Class
cls
-> TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
pred
| Bool -> Bool
not Bool
mentions_qtvs
-> Maybe TcType
forall a. Maybe a
Nothing
| Bool
is_nested
-> TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
pred
| VarSet
pred_tvs VarSet -> VarSet -> Bool
`subVarSet` (VarSet
qtvs VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
mono_tvs0)
-> TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
pred
| Bool
otherwise
-> Maybe TcType
forall a. Maybe a
Nothing
EqPred EqRel
eq_rel TcType
ty1 TcType
ty2
| Bool
mentions_qtvs
, EqRel -> TcType -> TcType -> Bool
quantify_equality EqRel
eq_rel TcType
ty1 TcType
ty2
, Just (Class
cls, [TcType]
tys) <- EqRel -> TcType -> TcType -> Maybe (Class, [TcType])
boxEqPred EqRel
eq_rel TcType
ty1 TcType
ty2
-> TcType -> Maybe TcType
forall a. a -> Maybe a
Just (Class -> [TcType] -> TcType
mkClassPred Class
cls [TcType]
tys)
| Bool
otherwise
-> Maybe TcType
forall a. Maybe a
Nothing
IrredPred {} | Bool
mentions_qtvs -> TcType -> Maybe TcType
forall a. a -> Maybe a
Just TcType
pred
| Bool
otherwise -> Maybe TcType
forall a. Maybe a
Nothing
ForAllPred {} -> Maybe TcType
forall a. Maybe a
Nothing
quantify_equality :: EqRel -> TcType -> TcType -> Bool
quantify_equality EqRel
NomEq TcType
ty1 TcType
ty2 = TcType -> Bool
quant_fun TcType
ty1 Bool -> Bool -> Bool
|| TcType -> Bool
quant_fun TcType
ty2
quantify_equality EqRel
ReprEq TcType
_ TcType
_ = Bool
True
quant_fun :: TcType -> Bool
quant_fun TcType
ty
= case HasDebugCallStack => TcType -> Maybe (TyCon, [TcType])
TcType -> Maybe (TyCon, [TcType])
tcSplitTyConApp_maybe TcType
ty of
Just (TyCon
tc, [TcType]
tys) | TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
-> [TcType] -> VarSet
tyCoVarsOfTypes [TcType]
tys VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
qtvs
Maybe (TyCon, [TcType])
_ -> Bool
False
growThetaTyVars :: ThetaType -> TyCoVarSet -> TyCoVarSet
growThetaTyVars :: [TcType] -> VarSet -> VarSet
growThetaTyVars [TcType]
theta VarSet
tcvs
| [TcType] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcType]
theta = VarSet
tcvs
| Bool
otherwise = (VarSet -> VarSet) -> VarSet -> VarSet
transCloVarSet VarSet -> VarSet
mk_next VarSet
seed_tcvs
where
seed_tcvs :: VarSet
seed_tcvs = VarSet
tcvs VarSet -> VarSet -> VarSet
`unionVarSet` [TcType] -> VarSet
tyCoVarsOfTypes [TcType]
ips
([TcType]
ips, [TcType]
non_ips) = (TcType -> Bool) -> [TcType] -> ([TcType], [TcType])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition TcType -> Bool
isIPLikePred [TcType]
theta
mk_next :: VarSet -> VarSet
mk_next :: VarSet -> VarSet
mk_next VarSet
so_far = (TcType -> VarSet -> VarSet) -> VarSet -> [TcType] -> VarSet
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (VarSet -> TcType -> VarSet -> VarSet
grow_one VarSet
so_far) VarSet
emptyVarSet [TcType]
non_ips
grow_one :: VarSet -> TcType -> VarSet -> VarSet
grow_one VarSet
so_far TcType
pred VarSet
tcvs
| VarSet
pred_tcvs VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
so_far = VarSet
tcvs VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
pred_tcvs
| Bool
otherwise = VarSet
tcvs
where
pred_tcvs :: VarSet
pred_tcvs = TcType -> VarSet
tyCoVarsOfType TcType
pred
simplifyWantedsTcM :: [CtEvidence] -> TcM WantedConstraints
simplifyWantedsTcM :: [CtEvidence] -> IOEnv (Env TcGblEnv TcLclEnv) WantedConstraints
simplifyWantedsTcM [CtEvidence]
wanted
= do { String -> SDoc -> TcM ()
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 })
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wc
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
| Bool
otherwise
= 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 "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 })
= 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, wc1) <- TcS WantedConstraints -> TcS (Int, WantedConstraints)
forall a. TcS a -> TcS (Int, a)
reportUnifications (TcS WantedConstraints -> TcS (Int, WantedConstraints))
-> TcS WantedConstraints -> TcS (Int, WantedConstraints)
forall a b. (a -> b) -> a -> b
$
Cts -> TcS WantedConstraints
solveSimpleWanteds Cts
simples
; wc2 <- if not definitely_redo_implications
&& unifs1 == 0
&& isEmptyBag (wc_impl wc1)
then return (wc { wc_simple = wc_simple wc1 })
else do { implics2 <- solveNestedImplications $
implics `unionBags` (wc_impl wc1)
; return (wc { wc_simple = wc_simple wc1
, wc_impl = implics2 }) }
; 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 (Maybe Implication))
-> Bag Implication -> TcS (Bag (Maybe Implication))
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Bag a -> m (Bag b)
mapBagM Implication -> TcS (Maybe Implication)
solveImplication Bag Implication
implics
; traceTcS "solveNestedImplications end }" $
vcat [ text "unsolved_implics =" <+> ppr unsolved_implics ]
; return (catBagMaybes unsolved_implics) }
solveImplication :: Implication
-> TcS (Maybe Implication)
solveImplication :: Implication -> TcS (Maybe 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_status :: Implication -> ImplicStatus
ic_status = ImplicStatus
status })
| ImplicStatus -> Bool
isSolvedStatus ImplicStatus
status
= Maybe Implication -> TcS (Maybe Implication)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Implication -> Maybe Implication
forall a. a -> Maybe a
Just 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 (Implication -> CtLocEnv
ic_env Implication
imp)
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 (Maybe Implication)
setImplicationStatus :: Implication -> TcS (Maybe 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
, ic_given :: Implication -> [TcTyVar]
ic_given = [TcTyVar]
givens })
| Bool -> SDoc -> Bool -> Bool
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) (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$
Bool -> Bool
not (WantedConstraints -> Bool
isSolvedWC WantedConstraints
pruned_wc)
= do { String -> SDoc -> TcS ()
traceTcS String
"setImplicationStatus(not-all-solved) {" (Implication -> SDoc
forall a. Outputable a => a -> SDoc
ppr Implication
implic)
; implic <- Implication -> TcS Implication
neededEvVars Implication
implic
; let new_status | WantedConstraints -> Bool
insolubleWC WantedConstraints
pruned_wc = ImplicStatus
IC_Insoluble
| Bool
otherwise = ImplicStatus
IC_Unsolved
new_implic = Implication
implic { ic_status = new_status
, ic_wanted = pruned_wc }
; traceTcS "setImplicationStatus(not-all-solved) }" (ppr new_implic)
; return $ Just new_implic }
| Bool
otherwise
= do { String -> SDoc -> TcS ()
traceTcS String
"setImplicationStatus(all-solved) {" (Implication -> SDoc
forall a. Outputable a => a -> SDoc
ppr Implication
implic)
; implic@(Implic { ic_need_inner = need_inner
, ic_need_outer = need_outer }) <- Implication -> TcS Implication
neededEvVars Implication
implic
; bad_telescope <- checkBadTelescope implic
; let warn_givens = SkolemInfoAnon -> VarSet -> [TcTyVar] -> [TcTyVar]
findUnnecessaryGivens SkolemInfoAnon
info VarSet
need_inner [TcTyVar]
givens
discard_entire_implication
= [TcTyVar] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcTyVar]
warn_givens
Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
bad_telescope
Bool -> Bool -> Bool
&& WantedConstraints -> Bool
isEmptyWC WantedConstraints
pruned_wc
Bool -> Bool -> Bool
&& VarSet -> Bool
isEmptyVarSet VarSet
need_outer
final_status
| Bool
bad_telescope = ImplicStatus
IC_BadTelescope
| Bool
otherwise = IC_Solved { ics_dead :: [TcTyVar]
ics_dead = [TcTyVar]
warn_givens }
final_implic = Implication
implic { ic_status = final_status
, ic_wanted = pruned_wc }
; traceTcS "setImplicationStatus(all-solved) }" $
vcat [ text "discard:" <+> ppr discard_entire_implication
, text "new_implic:" <+> ppr final_implic ]
; return $ if discard_entire_implication
then Nothing
else Just final_implic }
where
WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics, wc_errors :: WantedConstraints -> Bag DelayedError
wc_errors = Bag DelayedError
errs } = WantedConstraints
wc
pruned_implics :: Bag Implication
pruned_implics = (Implication -> Bool) -> Bag Implication -> Bag Implication
forall a. (a -> Bool) -> Bag a -> Bag a
filterBag Implication -> Bool
keep_me Bag Implication
implics
pruned_wc :: WantedConstraints
pruned_wc = WC { wc_simple :: Cts
wc_simple = Cts
simples
, wc_impl :: Bag Implication
wc_impl = Bag Implication
pruned_implics
, wc_errors :: Bag DelayedError
wc_errors = Bag DelayedError
errs }
keep_me :: Implication -> Bool
keep_me :: Implication -> Bool
keep_me Implication
ic
| IC_Solved { ics_dead :: ImplicStatus -> [TcTyVar]
ics_dead = [TcTyVar]
dead_givens } <- Implication -> ImplicStatus
ic_status Implication
ic
, [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 (Implication -> WantedConstraints
ic_wanted Implication
ic))
= Bool
False
| Bool
otherwise
= Bool
True
findUnnecessaryGivens :: SkolemInfoAnon -> VarSet -> [EvVar] -> [EvVar]
findUnnecessaryGivens :: SkolemInfoAnon -> VarSet -> [TcTyVar] -> [TcTyVar]
findUnnecessaryGivens SkolemInfoAnon
info VarSet
need_inner [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
is_used :: TcTyVar -> Bool
is_used TcTyVar
given = TcTyVar -> Bool
is_type_error TcTyVar
given
Bool -> Bool -> Bool
|| TcTyVar
given TcTyVar -> VarSet -> Bool
`elemVarSet` VarSet
need_inner
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 -> VarSet -> Bool
`elemVarSet` [TcTyVar] -> VarSet
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)
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 :: VarSet -> [TcTyVar] -> Bool
go VarSet
_ [] = Bool
False
go VarSet
later_skols (TcTyVar
one_skol : [TcTyVar]
earlier_skols)
| TcType -> VarSet
tyCoVarsOfType (TcTyVar -> TcType
tyVarKind TcTyVar
one_skol) VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
later_skols
= Bool
True
| Bool
otherwise
= VarSet -> [TcTyVar] -> Bool
go (VarSet
later_skols VarSet -> TcTyVar -> VarSet
`extendVarSet` TcTyVar
one_skol) [TcTyVar]
earlier_skols
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 {}) = Bool
True
warnRedundantGivens SkolemInfoAnon
_ = Bool
False
neededEvVars :: Implication -> TcS Implication
neededEvVars :: Implication -> TcS Implication
neededEvVars implic :: Implication
implic@(Implic { ic_given :: Implication -> [TcTyVar]
ic_given = [TcTyVar]
givens
, 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_inner :: Implication -> VarSet
ic_need_inner = VarSet
old_needs })
= do { ev_binds <- EvBindsVar -> TcS EvBindMap
TcS.getTcEvBindsMap EvBindsVar
ev_binds_var
; tcvs <- TcS.getTcEvTyCoVars ev_binds_var
; let seeds1 = (Implication -> VarSet -> VarSet)
-> VarSet -> Bag Implication -> VarSet
forall a b. (a -> b -> b) -> b -> Bag a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Implication -> VarSet -> VarSet
add_implic_seeds VarSet
old_needs Bag Implication
implics
seeds2 = (EvBind -> VarSet -> VarSet) -> VarSet -> EvBindMap -> VarSet
forall a. (EvBind -> a -> a) -> a -> EvBindMap -> a
nonDetStrictFoldEvBindMap EvBind -> VarSet -> VarSet
add_wanted VarSet
seeds1 EvBindMap
ev_binds
seeds3 = VarSet
seeds2 VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
tcvs
need_inner = EvBindMap -> VarSet -> VarSet
findNeededEvVars EvBindMap
ev_binds VarSet
seeds3
live_ev_binds = (EvBind -> Bool) -> EvBindMap -> EvBindMap
filterEvBindMap (VarSet -> EvBind -> Bool
needed_ev_bind VarSet
need_inner) EvBindMap
ev_binds
need_outer = VarSet -> EvBindMap -> VarSet
varSetMinusEvBindMap VarSet
need_inner EvBindMap
live_ev_binds
VarSet -> [TcTyVar] -> VarSet
`delVarSetList` [TcTyVar]
givens
; TcS.setTcEvBindsMap ev_binds_var live_ev_binds
; traceTcS "neededEvVars" $
vcat [ text "old_needs:" <+> ppr old_needs
, text "seeds3:" <+> ppr seeds3
, text "tcvs:" <+> ppr tcvs
, text "ev_binds:" <+> ppr ev_binds
, text "live_ev_binds:" <+> ppr live_ev_binds ]
; return (implic { ic_need_inner = need_inner
, ic_need_outer = need_outer }) }
where
add_implic_seeds :: Implication -> VarSet -> VarSet
add_implic_seeds (Implic { ic_need_outer :: Implication -> VarSet
ic_need_outer = VarSet
needs }) VarSet
acc
= VarSet
needs VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
acc
needed_ev_bind :: VarSet -> EvBind -> Bool
needed_ev_bind VarSet
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 -> VarSet -> Bool
`elemVarSet` VarSet
needed
| Bool
otherwise = Bool
True
add_wanted :: EvBind -> VarSet -> VarSet
add_wanted :: EvBind -> VarSet -> VarSet
add_wanted (EvBind { eb_info :: EvBind -> EvBindInfo
eb_info = EvBindInfo
info, eb_rhs :: EvBind -> EvTerm
eb_rhs = EvTerm
rhs }) VarSet
needs
| EvBindGiven{} <- EvBindInfo
info = VarSet
needs
| Bool
otherwise = EvTerm -> VarSet
evVarsOfTerm EvTerm
rhs VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
needs
simplifyDelayedErrors :: Bag DelayedError -> TcS (Bag DelayedError)
simplifyDelayedErrors :: Bag DelayedError -> TcS (Bag DelayedError)
simplifyDelayedErrors = (DelayedError -> TcS DelayedError)
-> Bag DelayedError -> TcS (Bag DelayedError)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Bag a -> m (Bag b)
mapBagM DelayedError -> TcS DelayedError
simpl_err
where
simpl_err :: DelayedError -> TcS DelayedError
simpl_err :: DelayedError -> TcS DelayedError
simpl_err (DE_Hole Hole
hole) = Hole -> DelayedError
DE_Hole (Hole -> DelayedError) -> TcS Hole -> TcS 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 {}) = DelayedError -> TcS DelayedError
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return DelayedError
err
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' }) }
type UnificationDone = Bool
noUnification, didUnification :: UnificationDone
noUnification :: Bool
noUnification = Bool
False
didUnification :: Bool
didUnification = Bool
True
defaultTyVarTcS :: TcTyVar -> TcS UnificationDone
defaultTyVarTcS :: TcTyVar -> TcS Bool
defaultTyVarTcS TcTyVar
the_tv
| TcTyVar -> Bool
isTyVarTyVar TcTyVar
the_tv
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
noUnification
| TcTyVar -> Bool
isRuntimeRepVar TcTyVar
the_tv
= do { String -> SDoc -> TcS ()
traceTcS String
"defaultTyVarTcS RuntimeRep" (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
the_tv)
; TcTyVar -> TcType -> TcS ()
unifyTyVar TcTyVar
the_tv TcType
liftedRepTy
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
didUnification }
| TcTyVar -> Bool
isLevityVar TcTyVar
the_tv
= do { String -> SDoc -> TcS ()
traceTcS String
"defaultTyVarTcS Levity" (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
the_tv)
; TcTyVar -> TcType -> TcS ()
unifyTyVar TcTyVar
the_tv TcType
liftedDataConTy
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
didUnification }
| TcTyVar -> Bool
isMultiplicityVar TcTyVar
the_tv
= do { String -> SDoc -> TcS ()
traceTcS String
"defaultTyVarTcS Multiplicity" (TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
the_tv)
; TcTyVar -> TcType -> TcS ()
unifyTyVar TcTyVar
the_tv TcType
ManyTy
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
didUnification }
| Bool
otherwise
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
noUnification
approximateWC :: Bool
-> WantedConstraints
-> Cts
approximateWC :: Bool -> WantedConstraints -> Cts
approximateWC Bool
float_past_equalities WantedConstraints
wc
= Bool -> VarSet -> WantedConstraints -> Cts
float_wc Bool
False VarSet
emptyVarSet WantedConstraints
wc
where
float_wc :: Bool
-> TcTyCoVarSet
-> WantedConstraints -> Cts
float_wc :: Bool -> VarSet -> WantedConstraints -> Cts
float_wc Bool
encl_eqs VarSet
trapping_tvs (WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics })
= (Ct -> Bool) -> Cts -> Cts
forall a. (a -> Bool) -> Bag a -> Bag a
filterBag (Bool -> VarSet -> Ct -> Bool
is_floatable Bool
encl_eqs VarSet
trapping_tvs) Cts
simples Cts -> Cts -> Cts
forall a. Bag a -> Bag a -> Bag a
`unionBags`
(Implication -> Cts) -> Bag Implication -> Cts
forall a b. (a -> Bag b) -> Bag a -> Bag b
concatMapBag (Bool -> VarSet -> Implication -> Cts
float_implic Bool
encl_eqs VarSet
trapping_tvs) Bag Implication
implics
float_implic :: Bool -> TcTyCoVarSet -> Implication -> Cts
float_implic :: Bool -> VarSet -> Implication -> Cts
float_implic Bool
encl_eqs VarSet
trapping_tvs Implication
imp
= Bool -> VarSet -> WantedConstraints -> Cts
float_wc Bool
new_encl_eqs VarSet
new_trapping_tvs (Implication -> WantedConstraints
ic_wanted Implication
imp)
where
new_trapping_tvs :: VarSet
new_trapping_tvs = VarSet
trapping_tvs VarSet -> [TcTyVar] -> VarSet
`extendVarSetList` Implication -> [TcTyVar]
ic_skols Implication
imp
new_encl_eqs :: Bool
new_encl_eqs = Bool
encl_eqs Bool -> Bool -> Bool
|| Implication -> HasGivenEqs
ic_given_eqs Implication
imp HasGivenEqs -> HasGivenEqs -> Bool
forall a. Eq a => a -> a -> Bool
== HasGivenEqs
MaybeGivenEqs
is_floatable :: Bool -> VarSet -> Ct -> Bool
is_floatable Bool
encl_eqs VarSet
skol_tvs Ct
ct
| Ct -> Bool
isGivenCt Ct
ct = Bool
False
| Ct -> Bool
insolubleCt Ct
ct = Bool
False
| Ct -> VarSet
tyCoVarsOfCt Ct
ct VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
skol_tvs = Bool
False
| Bool
otherwise
= case TcType -> Pred
classifyPredType (Ct -> TcType
ctPred Ct
ct) of
EqPred {} -> Bool
float_past_equalities Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
encl_eqs
ClassPred {} -> Bool
True
IrredPred {} -> Bool
True
ForAllPred {} -> Bool
False
tryTypeClassDefaulting :: WantedConstraints -> TcS WantedConstraints
tryTypeClassDefaulting :: WantedConstraints -> TcS WantedConstraints
tryTypeClassDefaulting WantedConstraints
wc
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wc Bool -> Bool -> Bool
|| WantedConstraints -> Bool
insolubleWC WantedConstraints
wc
= WantedConstraints -> TcS WantedConstraints
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return WantedConstraints
wc
| Bool
otherwise
= do { something_happened <- WantedConstraints -> TcS Bool
applyDefaultingRules WantedConstraints
wc
; solveAgainIf something_happened wc }
applyDefaultingRules :: WantedConstraints -> TcS Bool
applyDefaultingRules :: WantedConstraints -> TcS Bool
applyDefaultingRules WantedConstraints
wanteds
| WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanteds
= Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
| Bool
otherwise
= do { (default_env, extended_rules) <- TcS (DefaultEnv, Bool)
getDefaultInfo
; wanteds <- TcS.zonkWC wanteds
; tcg_env <- TcS.getGblEnv
; let plugins = TcGblEnv -> [FillDefaulting]
tcg_defaulting_plugins TcGblEnv
tcg_env
default_tys = DefaultEnv -> [ClassDefaults]
defaultList DefaultEnv
default_env
; (wanteds, plugin_defaulted) <- if null plugins then return (wanteds, []) else
do {
; traceTcS "defaultingPlugins {" (ppr wanteds)
; (wanteds, defaultedGroups) <- mapAccumLM run_defaulting_plugin wanteds plugins
; traceTcS "defaultingPlugins }" (ppr defaultedGroups)
; return (wanteds, defaultedGroups)
}
; let groups = ([ClassDefaults], Bool) -> WantedConstraints -> [(TcTyVar, [Ct])]
findDefaultableGroups ([ClassDefaults]
default_tys, Bool
extended_rules) WantedConstraints
wanteds
; traceTcS "applyDefaultingRules {" $
vcat [ text "wanteds =" <+> ppr wanteds
, text "groups =" <+> ppr groups
, text "info =" <+> ppr (default_tys, extended_rules) ]
; something_happeneds <- mapM (disambigGroup wanteds default_tys) groups
; traceTcS "applyDefaultingRules }" (ppr something_happeneds)
; return $ or something_happeneds || or plugin_defaulted }
where
run_defaulting_plugin :: WantedConstraints
-> FillDefaulting -> TcS (WantedConstraints, Bool)
run_defaulting_plugin WantedConstraints
wanteds FillDefaulting
p
= do { groups <- TcPluginM [DefaultingProposal] -> TcS [DefaultingProposal]
forall a. TcPluginM a -> TcS a
runTcPluginTcS (FillDefaulting
p WantedConstraints
wanteds)
; defaultedGroups <-
filterM (\DefaultingProposal
g -> WantedConstraints -> [Ct] -> ProposalSequence -> TcS Bool
disambigMultiGroup
WantedConstraints
wanteds
(DefaultingProposal -> [Ct]
deProposalCts DefaultingProposal
g)
([Proposal] -> ProposalSequence
ProposalSequence ([(TcTyVar, TcType)] -> Proposal
Proposal ([(TcTyVar, TcType)] -> Proposal)
-> [[(TcTyVar, TcType)]] -> [Proposal]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DefaultingProposal -> [[(TcTyVar, TcType)]]
deProposals DefaultingProposal
g)))
groups
; traceTcS "defaultingPlugin " $ ppr defaultedGroups
; case defaultedGroups of
[] -> (WantedConstraints, Bool) -> TcS (WantedConstraints, Bool)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (WantedConstraints
wanteds, Bool
False)
[DefaultingProposal]
_ -> do
wanteds' <- WantedConstraints -> TcS WantedConstraints
TcS.zonkWC WantedConstraints
wanteds
return (wanteds', True) }
findDefaultableGroups
:: ( [ClassDefaults]
, Bool )
-> WantedConstraints
-> [(TyVar, [Ct])]
findDefaultableGroups :: ([ClassDefaults], Bool) -> WantedConstraints -> [(TcTyVar, [Ct])]
findDefaultableGroups ([ClassDefaults]
default_tys, Bool
extended_defaults) WantedConstraints
wanteds
| [ClassDefaults] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ClassDefaults]
default_tys
= []
| Bool
otherwise
= [ (TcTyVar
tv, ((Ct, Class, TcTyVar) -> Ct) -> [(Ct, Class, TcTyVar)] -> [Ct]
forall a b. (a -> b) -> [a] -> [b]
map (Ct, Class, TcTyVar) -> Ct
forall a b c. (a, b, c) -> a
fstOf3 [(Ct, Class, TcTyVar)]
group)
| group' :: NonEmpty (Ct, Class, TcTyVar)
group'@((Ct
_,Class
_,TcTyVar
tv) :| [(Ct, Class, TcTyVar)]
_) <- [NonEmpty (Ct, Class, TcTyVar)]
unary_groups
, let group :: [(Ct, Class, TcTyVar)]
group = NonEmpty (Ct, Class, TcTyVar) -> [(Ct, Class, TcTyVar)]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (Ct, Class, TcTyVar)
group'
, TcTyVar -> Bool
defaultable_tyvar TcTyVar
tv
, [TyCon] -> Bool
defaultable_classes (((Ct, Class, TcTyVar) -> TyCon)
-> [(Ct, Class, TcTyVar)] -> [TyCon]
forall a b. (a -> b) -> [a] -> [b]
map (Class -> TyCon
classTyCon (Class -> TyCon)
-> ((Ct, Class, TcTyVar) -> Class) -> (Ct, Class, TcTyVar) -> TyCon
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ct, Class, TcTyVar) -> Class
forall a b c. (a, b, c) -> b
sndOf3) [(Ct, Class, TcTyVar)]
group) ]
where
simples :: Cts
simples = Bool -> WantedConstraints -> Cts
approximateWC Bool
True WantedConstraints
wanteds
([(Ct, Class, TcTyVar)]
unaries, [Ct]
non_unaries) = (Ct -> Either (Ct, Class, TcTyVar) Ct)
-> [Ct] -> ([(Ct, Class, TcTyVar)], [Ct])
forall a b c. (a -> Either b c) -> [a] -> ([b], [c])
partitionWith Ct -> Either (Ct, Class, TcTyVar) Ct
find_unary (Cts -> [Ct]
forall a. Bag a -> [a]
bagToList Cts
simples)
unary_groups :: [NonEmpty (Ct, Class, TcTyVar)]
unary_groups = ((Ct, Class, TcTyVar) -> (Ct, Class, TcTyVar) -> Ordering)
-> [(Ct, Class, TcTyVar)] -> [NonEmpty (Ct, Class, TcTyVar)]
forall a. (a -> a -> Ordering) -> [a] -> [NonEmpty a]
equivClasses (Ct, Class, TcTyVar) -> (Ct, Class, TcTyVar) -> Ordering
forall {a} {a} {b} {a} {b}.
Ord a =>
(a, b, a) -> (a, b, a) -> Ordering
cmp_tv [(Ct, Class, TcTyVar)]
unaries
unary_groups :: [NonEmpty (Ct, Class, TcTyVar)]
unaries :: [(Ct, Class, TcTyVar)]
non_unaries :: [Ct]
find_unary :: Ct -> Either (Ct, Class, TyVar) Ct
find_unary :: Ct -> Either (Ct, Class, TcTyVar) Ct
find_unary Ct
cc
| Just (Class
cls,[TcType]
tys) <- TcType -> Maybe (Class, [TcType])
getClassPredTys_maybe (Ct -> TcType
ctPred Ct
cc)
, [TcType
ty] <- TyCon -> [TcType] -> [TcType]
filterOutInvisibleTypes (Class -> TyCon
classTyCon Class
cls) [TcType]
tys
, Just TcTyVar
tv <- TcType -> Maybe TcTyVar
getTyVar_maybe TcType
ty
, TcTyVar -> Bool
isMetaTyVar TcTyVar
tv
= (Ct, Class, TcTyVar) -> Either (Ct, Class, TcTyVar) Ct
forall a b. a -> Either a b
Left (Ct
cc, Class
cls, TcTyVar
tv)
find_unary Ct
cc = Ct -> Either (Ct, Class, TcTyVar) Ct
forall a b. b -> Either a b
Right Ct
cc
bad_tvs :: TcTyCoVarSet
bad_tvs :: VarSet
bad_tvs = (Ct -> VarSet) -> [Ct] -> VarSet
forall a. (a -> VarSet) -> [a] -> VarSet
mapUnionVarSet Ct -> VarSet
tyCoVarsOfCt [Ct]
non_unaries
cmp_tv :: (a, b, a) -> (a, b, a) -> Ordering
cmp_tv (a
_,b
_,a
tv1) (a
_,b
_,a
tv2) = a
tv1 a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` a
tv2
defaultable_tyvar :: TcTyVar -> Bool
defaultable_tyvar :: TcTyVar -> Bool
defaultable_tyvar TcTyVar
tv
= let b1 :: Bool
b1 = TcTyVar -> Bool
isTyConableTyVar TcTyVar
tv
b2 :: Bool
b2 = Bool -> Bool
not (TcTyVar
tv TcTyVar -> VarSet -> Bool
`elemVarSet` VarSet
bad_tvs)
in Bool
b1 Bool -> Bool -> Bool
&& (Bool
b2 Bool -> Bool -> Bool
|| Bool
extended_defaults)
defaultable_classes :: [TyCon] -> Bool
defaultable_classes :: [TyCon] -> Bool
defaultable_classes [TyCon]
clss = Bool -> Bool
not (Bool -> Bool) -> ([TyCon] -> Bool) -> [TyCon] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TyCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([TyCon] -> Bool) -> ([TyCon] -> [TyCon]) -> [TyCon] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TyCon] -> [TyCon] -> [TyCon]
forall a. Eq a => [a] -> [a] -> [a]
intersect [TyCon]
clss ([TyCon] -> Bool) -> [TyCon] -> Bool
forall a b. (a -> b) -> a -> b
$ (ClassDefaults -> TyCon) -> [ClassDefaults] -> [TyCon]
forall a b. (a -> b) -> [a] -> [b]
map ClassDefaults -> TyCon
cd_class [ClassDefaults]
default_tys
newtype ProposalSequence = ProposalSequence{ProposalSequence -> [Proposal]
getProposalSequence :: [Proposal]}
newtype Proposal = Proposal [(TcTyVar, Type)]
instance Outputable ProposalSequence where
ppr :: ProposalSequence -> SDoc
ppr (ProposalSequence [Proposal]
proposals) = [Proposal] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Proposal]
proposals
instance Outputable Proposal where
ppr :: Proposal -> SDoc
ppr (Proposal [(TcTyVar, TcType)]
assignments) = [(TcTyVar, TcType)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(TcTyVar, TcType)]
assignments
disambigGroup :: WantedConstraints
-> [ClassDefaults]
-> (TcTyVar, [Ct])
-> TcS Bool
disambigGroup :: WantedConstraints -> [ClassDefaults] -> (TcTyVar, [Ct]) -> TcS Bool
disambigGroup WantedConstraints
orig_wanteds [ClassDefaults]
default_ctys (TcTyVar
tv, [Ct]
wanteds)
= WantedConstraints
-> [Ct]
-> [ProposalSequence]
-> (NonEmpty ([TcTyVar], Subst) -> Bool)
-> TcS Bool
disambigProposalSequences WantedConstraints
orig_wanteds [Ct]
wanteds [ProposalSequence]
proposalSequences NonEmpty ([TcTyVar], Subst) -> Bool
allConsistent
where
proposalSequences :: [ProposalSequence]
proposalSequences = [ [Proposal] -> ProposalSequence
ProposalSequence [[(TcTyVar, TcType)] -> Proposal
Proposal [(TcTyVar
tv, TcType
ty)] | TcType
ty <- [TcType]
tys]
| ClassDefaults{cd_types :: ClassDefaults -> [TcType]
cd_types = [TcType]
tys} <- [ClassDefaults]
defaultses ]
allConsistent :: NonEmpty ([TcTyVar], Subst) -> Bool
allConsistent (([TcTyVar]
_, Subst
sub) :| [([TcTyVar], Subst)]
subs) = (([TcTyVar], Subst) -> Bool) -> [([TcTyVar], Subst)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (TcTyVar -> Subst -> Subst -> Bool
eqSubAt TcTyVar
tv Subst
sub (Subst -> Bool)
-> (([TcTyVar], Subst) -> Subst) -> ([TcTyVar], Subst) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([TcTyVar], Subst) -> Subst
forall a b. (a, b) -> b
snd) [([TcTyVar], Subst)]
subs
defaultses :: [ClassDefaults]
defaultses =
[ ClassDefaults
defaults | defaults :: ClassDefaults
defaults@ClassDefaults{cd_class :: ClassDefaults -> TyCon
cd_class = TyCon
cls} <- [ClassDefaults]
default_ctys
, (Ct -> Bool) -> [Ct] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (TyCon -> Ct -> Bool
isDictForClass TyCon
cls) [Ct]
wanteds ]
isDictForClass :: TyCon -> Ct -> Bool
isDictForClass TyCon
clcon Ct
ct = ((Class, [TcType]) -> Bool) -> Maybe (Class, [TcType]) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((TyCon
clcon TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
==) (TyCon -> Bool)
-> ((Class, [TcType]) -> TyCon) -> (Class, [TcType]) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> TyCon
classTyCon (Class -> TyCon)
-> ((Class, [TcType]) -> Class) -> (Class, [TcType]) -> TyCon
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Class, [TcType]) -> Class
forall a b. (a, b) -> a
fst) (TcType -> Maybe (Class, [TcType])
getClassPredTys_maybe (TcType -> Maybe (Class, [TcType]))
-> TcType -> Maybe (Class, [TcType])
forall a b. (a -> b) -> a -> b
$ Ct -> TcType
ctPred Ct
ct)
eqSubAt :: TcTyVar -> Subst -> Subst -> Bool
eqSubAt :: TcTyVar -> Subst -> Subst -> Bool
eqSubAt TcTyVar
tvar Subst
s1 Subst
s2 = Maybe Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (TcType -> TcType -> Bool)
-> Maybe TcType -> Maybe TcType -> Maybe Bool
forall a b c. (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
tcEqType (Subst -> TcTyVar -> Maybe TcType
lookupTyVar Subst
s1 TcTyVar
tvar) (Subst -> TcTyVar -> Maybe TcType
lookupTyVar Subst
s2 TcTyVar
tvar)
disambigMultiGroup :: WantedConstraints
-> [Ct]
-> ProposalSequence
-> TcS Bool
disambigMultiGroup :: WantedConstraints -> [Ct] -> ProposalSequence -> TcS Bool
disambigMultiGroup WantedConstraints
orig_wanteds [Ct]
wanteds ProposalSequence
proposalSequence
= WantedConstraints
-> [Ct]
-> [ProposalSequence]
-> (NonEmpty ([TcTyVar], Subst) -> Bool)
-> TcS Bool
disambigProposalSequences WantedConstraints
orig_wanteds [Ct]
wanteds [ProposalSequence
proposalSequence] (Bool -> NonEmpty ([TcTyVar], Subst) -> Bool
forall a b. a -> b -> a
const Bool
True)
disambigProposalSequences :: WantedConstraints
-> [Ct]
-> [ProposalSequence]
-> (NonEmpty ([TcTyVar], Subst) -> Bool)
-> TcS Bool
disambigProposalSequences :: WantedConstraints
-> [Ct]
-> [ProposalSequence]
-> (NonEmpty ([TcTyVar], Subst) -> Bool)
-> TcS Bool
disambigProposalSequences WantedConstraints
orig_wanteds [Ct]
wanteds [ProposalSequence]
proposalSequences NonEmpty ([TcTyVar], Subst) -> Bool
allConsistent
= do { (ProposalSequence -> TcS ()) -> [ProposalSequence] -> TcS ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((Proposal -> TcS ()) -> [Proposal] -> TcS ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Proposal -> TcS ()
reportInvalidDefaultedTyVars ([Proposal] -> TcS ())
-> (ProposalSequence -> [Proposal]) -> ProposalSequence -> TcS ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProposalSequence -> [Proposal]
getProposalSequence) [ProposalSequence]
proposalSequences
; fake_ev_binds_var <- TcS EvBindsVar
TcS.newTcEvBinds
; tclvl <- TcS.getTcLevel
; successes <- fmap catMaybes $
nestImplicTcS fake_ev_binds_var (pushTcLevel tclvl) $
mapM firstSuccess proposalSequences
; traceTcS "disambigProposalSequences" (vcat [ ppr wanteds
, ppr proposalSequences
, ppr successes ])
; case successes of
success :: ([TcTyVar], Subst)
success@([TcTyVar]
tvs, Subst
subst) : [([TcTyVar], Subst)]
rest
| NonEmpty ([TcTyVar], Subst) -> Bool
allConsistent (([TcTyVar], Subst)
success ([TcTyVar], Subst)
-> [([TcTyVar], Subst)] -> NonEmpty ([TcTyVar], Subst)
forall a. a -> [a] -> NonEmpty a
:| [([TcTyVar], Subst)]
rest)
-> do { [TcTyVar] -> Subst -> TcS ()
applyDefaultSubst [TcTyVar]
tvs Subst
subst
; let warn :: TcTyVar -> TcM ()
warn TcTyVar
tv = (TcType -> TcM ()) -> Maybe TcType -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ([Ct] -> TcTyVar -> TcType -> TcM ()
warnDefaulting [Ct]
wanteds TcTyVar
tv) (Subst -> TcTyVar -> Maybe TcType
lookupTyVar Subst
subst TcTyVar
tv)
; TcM () -> TcS ()
forall a. TcM a -> TcS a
wrapWarnTcS (TcM () -> TcS ()) -> TcM () -> TcS ()
forall a b. (a -> b) -> a -> b
$ (TcTyVar -> TcM ()) -> [TcTyVar] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ TcTyVar -> TcM ()
warn [TcTyVar]
tvs
; String -> SDoc -> TcS ()
traceTcS String
"disambigProposalSequences succeeded }" ([ProposalSequence] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ProposalSequence]
proposalSequences)
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True }
[([TcTyVar], Subst)]
_ ->
do { String -> SDoc -> TcS ()
traceTcS String
"disambigProposalSequences failed }" ([ProposalSequence] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ProposalSequence]
proposalSequences)
; Bool -> TcS Bool
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False } }
where
reportInvalidDefaultedTyVars :: Proposal -> TcS ()
firstSuccess :: ProposalSequence -> TcS (Maybe ([TcTyVar], Subst))
firstSuccess :: ProposalSequence -> TcS (Maybe ([TcTyVar], Subst))
firstSuccess (ProposalSequence [Proposal]
proposals)
= First ([TcTyVar], Subst) -> Maybe ([TcTyVar], Subst)
forall a. First a -> Maybe a
getFirst (First ([TcTyVar], Subst) -> Maybe ([TcTyVar], Subst))
-> TcS (First ([TcTyVar], Subst)) -> TcS (Maybe ([TcTyVar], Subst))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Proposal -> TcS (First ([TcTyVar], Subst)))
-> [Proposal] -> TcS (First ([TcTyVar], Subst))
forall (m :: * -> *) (t :: * -> *) b a.
(Applicative m, Foldable t, Monoid b) =>
(a -> m b) -> t a -> m b
foldMapM ((Maybe ([TcTyVar], Subst) -> First ([TcTyVar], Subst))
-> TcS (Maybe ([TcTyVar], Subst)) -> TcS (First ([TcTyVar], Subst))
forall a b. (a -> b) -> TcS a -> TcS b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe ([TcTyVar], Subst) -> First ([TcTyVar], Subst)
forall a. Maybe a -> First a
First (TcS (Maybe ([TcTyVar], Subst)) -> TcS (First ([TcTyVar], Subst)))
-> (Proposal -> TcS (Maybe ([TcTyVar], Subst)))
-> Proposal
-> TcS (First ([TcTyVar], Subst))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ct] -> Proposal -> TcS (Maybe ([TcTyVar], Subst))
tryDefaultGroup [Ct]
wanteds) [Proposal]
proposals
reportInvalidDefaultedTyVars :: Proposal -> TcS ()
reportInvalidDefaultedTyVars proposal :: Proposal
proposal@(Proposal [(TcTyVar, TcType)]
assignments)
= do { let tvs :: [TcTyVar]
tvs = (TcTyVar, TcType) -> TcTyVar
forall a b. (a, b) -> a
fst ((TcTyVar, TcType) -> TcTyVar) -> [(TcTyVar, TcType)] -> [TcTyVar]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(TcTyVar, TcType)]
assignments
; invalid_tvs <- (TcTyVar -> TcS Bool) -> [TcTyVar] -> TcS [TcTyVar]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterOutM TcTyVar -> TcS Bool
TcS.isUnfilledMetaTyVar [TcTyVar]
tvs
; traverse_ (errInvalidDefaultedTyVar orig_wanteds proposal) (nonEmpty invalid_tvs) }
applyDefaultSubst :: [TcTyVar] -> Subst -> TcS ()
applyDefaultSubst :: [TcTyVar] -> Subst -> TcS ()
applyDefaultSubst [TcTyVar]
tvs Subst
subst =
do { deep_tvs <- (TcTyVar -> TcS Bool) -> [TcTyVar] -> TcS [TcTyVar]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM TcTyVar -> TcS Bool
TcS.isUnfilledMetaTyVar ([TcTyVar] -> TcS [TcTyVar]) -> [TcTyVar] -> TcS [TcTyVar]
forall a b. (a -> b) -> a -> b
$ VarSet -> [TcTyVar]
forall elt. UniqSet elt -> [elt]
nonDetEltsUniqSet (VarSet -> [TcTyVar]) -> VarSet -> [TcTyVar]
forall a b. (a -> b) -> a -> b
$ VarSet -> VarSet
closeOverKinds ([TcTyVar] -> VarSet
mkVarSet [TcTyVar]
tvs)
; forM_ deep_tvs $ \ TcTyVar
tv -> (TcType -> TcS ()) -> Maybe TcType -> TcS ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (TcTyVar -> TcType -> TcS ()
unifyTyVar TcTyVar
tv) (VarEnv TcType -> TcTyVar -> Maybe TcType
forall a. VarEnv a -> TcTyVar -> Maybe a
lookupVarEnv (Subst -> VarEnv TcType
getTvSubstEnv Subst
subst) TcTyVar
tv)
}
tryDefaultGroup :: [Ct]
-> Proposal
-> TcS (Maybe ([TcTyVar], Subst))
tryDefaultGroup :: [Ct] -> Proposal -> TcS (Maybe ([TcTyVar], Subst))
tryDefaultGroup [Ct]
wanteds (Proposal [(TcTyVar, TcType)]
assignments)
| let ([TcTyVar]
tvs, [TcType]
default_tys) = [(TcTyVar, TcType)] -> ([TcTyVar], [TcType])
forall a b. [(a, b)] -> ([a], [b])
unzip [(TcTyVar, TcType)]
assignments
, Just Subst
subst <- [TcType] -> [TcType] -> Maybe Subst
tcMatchTyKis ([TcTyVar] -> [TcType]
mkTyVarTys [TcTyVar]
tvs) [TcType]
default_tys
= do { lcl_env <- TcS TcLclEnv
TcS.getLclEnv
; tc_lvl <- TcS.getTcLevel
; let loc = TcLevel -> SkolemInfoAnon -> CtLocEnv -> CtLoc
mkGivenLoc TcLevel
tc_lvl (SkolemInfo -> SkolemInfoAnon
getSkolemInfo SkolemInfo
HasDebugCallStack => SkolemInfo
unkSkol) (TcLclEnv -> CtLocEnv
mkCtLocEnv TcLclEnv
lcl_env)
; wanted_evs <- sequence [ newWantedNC loc rewriters pred'
| wanted <- wanteds
, CtWanted { ctev_pred = pred
, ctev_rewriters = rewriters }
<- return (ctEvidence wanted)
, let pred' = HasDebugCallStack => Subst -> TcType -> TcType
Subst -> TcType -> TcType
substTy Subst
subst TcType
pred ]
; residual_wc <- solveSimpleWanteds $ listToBag $ map mkNonCanonical wanted_evs
; return $ if isEmptyWC residual_wc then Just (tvs, subst) else Nothing }
| Bool
otherwise
= Maybe ([TcTyVar], Subst) -> TcS (Maybe ([TcTyVar], Subst))
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ([TcTyVar], Subst)
forall a. Maybe a
Nothing
errInvalidDefaultedTyVar :: WantedConstraints -> Proposal -> NonEmpty TcTyVar -> TcS ()
errInvalidDefaultedTyVar :: WantedConstraints -> Proposal -> NonEmpty TcTyVar -> TcS ()
errInvalidDefaultedTyVar WantedConstraints
wanteds (Proposal [(TcTyVar, TcType)]
assignments) NonEmpty TcTyVar
problematic_tvs
= TcRnMessage -> TcS ()
forall a. TcRnMessage -> TcS a
failTcS (TcRnMessage -> TcS ()) -> TcRnMessage -> TcS ()
forall a b. (a -> b) -> a -> b
$ [Ct] -> [(TcTyVar, TcType)] -> NonEmpty TcTyVar -> TcRnMessage
TcRnInvalidDefaultedTyVar [Ct]
tidy_wanteds [(TcTyVar, TcType)]
tidy_assignments NonEmpty TcTyVar
tidy_problems
where
proposal_tvs :: [TcTyVar]
proposal_tvs = ((TcTyVar, TcType) -> [TcTyVar])
-> [(TcTyVar, TcType)] -> [TcTyVar]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(TcTyVar
tv, TcType
ty) -> TcTyVar
tv TcTyVar -> [TcTyVar] -> [TcTyVar]
forall a. a -> [a] -> [a]
: TcType -> [TcTyVar]
tyCoVarsOfTypeList TcType
ty) [(TcTyVar, TcType)]
assignments
tidy_env :: TidyEnv
tidy_env = TidyEnv -> [TcTyVar] -> TidyEnv
tidyFreeTyCoVars TidyEnv
emptyTidyEnv ([TcTyVar] -> TidyEnv) -> [TcTyVar] -> TidyEnv
forall a b. (a -> b) -> a -> b
$ [TcTyVar]
proposal_tvs [TcTyVar] -> [TcTyVar] -> [TcTyVar]
forall a. [a] -> [a] -> [a]
++ NonEmpty TcTyVar -> [TcTyVar]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty TcTyVar
problematic_tvs
tidy_wanteds :: [Ct]
tidy_wanteds = (Ct -> Ct) -> [Ct] -> [Ct]
forall a b. (a -> b) -> [a] -> [b]
map (TidyEnv -> Ct -> Ct
tidyCt TidyEnv
tidy_env) ([Ct] -> [Ct]) -> [Ct] -> [Ct]
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> [Ct]
flattenWC WantedConstraints
wanteds
tidy_assignments :: [(TcTyVar, TcType)]
tidy_assignments = [(TidyEnv -> TcTyVar -> TcTyVar
tidyTyCoVarOcc TidyEnv
tidy_env TcTyVar
tv, TidyEnv -> TcType -> TcType
tidyType TidyEnv
tidy_env TcType
ty) | (TcTyVar
tv, TcType
ty) <- [(TcTyVar, TcType)]
assignments]
tidy_problems :: NonEmpty TcTyVar
tidy_problems = (TcTyVar -> TcTyVar) -> NonEmpty TcTyVar -> NonEmpty TcTyVar
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TidyEnv -> TcTyVar -> TcTyVar
tidyTyCoVarOcc TidyEnv
tidy_env) NonEmpty TcTyVar
problematic_tvs
flattenWC :: WantedConstraints -> [Ct]
flattenWC :: WantedConstraints -> [Ct]
flattenWC (WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
cts, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
impls })
= Cts -> [Ct]
ctsElts Cts
cts [Ct] -> [Ct] -> [Ct]
forall a. [a] -> [a] -> [a]
++ (Implication -> [Ct]) -> Bag Implication -> [Ct]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (WantedConstraints -> [Ct]
flattenWC (WantedConstraints -> [Ct])
-> (Implication -> WantedConstraints) -> Implication -> [Ct]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Implication -> WantedConstraints
ic_wanted) Bag Implication
impls
isInteractiveClass :: Bool
-> Class -> Bool
isInteractiveClass :: Bool -> Class -> Bool
isInteractiveClass Bool
ovl_strings Class
cls
= Bool -> Class -> Bool
isNumClass Bool
ovl_strings Class
cls Bool -> Bool -> Bool
|| (Class -> Unique
classKey Class
cls Unique -> [Unique] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Unique]
interactiveClassKeys)
isNumClass :: Bool
-> Class -> Bool
isNumClass :: Bool -> Class -> Bool
isNumClass Bool
ovl_strings Class
cls
= Class -> Bool
isNumericClass Class
cls Bool -> Bool -> Bool
|| (Bool
ovl_strings Bool -> Bool -> Bool
&& (Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
isStringClassKey))