summaryrefslogtreecommitdiff
path: root/compiler/typecheck/TcInteract.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/typecheck/TcInteract.hs')
-rw-r--r--compiler/typecheck/TcInteract.hs44
1 files changed, 41 insertions, 3 deletions
diff --git a/compiler/typecheck/TcInteract.hs b/compiler/typecheck/TcInteract.hs
index 1771e19849..3914db6c13 100644
--- a/compiler/typecheck/TcInteract.hs
+++ b/compiler/typecheck/TcInteract.hs
@@ -39,6 +39,7 @@ import TcSMonad
import Bag
import MonadUtils ( concatMapM, foldlM )
+import CoreSyn
import Data.List( partition, foldl', deleteFirstsBy )
import SrcLoc
import VarEnv
@@ -1827,14 +1828,51 @@ doTopReactOther :: Ct -> TcS (StopOrContinue Ct)
-- Why equalities? See TcCanonical
-- Note [Equality superclasses in quantified constraints]
doTopReactOther work_item
- = do { res <- matchLocalInst pred (ctEvLoc ev)
+ | isGiven ev
+ = continueWith work_item
+
+ | EqPred eq_rel t1 t2 <- classifyPredType pred
+ = -- See Note [Looking up primitive equalities in quantified constraints]
+ case boxEqPred eq_rel t1 t2 of
+ Nothing -> continueWith work_item
+ Just (cls, tys)
+ -> do { res <- matchLocalInst (mkClassPred cls tys) loc
+ ; case res of
+ OneInst { cir_mk_ev = mk_ev }
+ -> chooseInstance work_item
+ (res { cir_mk_ev = mk_eq_ev cls tys mk_ev })
+ where
+ _ -> continueWith work_item }
+
+ | otherwise
+ = do { res <- matchLocalInst pred loc
; case res of
OneInst {} -> chooseInstance work_item res
_ -> continueWith work_item }
where
ev = ctEvidence work_item
+ loc = ctEvLoc ev
pred = ctEvPred ev
+ mk_eq_ev cls tys mk_ev evs
+ = case (mk_ev evs) of
+ EvExpr e -> EvExpr (Var sc_id `mkTyApps` tys `App` e)
+ ev -> pprPanic "mk_eq_ev" (ppr ev)
+ where
+ [sc_id] = classSCSelIds cls
+
+{- Note [Looking up primitive equalities in quantified constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For equalities (a ~# b) look up (a ~ b), and then do a superclass
+selection. This avoids having to support quantified constraints whose
+kind is not Constraint, such as (forall a. F a ~# b)
+
+See
+ * Note [Evidence for quantified constraints] in Type
+ * Note [Equality superclasses in quantified constraints]
+ in TcCanonical
+-}
+
--------------------
doTopReactFunEq :: Ct -> TcS (StopOrContinue Ct)
doTopReactFunEq work_item@(CFunEqCan { cc_ev = old_ev, cc_fun = fam_tc
@@ -2539,8 +2577,8 @@ nullary case of what's happening here.
-}
matchLocalInst :: TcPredType -> CtLoc -> TcS ClsInstResult
--- Try any Given quantified constraints, which are
--- effectively just local instance declarations.
+-- Look up the predicate in Given quantified constraints,
+-- which are effectively just local instance declarations.
matchLocalInst pred loc
= do { ics <- getInertCans
; case match_local_inst (inert_insts ics) of