diff options
author | Joachim Breitner <mail@joachim-breitner.de> | 2018-01-21 09:03:00 -0500 |
---|---|---|
committer | Joachim Breitner <mail@joachim-breitner.de> | 2018-01-22 19:37:17 -0500 |
commit | 51d5533979e7a189c21da544996c207a31da047e (patch) | |
tree | 1b78da116a2313d586ca5e3d06cbedf2aee7e795 | |
parent | 071962d30c9ac5d9ee0dedc5df0d6ce3d2e1bc0a (diff) | |
download | haskell-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.hs | 47 | ||||
-rw-r--r-- | compiler/typecheck/TcCanonical.hs | 13 | ||||
-rw-r--r-- | compiler/typecheck/TcErrors.hs | 4 | ||||
-rw-r--r-- | compiler/typecheck/TcEvTerm.hs | 44 | ||||
-rw-r--r-- | compiler/typecheck/TcEvidence.hs | 18 | ||||
-rw-r--r-- | compiler/typecheck/TcFlatten.hs | 2 | ||||
-rw-r--r-- | compiler/typecheck/TcHsSyn.hs | 7 | ||||
-rw-r--r-- | compiler/typecheck/TcInteract.hs | 14 | ||||
-rw-r--r-- | compiler/typecheck/TcSMonad.hs | 6 |
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] |