summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim Breitner <mail@joachim-breitner.de>2018-01-21 09:03:00 -0500
committerJoachim Breitner <mail@joachim-breitner.de>2018-01-22 19:37:17 -0500
commit51d5533979e7a189c21da544996c207a31da047e (patch)
tree1b78da116a2313d586ca5e3d06cbedf2aee7e795
parent071962d30c9ac5d9ee0dedc5df0d6ce3d2e1bc0a (diff)
downloadhaskell-51d5533979e7a189c21da544996c207a31da047e.tar.gz
Remove EvCallStack
and move code from the desugarer into the type checker. Also, use EvExpr instead of EvTerm where possible (i.e. where no EvTypeable has to reach).
-rw-r--r--compiler/deSugar/DsBinds.hs47
-rw-r--r--compiler/typecheck/TcCanonical.hs13
-rw-r--r--compiler/typecheck/TcErrors.hs4
-rw-r--r--compiler/typecheck/TcEvTerm.hs44
-rw-r--r--compiler/typecheck/TcEvidence.hs18
-rw-r--r--compiler/typecheck/TcFlatten.hs2
-rw-r--r--compiler/typecheck/TcHsSyn.hs7
-rw-r--r--compiler/typecheck/TcInteract.hs14
-rw-r--r--compiler/typecheck/TcSMonad.hs6
9 files changed, 66 insertions, 89 deletions
diff --git a/compiler/deSugar/DsBinds.hs b/compiler/deSugar/DsBinds.hs
index c093f210d2..e912a369b3 100644
--- a/compiler/deSugar/DsBinds.hs
+++ b/compiler/deSugar/DsBinds.hs
@@ -1155,7 +1155,6 @@ dsEvBind (EvBind { eb_lhs = v, eb_rhs = r}) = liftM ((,) v) (dsEvTerm r)
dsEvTerm :: EvTerm -> DsM CoreExpr
dsEvTerm (EvExpr e) = return e
-dsEvTerm (EvCallStack ty cs) = dsEvCallStack ty cs
dsEvTerm (EvTypeable ty ev) = dsEvTypeable ty ev
{-**********************************************************************
@@ -1278,49 +1277,3 @@ tyConRep tc
; return (Var tc_rep_id) }
| otherwise
= pprPanic "tyConRep" (ppr tc)
-
-{-**********************************************************************
-* *
- Desugaring EvCallStack evidence
-* *
-**********************************************************************-}
-
-dsEvCallStack :: PredType -> EvCallStack -> DsM CoreExpr
--- See Note [Overview of implicit CallStacks] in TcEvidence.hs
-dsEvCallStack ty cs = do
- df <- getDynFlags
- m <- getModule
- srcLocDataCon <- dsLookupDataCon srcLocDataConName
- let mkSrcLoc l =
- liftM (mkCoreConApps srcLocDataCon)
- (sequence [ mkStringExprFS (unitIdFS $ moduleUnitId m)
- , mkStringExprFS (moduleNameFS $ moduleName m)
- , mkStringExprFS (srcSpanFile l)
- , return $ mkIntExprInt df (srcSpanStartLine l)
- , return $ mkIntExprInt df (srcSpanStartCol l)
- , return $ mkIntExprInt df (srcSpanEndLine l)
- , return $ mkIntExprInt df (srcSpanEndCol l)
- ])
-
- emptyCS <- Var <$> dsLookupGlobalId emptyCallStackName
-
- pushCSVar <- dsLookupGlobalId pushCallStackName
- let pushCS name loc rest =
- mkCoreApps (Var pushCSVar) [mkCoreTup [name, loc], rest]
-
- let mkPush name loc tm = do
- nameExpr <- mkStringExprFS name
- locExpr <- mkSrcLoc loc
- case tm of
- EvCallStack _ EvCsEmpty -> return (pushCS nameExpr locExpr emptyCS)
- _ -> do tmExpr <- dsEvTerm tm
- -- at this point tmExpr :: IP sym CallStack
- -- but we need the actual CallStack to pass to pushCS,
- -- so we use unwrapIP to strip the dictionary wrapper
- -- See Note [Overview of implicit CallStacks]
- let ip_co = unwrapIP (exprType tmExpr)
- return (pushCS nameExpr locExpr (mkCastDs tmExpr ip_co))
- cs_expr <- case cs of
- EvCsPushCall name loc tm -> mkPush (occNameFS $ getOccName name) loc tm
- EvCsEmpty -> return emptyCS
- return $ Cast cs_expr (wrapIP ty)
diff --git a/compiler/typecheck/TcCanonical.hs b/compiler/typecheck/TcCanonical.hs
index d795498e9f..e159c3a770 100644
--- a/compiler/typecheck/TcCanonical.hs
+++ b/compiler/typecheck/TcCanonical.hs
@@ -19,6 +19,7 @@ import Type
import TcFlatten
import TcSMonad
import TcEvidence
+import TcEvTerm
import Class
import TyCon
import TyCoRep -- cleverly decomposes types, good for completeness checking
@@ -152,7 +153,7 @@ canClassNC ev cls tys
-- Then we solve the wanted by pushing the call-site
-- onto the newly emitted CallStack
- ; let ev_cs = EvCsPushCall func (ctLocSpan loc) (EvExpr (ctEvTerm new_ev))
+ ; let ev_cs = EvCsPushCall func (ctLocSpan loc) (ctEvTerm new_ev)
; solveCallStack ev ev_cs
; canClass new_ev cls tys False }
@@ -171,7 +172,9 @@ solveCallStack ev ev_cs = do
-- We're given ev_cs :: CallStack, but the evidence term should be a
-- dictionary, so we have to coerce ev_cs to a dictionary for
-- `IP ip CallStack`. See Note [Overview of implicit CallStacks]
- setWantedEvBind (ctEvEvId ev) (EvCallStack (ctEvPred ev) ev_cs)
+ cs_tm <- evCallStack ev_cs
+ let ev_tm = mkEvCast cs_tm (wrapIP (ctEvPred ev))
+ setWantedEvBind (ctEvEvId ev) (EvExpr ev_tm)
canClass :: CtEvidence
-> Class -> [Type]
@@ -1588,7 +1591,7 @@ canEqReflexive :: CtEvidence -- ty ~ ty
-> TcType -- ty
-> TcS (StopOrContinue Ct) -- always Stop
canEqReflexive ev eq_rel ty
- = do { setEvBindIfWanted ev (EvExpr $ evCoercion $
+ = do { setEvBindIfWanted ev (evCoercion $
mkTcReflCo (eqRelRole eq_rel) ty)
; stopWith ev "Solved by reflexivity" }
@@ -1864,8 +1867,8 @@ rewriteEvidence ev@(CtWanted { ctev_dest = dest
= do { mb_new_ev <- newWanted loc new_pred
; MASSERT( tcCoercionRole co == ctEvRole ev )
; setWantedEvTerm dest
- (EvExpr (mkEvCast (getEvExpr mb_new_ev)
- (tcDowngradeRole Representational (ctEvRole ev) co)))
+ (EvExpr $ mkEvCast (getEvExpr mb_new_ev)
+ (tcDowngradeRole Representational (ctEvRole ev) co))
; case mb_new_ev of
Fresh new_ev -> continueWith new_ev
Cached _ -> stopWith ev "Cached wanted" }
diff --git a/compiler/typecheck/TcErrors.hs b/compiler/typecheck/TcErrors.hs
index 2f8f4cf379..d895921411 100644
--- a/compiler/typecheck/TcErrors.hs
+++ b/compiler/typecheck/TcErrors.hs
@@ -812,11 +812,11 @@ addDeferredBinding ctxt err ct
; case dest of
EvVarDest evar
- -> addTcEvBind ev_binds_var $ mkWantedEvBind evar err_tm
+ -> addTcEvBind ev_binds_var $ mkWantedEvBind evar (EvExpr err_tm)
HoleDest hole
-> do { -- See Note [Deferred errors for coercion holes]
let co_var = coHoleCoVar hole
- ; addTcEvBind ev_binds_var $ mkWantedEvBind co_var err_tm
+ ; addTcEvBind ev_binds_var $ mkWantedEvBind co_var (EvExpr err_tm)
; fillCoercionHole hole (mkTcCoVarCo co_var) }}
| otherwise -- Do not set any evidence for Given/Derived
diff --git a/compiler/typecheck/TcEvTerm.hs b/compiler/typecheck/TcEvTerm.hs
index dca3d48978..4c3961964c 100644
--- a/compiler/typecheck/TcEvTerm.hs
+++ b/compiler/typecheck/TcEvTerm.hs
@@ -1,7 +1,7 @@
-- (those who have too heavy dependencies for TcEvidence)
module TcEvTerm
- ( evDelayedError )
+ ( evDelayedError, evCallStack )
where
import GhcPrelude
@@ -23,9 +23,47 @@ import SrcLoc
-- Used with Opt_DeferTypeErrors
-- See Note [Deferring coercion errors to runtime]
-- in TcSimplify
-evDelayedError :: Type -> FastString -> EvTerm
+evDelayedError :: Type -> FastString -> EvExpr
evDelayedError ty msg
- = EvExpr $ Var errorId `mkTyApps` [getRuntimeRep ty, ty] `mkApps` [litMsg]
+ = Var errorId `mkTyApps` [getRuntimeRep ty, ty] `mkApps` [litMsg]
where
errorId = tYPE_ERROR_ID
litMsg = Lit (MachStr (fastStringToByteString msg))
+
+-- Dictionary for CallStack implicit parameters
+evCallStack :: (MonadThings m, HasModule m, HasDynFlags m) =>
+ EvCallStack -> m EvExpr
+-- See Note [Overview of implicit CallStacks] in TcEvidence.hs
+evCallStack cs = do
+ df <- getDynFlags
+ m <- getModule
+ srcLocDataCon <- lookupDataCon srcLocDataConName
+ let mkSrcLoc l = mkCoreConApps srcLocDataCon <$>
+ sequence [ mkStringExprFS (unitIdFS $ moduleUnitId m)
+ , mkStringExprFS (moduleNameFS $ moduleName m)
+ , mkStringExprFS (srcSpanFile l)
+ , return $ mkIntExprInt df (srcSpanStartLine l)
+ , return $ mkIntExprInt df (srcSpanStartCol l)
+ , return $ mkIntExprInt df (srcSpanEndLine l)
+ , return $ mkIntExprInt df (srcSpanEndCol l)
+ ]
+
+ emptyCS <- Var <$> lookupId emptyCallStackName
+
+ pushCSVar <- lookupId pushCallStackName
+ let pushCS name loc rest =
+ mkCoreApps (Var pushCSVar) [mkCoreTup [name, loc], rest]
+
+ let mkPush name loc tm = do
+ nameExpr <- mkStringExprFS name
+ locExpr <- mkSrcLoc loc
+ -- at this point tm :: IP sym CallStack
+ -- but we need the actual CallStack to pass to pushCS,
+ -- so we use unwrapIP to strip the dictionary wrapper
+ -- See Note [Overview of implicit CallStacks]
+ let ip_co = unwrapIP (exprType tm)
+ return (pushCS nameExpr locExpr (Cast tm ip_co))
+
+ case cs of
+ EvCsPushCall name loc tm -> mkPush (occNameFS $ getOccName name) loc tm
+ EvCsEmpty -> return emptyCS
diff --git a/compiler/typecheck/TcEvidence.hs b/compiler/typecheck/TcEvidence.hs
index 752b0efe8d..7bf01fdad4 100644
--- a/compiler/typecheck/TcEvidence.hs
+++ b/compiler/typecheck/TcEvidence.hs
@@ -475,9 +475,9 @@ evBindVar = eb_lhs
mkWantedEvBind :: EvVar -> EvTerm -> EvBind
mkWantedEvBind ev tm = EvBind { eb_is_given = False, eb_lhs = ev, eb_rhs = tm }
-
-mkGivenEvBind :: EvVar -> EvTerm -> EvBind
-mkGivenEvBind ev tm = EvBind { eb_is_given = True, eb_lhs = ev, eb_rhs = tm }
+-- EvTypeable are never given, so we can work with EvExpr here instead of EvTerm
+mkGivenEvBind :: EvVar -> EvExpr -> EvBind
+mkGivenEvBind ev tm = EvBind { eb_is_given = True, eb_lhs = ev, eb_rhs = EvExpr tm }
-- An EvTerm is, conceptually, a CoreExpr that implements the constraint.
@@ -486,9 +486,6 @@ mkGivenEvBind ev tm = EvBind { eb_is_given = True, eb_lhs = ev, eb_rhs = tm }
-- Because of staging problems issues around EvTypeable
data EvTerm
= EvExpr EvExpr
- | EvCallStack TcPredType EvCallStack
- -- Dictionary for CallStack implicit parameters, toether with the
- -- Predtype for coercion
| EvTypeable Type EvTypeable -- Dictionary for (Typeable ty)
deriving Data.Data
@@ -563,7 +560,7 @@ data EvTypeable
data EvCallStack
-- See Note [Overview of implicit CallStacks]
= EvCsEmpty
- | EvCsPushCall Name RealSrcSpan EvTerm
+ | EvCsPushCall Name RealSrcSpan EvExpr
-- ^ @EvCsPushCall name loc stk@ represents a call to @name@, occurring at
-- @loc@, in a calling context @stk@.
deriving Data.Data
@@ -778,17 +775,11 @@ evTermCoercion tm = pprPanic "evTermCoercion" (ppr tm)
evVarsOfTerm :: EvTerm -> VarSet
evVarsOfTerm (EvExpr e) = exprSomeFreeVars isEvVar e
-evVarsOfTerm (EvCallStack _ cs) = evVarsOfCallStack cs
evVarsOfTerm (EvTypeable _ ev) = evVarsOfTypeable ev
evVarsOfTerms :: [EvTerm] -> VarSet
evVarsOfTerms = mapUnionVarSet evVarsOfTerm
-evVarsOfCallStack :: EvCallStack -> VarSet
-evVarsOfCallStack cs = case cs of
- EvCsEmpty -> emptyVarSet
- EvCsPushCall _ _ tm -> evVarsOfTerm tm
-
evVarsOfTypeable :: EvTypeable -> VarSet
evVarsOfTypeable ev =
case ev of
@@ -877,7 +868,6 @@ instance Outputable EvBind where
instance Outputable EvTerm where
ppr (EvExpr e) = ppr e
- ppr (EvCallStack _ cs) = ppr cs
ppr (EvTypeable ty ev) = ppr ev <+> dcolon <+> text "Typeable" <+> ppr ty
instance Outputable EvCallStack where
diff --git a/compiler/typecheck/TcFlatten.hs b/compiler/typecheck/TcFlatten.hs
index 5152841db5..ec0c2de504 100644
--- a/compiler/typecheck/TcFlatten.hs
+++ b/compiler/typecheck/TcFlatten.hs
@@ -1644,7 +1644,7 @@ tryFill ev tv rhs
setReflEvidence :: CtEvidence -> EqRel -> TcType -> TcS ()
setReflEvidence ev eq_rel rhs
- = setEvBindIfWanted ev (EvExpr (evCoercion refl_co))
+ = setEvBindIfWanted ev (evCoercion refl_co)
where
refl_co = mkTcReflCo (eqRelRole eq_rel) rhs
diff --git a/compiler/typecheck/TcHsSyn.hs b/compiler/typecheck/TcHsSyn.hs
index fc448ffb91..43ff2217ee 100644
--- a/compiler/typecheck/TcHsSyn.hs
+++ b/compiler/typecheck/TcHsSyn.hs
@@ -1425,13 +1425,6 @@ zonkEvTerm env (EvExpr e) =
EvExpr <$> zonkCoreExpr env e
zonkEvTerm env (EvTypeable ty ev) =
EvTypeable <$> zonkTcTypeToType env ty <*> zonkEvTypeable env ev
-zonkEvTerm env (EvCallStack ty cs)
- = do ty' <- zonkTcTypeToType env ty
- case cs of
- EvCsEmpty -> return (EvCallStack ty' cs)
- EvCsPushCall n l tm -> do { tm' <- zonkEvTerm env tm
- ; return (EvCallStack ty' (EvCsPushCall n l tm')) }
-
zonkCoreExpr :: ZonkEnv -> CoreExpr -> TcM CoreExpr
zonkCoreExpr env (Var v)
diff --git a/compiler/typecheck/TcInteract.hs b/compiler/typecheck/TcInteract.hs
index 7ff8a62ef0..11d9252bcd 100644
--- a/compiler/typecheck/TcInteract.hs
+++ b/compiler/typecheck/TcInteract.hs
@@ -681,9 +681,9 @@ interactIrred inerts workItem@(CIrredCan { cc_ev = ev_w, cc_insol = insoluble })
do { what_next <- solveOneFromTheOther ev_i ev_w
; traceTcS "iteractIrred" (ppr workItem $$ ppr what_next $$ ppr ct_i)
; case what_next of
- KeepInert -> do { setEvBindIfWanted ev_w (EvExpr (swap_me swap ev_i))
+ KeepInert -> do { setEvBindIfWanted ev_w (swap_me swap ev_i)
; return (Stop ev_w (text "Irred equal" <+> parens (ppr what_next))) }
- KeepWork -> do { setEvBindIfWanted ev_i (EvExpr (swap_me swap ev_w))
+ KeepWork -> do { setEvBindIfWanted ev_i (swap_me swap ev_w)
; updInertIrreds (\_ -> others)
; continueWith workItem } }
@@ -1001,9 +1001,9 @@ interactDict inerts workItem@(CDictCan { cc_ev = ev_w, cc_class = cls, cc_tyargs
{ what_next <- solveOneFromTheOther ev_i ev_w
; traceTcS "lookupInertDict" (ppr what_next)
; case what_next of
- KeepInert -> do { setEvBindIfWanted ev_w (EvExpr $ ctEvTerm ev_i)
+ KeepInert -> do { setEvBindIfWanted ev_w (ctEvTerm ev_i)
; return $ Stop ev_w (text "Dict equal" <+> parens (ppr what_next)) }
- KeepWork -> do { setEvBindIfWanted ev_i (EvExpr $ ctEvTerm ev_w)
+ KeepWork -> do { setEvBindIfWanted ev_i (ctEvTerm ev_w)
; updInertDicts $ \ ds -> delDict ds cls tys
; continueWith workItem } } }
@@ -1550,7 +1550,7 @@ interactTyVarEq inerts workItem@(CTyEqCan { cc_tyvar = tv
| Just (ev_i, swapped, keep_deriv)
<- inertsCanDischarge inerts tv rhs (ctEvFlavour ev, eq_rel)
= do { setEvBindIfWanted ev $
- EvExpr $ evCoercion (maybeSym swapped $
+ evCoercion (maybeSym swapped $
tcDowngradeRole (eqRelRole eq_rel)
(ctEvRole ev_i)
(ctEvCoercion ev_i))
@@ -1616,7 +1616,7 @@ solveByUnification wd tv xi
text "Right Kind is:" <+> ppr (typeKind xi) ]
; unifyTyVar tv xi
- ; setEvBindIfWanted wd (EvExpr (evCoercion (mkTcNomReflCo xi))) }
+ ; setEvBindIfWanted wd (evCoercion (mkTcNomReflCo xi)) }
ppr_kicked :: Int -> SDoc
ppr_kicked 0 = empty
@@ -2202,7 +2202,7 @@ doTopReactDict inerts work_item@(CDictCan { cc_ev = fl, cc_class = cls
; continueWith work_item }
| Just ev <- lookupSolvedDict inerts dict_loc cls xis -- Cached
- = do { setEvBindIfWanted fl (EvExpr (ctEvTerm ev))
+ = do { setEvBindIfWanted fl (ctEvTerm ev)
; stopWith fl "Dict/Top (cached)" }
| otherwise -- Wanted or Derived, but not cached
diff --git a/compiler/typecheck/TcSMonad.hs b/compiler/typecheck/TcSMonad.hs
index 3142567ddb..cd8eea1900 100644
--- a/compiler/typecheck/TcSMonad.hs
+++ b/compiler/typecheck/TcSMonad.hs
@@ -3038,11 +3038,11 @@ setWantedEvTerm (EvVarDest ev) tm = setWantedEvBind ev tm
setWantedEvBind :: EvVar -> EvTerm -> TcS ()
setWantedEvBind ev_id tm = setEvBind (mkWantedEvBind ev_id tm)
-setEvBindIfWanted :: CtEvidence -> EvTerm -> TcS ()
+setEvBindIfWanted :: CtEvidence -> EvExpr -> TcS ()
setEvBindIfWanted ev tm
= case ev of
CtWanted { ctev_dest = dest }
- -> setWantedEvTerm dest tm
+ -> setWantedEvTerm dest (EvExpr tm)
_ -> return ()
newTcEvBinds :: TcS EvBindsVar
@@ -3065,7 +3065,7 @@ newGivenEvVar loc (pred, rhs)
newBoundEvVarId :: TcPredType -> EvExpr -> TcS EvVar
newBoundEvVarId pred rhs
= do { new_ev <- newEvVar pred
- ; setEvBind (mkGivenEvBind new_ev (EvExpr rhs))
+ ; setEvBind (mkGivenEvBind new_ev rhs)
; return new_ev }
newGivenEvVars :: CtLoc -> [(TcPredType, EvExpr)] -> TcS [CtEvidence]