summaryrefslogtreecommitdiff
path: root/compiler/specialise/Rules.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/specialise/Rules.hs')
-rw-r--r--compiler/specialise/Rules.hs54
1 files changed, 32 insertions, 22 deletions
diff --git a/compiler/specialise/Rules.hs b/compiler/specialise/Rules.hs
index f7a67ea8bd..531b13166c 100644
--- a/compiler/specialise/Rules.hs
+++ b/compiler/specialise/Rules.hs
@@ -37,7 +37,7 @@ import CoreFVs ( exprFreeVars, exprsFreeVars, bindFreeVars
import CoreUtils ( exprType, eqExpr, mkTick, mkTicks,
stripTicksTopT, stripTicksTopE )
import PprCore ( pprRules )
-import Type ( Type, substTy, mkTvSubst )
+import Type ( Type, substTy, mkTCvSubst )
import TcType ( tcSplitTyConApp_maybe )
import TysPrim ( anyTypeOfKind )
import Coercion
@@ -50,7 +50,7 @@ import VarSet
import Name ( Name, NamedThing(..), nameIsLocalOrFrom )
import NameSet
import NameEnv
-import Unify ( ruleMatchTyX, MatchEnv(..) )
+import Unify ( ruleMatchTyX )
import BasicTypes ( Activation, CompilerPhase, isActive, pprRuleName )
import StaticFlags ( opt_PprStyle_Debug )
import DynFlags ( DynFlags )
@@ -61,6 +61,7 @@ import Bag
import Util
import Data.List
import Data.Ord
+import Control.Monad ( guard )
{-
Note [Overall plumbing for rules]
@@ -561,7 +562,17 @@ matchN (in_scope, id_unf) rule_name tmpl_vars tmpl_es target_es
-- See Note [Unbound template type variables]
where
fake_ty = anyTypeOfKind kind
- kind = Type.substTy (mkTvSubst in_scope tv_subst) (tyVarKind tmpl_var)
+ cv_subst = to_co_env id_subst
+ kind = Type.substTy (mkTCvSubst in_scope (tv_subst, cv_subst))
+ (tyVarKind tmpl_var)
+
+ to_co_env env = foldVarEnv_Directly to_co emptyVarEnv env
+ to_co uniq expr env
+ | Just co <- exprToCoercion_maybe expr
+ = extendVarEnv_Directly env uniq co
+
+ | otherwise
+ = env
unbound var = pprPanic "Template variable unbound in rewrite rule" $
vcat [ ptext (sLit "Variable:") <+> ppr var
@@ -779,19 +790,20 @@ match_co :: RuleMatchEnv
-> Coercion
-> Coercion
-> Maybe RuleSubst
-match_co renv subst (CoVarCo cv) co
- = match_var renv subst cv (Coercion co)
-match_co renv subst (Refl r1 ty1) co
- = case co of
- Refl r2 ty2
- | r1 == r2 -> match_ty renv subst ty1 ty2
- _ -> Nothing
-match_co renv subst (TyConAppCo r1 tc1 cos1) co2
- = case co2 of
- TyConAppCo r2 tc2 cos2
- | r1 == r2 && tc1 == tc2
- -> match_cos renv subst cos1 cos2
- _ -> Nothing
+match_co renv subst co1 co2
+ | Just cv <- getCoVar_maybe co1
+ = match_var renv subst cv (Coercion co2)
+ | Just (ty1, r1) <- isReflCo_maybe co1
+ = do { (ty2, r2) <- isReflCo_maybe co2
+ ; guard (r1 == r2)
+ ; match_ty renv subst ty1 ty2 }
+match_co renv subst co1 co2
+ | Just (tc1, cos1) <- splitTyConAppCo_maybe co1
+ = case splitTyConAppCo_maybe co2 of
+ Just (tc2, cos2)
+ | tc1 == tc2
+ -> match_cos renv subst cos1 cos2
+ _ -> Nothing
match_co _ _ _co1 _co2
-- Currently just deals with CoVarCo, TyConAppCo and Refl
#ifdef DEBUG
@@ -806,13 +818,11 @@ match_cos :: RuleMatchEnv
-> [Coercion]
-> Maybe RuleSubst
match_cos renv subst (co1:cos1) (co2:cos2) =
- case match_co renv subst co1 co2 of
- Just subst' -> match_cos renv subst' cos1 cos2
- Nothing -> Nothing
+ do { subst' <- match_co renv subst co1 co2
+ ; match_cos renv subst' cos1 cos2 }
match_cos _ subst [] [] = Just subst
match_cos _ _ cos1 cos2 = pprTrace "match_cos: not same length" (ppr cos1 $$ ppr cos2) Nothing
-
-------------
rnMatchBndr2 :: RuleMatchEnv -> RuleSubst -> Var -> Var -> RuleMatchEnv
rnMatchBndr2 renv subst x1 x2
@@ -932,11 +942,11 @@ match_ty :: RuleMatchEnv
-- We only want to replace (f T) with f', not (f Int).
match_ty renv subst ty1 ty2
- = do { tv_subst' <- Unify.ruleMatchTyX menv tv_subst ty1 ty2
+ = do { tv_subst'
+ <- Unify.ruleMatchTyX (rv_tmpls renv) (rv_lcl renv) tv_subst ty1 ty2
; return (subst { rs_tv_subst = tv_subst' }) }
where
tv_subst = rs_tv_subst subst
- menv = ME { me_tmpls = rv_tmpls renv, me_env = rv_lcl renv }
{-
Note [Expanding variables]