diff options
author | Joachim Breitner <mail@joachim-breitner.de> | 2014-01-24 13:33:37 +0000 |
---|---|---|
committer | Joachim Breitner <mail@joachim-breitner.de> | 2014-02-11 15:35:52 +0000 |
commit | b4715d67ae90f4cc847daa94f0fc056a40057d65 (patch) | |
tree | 66204fcaaec789904cae55da5a5737e61a90b333 /compiler/deSugar | |
parent | a4450ece29ee42f6d04cdd6baf4c48ff596b687d (diff) | |
download | haskell-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.lhs | 46 |
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 |