summaryrefslogtreecommitdiff
path: root/compiler/deSugar
diff options
context:
space:
mode:
authorJoachim Breitner <mail@joachim-breitner.de>2014-01-24 13:33:37 +0000
committerJoachim Breitner <mail@joachim-breitner.de>2014-02-11 15:35:52 +0000
commitb4715d67ae90f4cc847daa94f0fc056a40057d65 (patch)
tree66204fcaaec789904cae55da5a5737e61a90b333 /compiler/deSugar
parenta4450ece29ee42f6d04cdd6baf4c48ff596b687d (diff)
downloadhaskell-b4715d67ae90f4cc847daa94f0fc056a40057d65.tar.gz
Replace forall'ed Coercible by ~R# in RULES
we want a rule "map coerce = coerce" to match the core generated for "map Age" (this is #2110).
Diffstat (limited to 'compiler/deSugar')
-rw-r--r--compiler/deSugar/Desugar.lhs46
1 files changed, 44 insertions, 2 deletions
diff --git a/compiler/deSugar/Desugar.lhs b/compiler/deSugar/Desugar.lhs
index e13767ff59..cd75de9a3a 100644
--- a/compiler/deSugar/Desugar.lhs
+++ b/compiler/deSugar/Desugar.lhs
@@ -18,6 +18,7 @@ import Id
import Name
import Type
import FamInstEnv
+import Coercion
import InstEnv
import Class
import Avail
@@ -33,8 +34,11 @@ import Module
import NameSet
import NameEnv
import Rules
+import TysPrim (eqReprPrimTyCon)
+import TysWiredIn (coercibleTyCon )
import BasicTypes ( Activation(.. ) )
import CoreMonad ( endPass, CoreToDo(..) )
+import MkCore
import FastString
import ErrUtils
import Outputable
@@ -347,6 +351,7 @@ Reason
%************************************************************************
\begin{code}
+
dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
= putSrcSpanDs loc $
@@ -359,9 +364,11 @@ dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
; rhs' <- dsLExpr rhs
; dflags <- getDynFlags
+ ; (bndrs'', lhs'', rhs'') <- unfold_coerce bndrs' lhs' rhs'
+
-- Substitute the dict bindings eagerly,
-- and take the body apart into a (f args) form
- ; case decomposeRuleLhs bndrs' lhs' of {
+ ; case decomposeRuleLhs bndrs'' lhs'' of {
Left msg -> do { warnDs msg; return Nothing } ;
Right (final_bndrs, fn_id, args) -> do
@@ -370,7 +377,7 @@ dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
-- we don't want to attach rules to the bindings of implicit Ids,
-- because they don't show up in the bindings until just before code gen
fn_name = idName fn_id
- final_rhs = simpleOptExpr rhs' -- De-crap it
+ final_rhs = simpleOptExpr rhs'' -- De-crap it
rule = mkRule False {- Not auto -} is_local
name act fn_name final_bndrs args final_rhs
@@ -398,6 +405,27 @@ dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
; return (Just rule)
} } }
+
+-- See Note [Desugaring coerce as cast]
+unfold_coerce :: [Id] -> CoreExpr -> CoreExpr -> DsM ([Var], CoreExpr, CoreExpr)
+unfold_coerce bndrs lhs rhs = do
+ (bndrs', wrap) <- go bndrs
+ return (bndrs', wrap lhs, wrap rhs)
+ where
+ go :: [Id] -> DsM ([Id], CoreExpr -> CoreExpr)
+ go [] = return ([], id)
+ go (v:vs)
+ | Just (tc, args) <- splitTyConApp_maybe (idType v)
+ , tc == coercibleTyCon = do
+ let ty' = mkTyConApp eqReprPrimTyCon args
+ v' <- mkDerivedLocalM mkRepEqOcc v ty'
+
+ (bndrs, wrap) <- go vs
+ return (v':bndrs, mkCoreLet (NonRec v (mkEqBox (mkCoVarCo v'))) . wrap)
+ | otherwise = do
+ (bndrs,wrap) <- go vs
+ return (v:bndrs, wrap)
+
\end{code}
Note [Desugaring RULE left hand sides]
@@ -417,6 +445,20 @@ the rule is precisly to optimise them:
{-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}
+Note [Desugaring coerce as cast]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We want the user to express a rule saying roughly “mapping a coercion over a
+list can be replaced by a coercion”. But the cast operator of Core (▷) cannot
+be written in Haskell. So we use `coerce` for that (#2110). The user writes
+ map coerce = coerce
+as a RULE, and this optimizes any kind of mapped' casts aways, including `map
+MkNewtype`.
+
+For that we replace any forall'ed `c :: Coercible a b` value in a RULE by
+corresponding `co :: a ~#R b` and wrap the LHS and the RHS in
+`let c = MkCoercible co in ...`. This is later simplified to the desired form
+by simpleOptExpr (for the LHS) resp. the simplifiers (for the RHS).
+
%************************************************************************
%* *
%* Desugaring vectorisation declarations