[commit: ghc] master: Make the desugarer a tiny bit cleverer on coercions (fixes Trac #7837) (29cc690)

Simon Peyton Jones simonpj at microsoft.com
Tue Apr 16 17:41:24 CEST 2013


Repository : http://darcs.haskell.org/ghc.git/

On branch  : master

https://github.com/ghc/ghc/commit/29cc690e8a6c154973de27d7bb49aa2a47b51dc7

>---------------------------------------------------------------

commit 29cc690e8a6c154973de27d7bb49aa2a47b51dc7
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Tue Apr 16 10:33:13 2013 +0100

    Make the desugarer a tiny bit cleverer on coercions (fixes Trac #7837)
    
    The desugarer was generating a redundant box/unbox pair on the
    LHS of a RULE, which in turn made matching fail.
    
    See Note [Simple coercions] in DsBinds.

>---------------------------------------------------------------

 compiler/deSugar/DsBinds.lhs | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/compiler/deSugar/DsBinds.lhs b/compiler/deSugar/DsBinds.lhs
index 41172e1..62793ac 100644
--- a/compiler/deSugar/DsBinds.lhs
+++ b/compiler/deSugar/DsBinds.lhs
@@ -748,7 +748,10 @@ dsEvTerm (EvCast tm co)
 
 dsEvTerm (EvDFunApp df tys tms) = do { tms' <- mapM dsEvTerm tms
                                      ; return (Var df `mkTyApps` tys `mkApps` tms') }
-dsEvTerm (EvCoercion co)         = dsTcCoercion co mkEqBox
+
+dsEvTerm (EvCoercion (TcCoVarCo v)) = return (Var v)  -- See Note [Simple coercions]
+dsEvTerm (EvCoercion co)            = dsTcCoercion co mkEqBox
+
 dsEvTerm (EvTupleSel v n)
    = do { tm' <- dsEvTerm v
         ; let scrut_ty = exprType tm'
@@ -802,7 +805,6 @@ dsTcCoercion co thing_inside
              result_expr = thing_inside (ds_tc_coercion subst co)
              result_ty   = exprType result_expr
 
-
        ; return (foldr (wrap_in_case result_ty) result_expr eqvs_covs) }
   where
     mk_co_var :: Id -> Unique -> (Id, Id)
@@ -862,3 +864,30 @@ ds_tc_coercion subst tc_co
      | Just co <- Coercion.lookupCoVar subst v = co
      | otherwise  = pprPanic "ds_tc_coercion" (ppr v $$ ppr tc_co)
 \end{code}
+
+Note [Simple coercions]
+~~~~~~~~~~~~~~~~~~~~~~~
+We have a special case for coercions that are simple variables.
+Suppose   cv :: a ~ b   is in scope
+Lacking the special case, if we see
+	f a b cv
+we'd desguar to
+        f a b (case cv of EqBox (cv# :: a ~# b) -> EqBox cv#)
+which is a bit stupid.  The special case does the obvious thing.
+
+This turns out to be important when desugaring the LHS of a RULE
+(see Trac #7837).  Suppose we have
+    normalise        :: (a ~ Scalar a) => a -> a
+    normalise_Double :: Double -> Double
+    {-# RULES "normalise" normalise = normalise_Double #-}
+
+Then the RULE we want looks like
+     forall a, (cv:a~Scalar a). 
+       normalise a cv = normalise_Double
+But without the special case we generate the redundant box/unbox,
+which simpleOpt (currently) doesn't remove. So the rule never matches.
+
+Maybe simpleOpt should be smarter.  But it seems like a good plan
+to simply never generate the redundant box/unbox in the first place.
+
+





More information about the ghc-commits mailing list