summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Solver/InertSet.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Tc/Solver/InertSet.hs')
-rw-r--r--compiler/GHC/Tc/Solver/InertSet.hs29
1 files changed, 24 insertions, 5 deletions
diff --git a/compiler/GHC/Tc/Solver/InertSet.hs b/compiler/GHC/Tc/Solver/InertSet.hs
index 4ad07a58d4..c5252fb09a 100644
--- a/compiler/GHC/Tc/Solver/InertSet.hs
+++ b/compiler/GHC/Tc/Solver/InertSet.hs
@@ -241,7 +241,7 @@ data InertSet
, inert_cycle_breakers :: [(TcTyVar, TcType)]
-- a list of CycleBreakerTv / original family applications
-- used to undo the cycle-breaking needed to handle
- -- Note [Type variable cycles in Givens] in GHC.Tc.Solver.Canonical
+ -- Note [Type variable cycles] in GHC.Tc.Solver.Canonical
, inert_famapp_cache :: FunEqMap (TcCoercion, TcType)
-- Just a hash-cons cache for use when reducing family applications
@@ -277,7 +277,8 @@ emptyInertCans
, inert_safehask = emptyDictMap
, inert_funeqs = emptyFunEqs
, inert_insts = []
- , inert_irreds = emptyCts }
+ , inert_irreds = emptyCts
+ , inert_blocked = emptyCts }
emptyInert :: InertSet
emptyInert
@@ -839,7 +840,7 @@ The idea is that
with S(fw,_).
* T3 is guaranteed by an occurs-check on the work item.
- This is done during canonicalisation, in canEqOK and checkTypeEq; invariant
+ This is done during canonicalisation, in checkTypeEq; invariant
(TyEq:OC) of CEqCan. See also Note [CEqCan occurs check] in GHC.Tc.Types.Constraint.
* (K1-3) are the "kick-out" criteria. (As stated, they are really the
@@ -1101,6 +1102,14 @@ data InertCans -- See Note [Detailed InertCans Invariants] for more
-- and which don't interact with others (e.g. (c a))
-- and insoluble predicates (e.g. Int ~ Bool, or a ~ [a])
+ , inert_blocked :: Cts
+ -- Equality predicates blocked on a coercion hole.
+ -- Each Ct is a CIrredCan with cc_reason = HoleBlockerReason
+ -- See Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical
+ -- wrinkle (2)
+ -- These are stored separately from inert_irreds because
+ -- they get kicked out for different reasons
+
, inert_given_eq_lvl :: TcLevel
-- The TcLevel of the innermost implication that has a Given
-- equality of the sort that make a unification variable untouchable
@@ -1119,8 +1128,11 @@ type InertEqs = DTyVarEnv EqualCtList
instance Outputable InertCans where
ppr (IC { inert_eqs = eqs
- , inert_funeqs = funeqs, inert_dicts = dicts
- , inert_safehask = safehask, inert_irreds = irreds
+ , inert_funeqs = funeqs
+ , inert_dicts = dicts
+ , inert_safehask = safehask
+ , inert_irreds = irreds
+ , inert_blocked = blocked
, inert_given_eq_lvl = ge_lvl
, inert_given_eqs = given_eqs
, inert_insts = insts })
@@ -1137,6 +1149,8 @@ instance Outputable InertCans where
text "Safe Haskell unsafe overlap =" <+> pprCts (dictsToBag safehask)
, ppUnless (isEmptyCts irreds) $
text "Irreds =" <+> pprCts irreds
+ , ppUnless (isEmptyCts blocked) $
+ text "Blocked =" <+> pprCts blocked
, ppUnless (null insts) $
text "Given instances =" <+> vcat (map ppr insts)
, text "Innermost given equalities =" <+> ppr ge_lvl
@@ -1210,6 +1224,11 @@ addInertItem tc_lvl
TyFamLHS tc tys -> ics { inert_funeqs = addCanFunEq funeqs tc tys item }
TyVarLHS tv -> ics { inert_eqs = addTyEq eqs tv item }
+addInertItem tc_lvl ics@(IC { inert_blocked = blocked })
+ item@(CIrredCan { cc_reason = HoleBlockerReason {}})
+ = updateGivenEqs tc_lvl item $ -- this item is always an equality
+ ics { inert_blocked = blocked `snocBag` item }
+
addInertItem tc_lvl ics@(IC { inert_irreds = irreds }) item@(CIrredCan {})
= updateGivenEqs tc_lvl item $ -- An Irred might turn out to be an
-- equality, so we play safe