Reorganisation of the source tree
[ghc-hetmet.git] / ghc / compiler / specialise / Rules.lhs
diff --git a/ghc/compiler/specialise/Rules.lhs b/ghc/compiler/specialise/Rules.lhs
deleted file mode 100644 (file)
index 4d74314..0000000
+++ /dev/null
@@ -1,633 +0,0 @@
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-%
-\section[CoreRules]{Transformation rules}
-
-\begin{code}
-module Rules (
-       RuleBase, emptyRuleBase, mkRuleBase, extendRuleBaseList, 
-       unionRuleBase, pprRuleBase, ruleCheckProgram,
-
-       mkSpecInfo, extendSpecInfo, addSpecInfo,
-       rulesOfBinds, addIdSpecialisations, 
-
-        lookupRule, mkLocalRule, roughTopNames
-    ) where
-
-#include "HsVersions.h"
-
-import CoreSyn         -- All of it
-import OccurAnal       ( occurAnalyseExpr )
-import CoreFVs         ( exprFreeVars, exprsFreeVars, rulesRhsFreeVars )
-import CoreUnfold      ( isCheapUnfolding, unfoldingTemplate )
-import CoreUtils       ( tcEqExprX )
-import PprCore         ( pprRules )
-import Type            ( TvSubstEnv )
-import TcType          ( tcSplitTyConApp_maybe )
-import CoreTidy                ( tidyRules )
-import Id              ( Id, idUnfolding, isLocalId, isGlobalId, idName,
-                         idSpecialisation, idCoreRules, setIdSpecialisation ) 
-import IdInfo          ( SpecInfo( SpecInfo ) )
-import Var             ( Var )
-import VarEnv          ( IdEnv, InScopeSet, emptyTidyEnv,
-                         emptyInScopeSet, mkInScopeSet, extendInScopeSetList, 
-                         emptyVarEnv, lookupVarEnv, extendVarEnv, 
-                         nukeRnEnvL, mkRnEnv2, rnOccR, rnOccL, inRnEnvR,
-                         rnBndrR, rnBndr2, rnBndrL, rnBndrs2 )
-import VarSet
-import Name            ( Name, NamedThing(..), nameOccName )
-import NameEnv
-import Unify           ( ruleMatchTyX, MatchEnv(..) )
-import BasicTypes      ( Activation, CompilerPhase, isActive )
-import Outputable
-import FastString
-import Maybes          ( isJust, orElse )
-import Bag
-import Util            ( singleton )
-import List            ( isPrefixOf )
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
-%*                                                                     *
-%************************************************************************
-
-A @CoreRule@ holds details of one rule for an @Id@, which
-includes its specialisations.
-
-For example, if a rule for @f@ contains the mapping:
-\begin{verbatim}
-       forall a b d. [Type (List a), Type b, Var d]  ===>  f' a b
-\end{verbatim}
-then when we find an application of f to matching types, we simply replace
-it by the matching RHS:
-\begin{verbatim}
-       f (List Int) Bool dict ===>  f' Int Bool
-\end{verbatim}
-All the stuff about how many dictionaries to discard, and what types
-to apply the specialised function to, are handled by the fact that the
-Rule contains a template for the result of the specialisation.
-
-There is one more exciting case, which is dealt with in exactly the same
-way.  If the specialised value is unboxed then it is lifted at its
-definition site and unlifted at its uses.  For example:
-
-       pi :: forall a. Num a => a
-
-might have a specialisation
-
-       [Int#] ===>  (case pi' of Lift pi# -> pi#)
-
-where pi' :: Lift Int# is the specialised version of pi.
-
-\begin{code}
-mkLocalRule :: RuleName -> Activation 
-           -> Name -> [CoreBndr] -> [CoreExpr] -> CoreExpr -> CoreRule
--- Used to make CoreRule for an Id defined in this module
-mkLocalRule name act fn bndrs args rhs
-  = Rule { ru_name = name, ru_fn = fn, ru_act = act,
-          ru_bndrs = bndrs, ru_args = args,
-          ru_rhs = rhs, ru_rough = roughTopNames args,
-          ru_orph = Just (nameOccName fn), ru_local = True }
-
---------------
-roughTopNames :: [CoreExpr] -> [Maybe Name]
-roughTopNames args = map roughTopName args
-
-roughTopName :: CoreExpr -> Maybe Name
--- Find the "top" free name of an expression
--- a) the function in an App chain (if a GlobalId)
--- b) the TyCon in a type
--- This is used for the fast-match-check for rules; 
---     if the top names don't match, the rest can't
-roughTopName (Type ty) = case tcSplitTyConApp_maybe ty of
-                         Just (tc,_) -> Just (getName tc)
-                         Nothing     -> Nothing
-roughTopName (App f a) = roughTopName f
-roughTopName (Var f) | isGlobalId f = Just (idName f)
-                    | otherwise    = Nothing
-roughTopName other = Nothing
-
-ruleCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool
--- (ruleCantMatch tpl actual) returns True only if 'actual'
--- definitely can't match 'tpl' by instantiating 'tpl'.  
--- It's only a one-way match; unlike instance matching we 
--- don't consider unification
-ruleCantMatch (Just n1 : ts) (Just n2 : as) = n1 /= n2 || ruleCantMatch ts as
-ruleCantMatch (Just n1 : ts) (Nothing : as) = True
-ruleCantMatch (t       : ts) (a       : as) = ruleCantMatch ts as
-ruleCantMatch ts            as             = False
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-               SpecInfo: the rules in an IdInfo
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-mkSpecInfo :: [CoreRule] -> SpecInfo
-mkSpecInfo rules = SpecInfo rules (rulesRhsFreeVars rules)
-
-extendSpecInfo :: SpecInfo -> [CoreRule] -> SpecInfo
-extendSpecInfo (SpecInfo rs1 fvs1) rs2
-  = SpecInfo (rs2 ++ rs1) (rulesRhsFreeVars rs2 `unionVarSet` fvs1)
-
-addSpecInfo :: SpecInfo -> SpecInfo -> SpecInfo
-addSpecInfo (SpecInfo rs1 fvs1) (SpecInfo rs2 fvs2) 
-  = SpecInfo (rs1 ++ rs2) (fvs1 `unionVarSet` fvs2)
-
-addIdSpecialisations :: Id -> [CoreRule] -> Id
-addIdSpecialisations id rules
-  = setIdSpecialisation id $
-    extendSpecInfo (idSpecialisation id) rules
-
-rulesOfBinds :: [CoreBind] -> [CoreRule]
-rulesOfBinds binds = concatMap (concatMap idCoreRules . bindersOf) binds
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-               RuleBase
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-type RuleBase = NameEnv [CoreRule]
-       -- Maps (the name of) an Id to its rules
-       -- The rules are are unordered; 
-       -- we sort out any overlaps on lookup
-
-emptyRuleBase = emptyNameEnv
-
-mkRuleBase :: [CoreRule] -> RuleBase
-mkRuleBase rules = extendRuleBaseList emptyRuleBase rules
-
-extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase
-extendRuleBaseList rule_base new_guys
-  = foldl extendRuleBase rule_base new_guys
-
-unionRuleBase :: RuleBase -> RuleBase -> RuleBase
-unionRuleBase rb1 rb2 = plusNameEnv_C (++) rb1 rb2
-
-extendRuleBase :: RuleBase -> CoreRule -> RuleBase
-extendRuleBase rule_base rule
-  = extendNameEnv_Acc (:) singleton rule_base (ruleIdName rule) rule
-
-pprRuleBase :: RuleBase -> SDoc
-pprRuleBase rules = vcat [ pprRules (tidyRules emptyTidyEnv rs) 
-                        | rs <- nameEnvElts rules ]
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection{Matching}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-lookupRule :: (Activation -> Bool) -> InScopeSet
-          -> RuleBase  -- Imported rules
-          -> Id -> [CoreExpr] -> Maybe (RuleName, CoreExpr)
-lookupRule is_active in_scope rule_base fn args
-  = matchRules is_active in_scope fn args rules
-  where
-       -- The rules for an Id come from two places:
-       --      (a) the ones it is born with (idCoreRules fn)
-       --      (b) rules added in subsequent modules (extra_rules)
-       -- PrimOps, for example, are born with a bunch of rules under (a)
-    rules = extra_rules ++ idCoreRules fn
-    extra_rules | isLocalId fn = []
-               | otherwise    = lookupNameEnv rule_base (idName fn) `orElse` []
-
-matchRules :: (Activation -> Bool) -> InScopeSet
-          -> Id -> [CoreExpr]
-          -> [CoreRule] -> Maybe (RuleName, CoreExpr)
--- See comments on matchRule
-matchRules is_active in_scope fn args rules
-  = case go [] rules of
-       []     -> Nothing
-       (m:ms) -> Just (case findBest (fn,args) m ms of
-                         (rule, ans) -> (ru_name rule, ans))
-  where
-    rough_args = map roughTopName args
-
-    go :: [(CoreRule,CoreExpr)] -> [CoreRule] -> [(CoreRule,CoreExpr)]
-    go ms []          = ms
-    go ms (r:rs) = case (matchRule is_active in_scope args rough_args r) of
-                       Just e  -> go ((r,e):ms) rs
-                       Nothing -> go ms         rs
-
-findBest :: (Id, [CoreExpr])
-        -> (CoreRule,CoreExpr) -> [(CoreRule,CoreExpr)] -> (CoreRule,CoreExpr)
--- All these pairs matched the expression
--- Return the pair the the most specific rule
--- The (fn,args) is just for overlap reporting
-
-findBest target (rule,ans)   [] = (rule,ans)
-findBest target (rule1,ans1) ((rule2,ans2):prs)
-  | rule1 `isMoreSpecific` rule2 = findBest target (rule1,ans1) prs
-  | rule2 `isMoreSpecific` rule1 = findBest target (rule1,ans1) prs
-#ifdef DEBUG
-  | otherwise = pprTrace "Rules.findBest: rule overlap (Rule 1 wins)"
-                        (vcat [ptext SLIT("Expression to match:") <+> ppr fn <+> sep (map ppr args),
-                               ptext SLIT("Rule 1:") <+> ppr rule1, 
-                               ptext SLIT("Rule 2:") <+> ppr rule2]) $
-               findBest target (rule1,ans1) prs
-#else
-  | otherwise = findBest target (rule1,ans1) prs
-#endif
-  where
-    (fn,args) = target
-
-isMoreSpecific :: CoreRule -> CoreRule -> Bool
-isMoreSpecific (BuiltinRule {}) r2 = True
-isMoreSpecific r1 (BuiltinRule {}) = False
-isMoreSpecific (Rule { ru_bndrs = bndrs1, ru_args = args1 })
-              (Rule { ru_bndrs = bndrs2, ru_args = args2 })
-  = isJust (matchN in_scope bndrs2 args2 args1)
-  where
-   in_scope = mkInScopeSet (mkVarSet bndrs1)
-       -- Actually we should probably include the free vars 
-       -- of rule1's args, but I can't be bothered
-
-noBlackList :: Activation -> Bool
-noBlackList act = False                -- Nothing is black listed
-
-matchRule :: (Activation -> Bool) -> InScopeSet
-         -> [CoreExpr] -> [Maybe Name]
-         -> CoreRule -> Maybe CoreExpr
-
--- If (matchRule rule args) returns Just (name,rhs)
--- then (f args) matches the rule, and the corresponding
--- rewritten RHS is rhs
---
--- The bndrs and rhs is occurrence-analysed
---
---     Example
---
--- The rule
---     forall f g x. map f (map g x) ==> map (f . g) x
--- is stored
---     CoreRule "map/map" 
---              [f,g,x]                -- tpl_vars
---              [f,map g x]            -- tpl_args
---              map (f.g) x)           -- rhs
---       
--- Then the call: matchRule the_rule [e1,map e2 e3]
---       = Just ("map/map", (\f,g,x -> rhs) e1 e2 e3)
---
--- Any 'surplus' arguments in the input are simply put on the end
--- of the output.
-
-matchRule is_active in_scope args rough_args
-         (BuiltinRule { ru_name = name, ru_try = match_fn })
-  = case match_fn args of
-       Just expr -> Just expr
-       Nothing   -> Nothing
-
-matchRule is_active in_scope args rough_args
-          (Rule { ru_name = rn, ru_act = act, ru_rough = tpl_tops,
-                 ru_bndrs = tpl_vars, ru_args = tpl_args,
-                 ru_rhs = rhs })
-  | not (is_active act)                      = Nothing
-  | ruleCantMatch tpl_tops rough_args = Nothing
-  | otherwise
-  = case matchN in_scope tpl_vars tpl_args args of
-       Nothing                    -> Nothing
-       Just (tpl_vals, leftovers) -> Just (rule_fn
-                                           `mkApps` tpl_vals
-                                           `mkApps` leftovers)
-  where
-    rule_fn = occurAnalyseExpr (mkLams tpl_vars rhs)
-       -- We could do this when putting things into the rulebase, I guess
-\end{code}
-
-\begin{code}
-matchN :: InScopeSet
-       -> [Var]                -- Template tyvars
-       -> [CoreExpr]           -- Template
-       -> [CoreExpr]           -- Target; can have more elts than template
-       -> Maybe ([CoreExpr],   -- What is substituted for each template var
-                 [CoreExpr])   -- Leftover target exprs
-
-matchN in_scope tmpl_vars tmpl_es target_es
-  = do { (subst, leftover_es) <- go init_menv emptySubstEnv tmpl_es target_es
-       ; return (map (lookup_tmpl subst) tmpl_vars, leftover_es) }
-  where
-    init_menv = ME { me_tmpls = mkVarSet tmpl_vars, me_env = init_rn_env }
-    init_rn_env = mkRnEnv2 (extendInScopeSetList in_scope tmpl_vars)
-               
-    go menv subst []     es    = Just (subst, es)
-    go menv subst ts     []    = Nothing       -- Fail if too few actual args
-    go menv subst (t:ts) (e:es) = do { subst1 <- match menv subst t e 
-                                    ; go menv subst1 ts es }
-
-    lookup_tmpl :: (TvSubstEnv, IdSubstEnv) -> Var -> CoreExpr
-    lookup_tmpl (tv_subst, id_subst) tmpl_var
-       | isTyVar tmpl_var = case lookupVarEnv tv_subst tmpl_var of
-                               Just ty         -> Type ty
-                               Nothing         -> unbound tmpl_var
-       | otherwise        = case lookupVarEnv id_subst tmpl_var of
-                               Just e -> e
-                               other  -> unbound tmpl_var
-    unbound var = pprPanic "Template variable unbound in rewrite rule" (ppr var)
-\end{code}
-
-
-       ---------------------------------------------
-               The inner workings of matching
-       ---------------------------------------------
-
-\begin{code}
--- These two definitions are not the same as in Subst,
--- but they simple and direct, and purely local to this module
--- The third, for TvSubstEnv, is the same as in VarEnv, but repeated here
--- for uniformity with IdSubstEnv
-type SubstEnv   = (TvSubstEnv, IdSubstEnv)     
-type IdSubstEnv = IdEnv    CoreExpr            
-
-emptySubstEnv :: SubstEnv
-emptySubstEnv = (emptyVarEnv, emptyVarEnv)
-
-
---     At one stage I tried to match even if there are more 
---     template args than real args.
-
---     I now think this is probably a bad idea.
---     Should the template (map f xs) match (map g)?  I think not.
---     For a start, in general eta expansion wastes work.
---     SLPJ July 99
-
-
-match :: MatchEnv
-      -> SubstEnv
-      -> CoreExpr              -- Template
-      -> CoreExpr              -- Target
-      -> Maybe SubstEnv
-
--- See the notes with Unify.match, which matches types
--- Everything is very similar for terms
-
--- Interesting examples:
--- Consider matching
---     \x->f      against    \f->f
--- When we meet the lambdas we must remember to rename f to f' in the
--- second expresion.  The RnEnv2 does that.
---
--- Consider matching 
---     forall a. \b->b    against   \a->3
--- We must rename the \a.  Otherwise when we meet the lambdas we 
--- might substitute [a/b] in the template, and then erroneously 
--- succeed in matching what looks like the template variable 'a' against 3.
-
--- The Var case follows closely what happens in Unify.match
-match menv subst@(tv_subst, id_subst) (Var v1) e2 
-  | v1 `elemVarSet` me_tmpls menv
-  = case lookupVarEnv id_subst v1' of
-       Nothing | any (inRnEnvR rn_env) (varSetElems (exprFreeVars e2))
-               -> Nothing      -- Occurs check failure
-               -- e.g. match forall a. (\x-> a x) against (\y. y y)
-
-               | otherwise
-               -> Just (tv_subst, extendVarEnv id_subst v1 e2)
-
-       Just e2' | tcEqExprX (nukeRnEnvL rn_env) e2' e2 
-                -> Just subst
-
-       other -> Nothing
-
-  | otherwise  -- v1 is not a template variable
-  = case e2 of
-       Var v2 | v1' == rnOccR rn_env v2 -> Just subst
-       other                            -> Nothing
-  where
-    rn_env = me_env menv
-    v1'    = rnOccL rn_env v1
-
--- Here is another important rule: if the term being matched is a
--- variable, we expand it so long as its unfolding is a WHNF
--- (Its occurrence information is not necessarily up to date,
---  so we don't use it.)
-match menv subst e1 (Var v2)
-  | isCheapUnfolding unfolding
-  = match menv subst e1 (unfoldingTemplate unfolding)
-  where
-    unfolding = idUnfolding v2
-
-match menv subst (Lit lit1) (Lit lit2)
-  | lit1 == lit2
-  = Just subst
-
-match menv subst (App f1 a1) (App f2 a2)
-  = do         { subst' <- match menv subst f1 f2
-       ; match menv subst' a1 a2 }
-
-match menv subst (Lam x1 e1) (Lam x2 e2)
-  = match menv' subst e1 e2
-  where
-    menv' = menv { me_env = rnBndr2 (me_env menv) x1 x2 }
-
--- This rule does eta expansion
---             (\x.M)  ~  N    iff     M  ~  N x
-match menv subst (Lam x1 e1) e2
-  = match menv' subst e1 (App e2 (varToCoreExpr new_x))
-  where
-    (rn_env', new_x) = rnBndrL (me_env menv) x1
-    menv' = menv { me_env = rn_env' }
-
--- Eta expansion the other way
---     M  ~  (\y.N)    iff   M y     ~  N
-match menv subst e1 (Lam x2 e2)
-  = match menv' subst (App e1 (varToCoreExpr new_x)) e2
-  where
-    (rn_env', new_x) = rnBndrR (me_env menv) x2
-    menv' = menv { me_env = rn_env' }
-
-match menv subst (Case e1 x1 ty1 alts1) (Case e2 x2 ty2 alts2)
-  = do { subst1 <- match_ty menv subst ty1 ty2
-       ; subst2 <- match menv subst1 e1 e2
-       ; let menv' = menv { me_env = rnBndr2 (me_env menv) x2 x2 }
-       ; match_alts menv' subst2 alts1 alts2   -- Alts are both sorted
-       }
-
-match menv subst (Type ty1) (Type ty2)
-  = match_ty menv subst ty1 ty2
-
-match menv subst (Note (Coerce to1 from1) e1) (Note (Coerce to2 from2) e2)
-  = do { subst1 <- match_ty menv subst  to1   to2
-       ; subst2 <- match_ty menv subst1 from1 from2
-       ; match menv subst2 e1 e2 }
-
--- This is an interesting rule: we simply ignore lets in the 
--- term being matched against!  The unfolding inside it is (by assumption)
--- already inside any occurrences of the bound variables, so we'll expand
--- them when we encounter them.
-match menv subst e1 (Let (NonRec x2 r2) e2)
-  = match menv' subst e1 e2
-  where
-    menv' = menv { me_env = fst (rnBndrR (me_env menv) x2) }
-       -- It's important to do this renaming. For example:
-       -- Matching
-       --      forall f,x,xs. f (x:xs)
-       --   against
-       --      f (let y = e in (y:[]))
-       -- We must not get success with x->y!  Instead, we 
-       -- need an occurs check.
-
--- Everything else fails
-match menv subst e1 e2 = Nothing
-
-------------------------------------------
-match_alts :: MatchEnv
-      -> SubstEnv
-      -> [CoreAlt]             -- Template
-      -> [CoreAlt]             -- Target
-      -> Maybe SubstEnv
-match_alts menv subst [] []
-  = return subst
-match_alts menv subst ((c1,vs1,r1):alts1) ((c2,vs2,r2):alts2)
-  | c1 == c2
-  = do { subst1 <- match menv' subst r1 r2
-       ; match_alts menv subst1 alts1 alts2 }
-  where
-    menv' :: MatchEnv
-    menv' = menv { me_env = rnBndrs2 (me_env menv) vs1 vs2 }
-
-match_alts menv subst alts1 alts2 
-  = Nothing
-\end{code}
-
-Matching Core types: use the matcher in TcType.
-Notice that we treat newtypes as opaque.  For example, suppose 
-we have a specialised version of a function at a newtype, say 
-       newtype T = MkT Int
-We only want to replace (f T) with f', not (f Int).
-
-\begin{code}
-------------------------------------------
-match_ty menv (tv_subst, id_subst) ty1 ty2
-  = do { tv_subst' <- Unify.ruleMatchTyX menv tv_subst ty1 ty2
-       ; return (tv_subst', id_subst) }
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection{Checking a program for failing rule applications}
-%*                                                                     *
-%************************************************************************
-
------------------------------------------------------
-                       Game plan
------------------------------------------------------
-
-We want to know what sites have rules that could have fired but didn't.
-This pass runs over the tree (without changing it) and reports such.
-
-NB: we assume that this follows a run of the simplifier, so every Id
-occurrence (including occurrences of imported Ids) is decorated with
-all its (active) rules.  No need to construct a rule base or anything
-like that.
-
-\begin{code}
-ruleCheckProgram :: CompilerPhase -> String -> [CoreBind] -> SDoc
--- Report partial matches for rules beginning 
--- with the specified string
-ruleCheckProgram phase rule_pat binds 
-  | isEmptyBag results
-  = text "Rule check results: no rule application sites"
-  | otherwise
-  = vcat [text "Rule check results:",
-         line,
-         vcat [ p $$ line | p <- bagToList results ]
-        ]
-  where
-    results = unionManyBags (map (ruleCheckBind (phase, rule_pat)) binds)
-    line = text (replicate 20 '-')
-         
-type RuleCheckEnv = (CompilerPhase, String)    -- Phase and Pattern
-
-ruleCheckBind :: RuleCheckEnv -> CoreBind -> Bag SDoc
-   -- The Bag returned has one SDoc for each call site found
-ruleCheckBind env (NonRec b r) = ruleCheck env r
-ruleCheckBind env (Rec prs)    = unionManyBags [ruleCheck env r | (b,r) <- prs]
-
-ruleCheck :: RuleCheckEnv -> CoreExpr -> Bag SDoc
-ruleCheck env (Var v)      = emptyBag
-ruleCheck env (Lit l)      = emptyBag
-ruleCheck env (Type ty)     = emptyBag
-ruleCheck env (App f a)     = ruleCheckApp env (App f a) []
-ruleCheck env (Note n e)    = ruleCheck env e
-ruleCheck env (Let bd e)    = ruleCheckBind env bd `unionBags` ruleCheck env e
-ruleCheck env (Lam b e)     = ruleCheck env e
-ruleCheck env (Case e _ _ as) = ruleCheck env e `unionBags` 
-                               unionManyBags [ruleCheck env r | (_,_,r) <- as]
-
-ruleCheckApp env (App f a) as = ruleCheck env a `unionBags` ruleCheckApp env f (a:as)
-ruleCheckApp env (Var f) as   = ruleCheckFun env f as
-ruleCheckApp env other as     = ruleCheck env other
-\end{code}
-
-\begin{code}
-ruleCheckFun :: RuleCheckEnv -> Id -> [CoreExpr] -> Bag SDoc
--- Produce a report for all rules matching the predicate
--- saying why it doesn't match the specified application
-
-ruleCheckFun (phase, pat) fn args
-  | null name_match_rules = emptyBag
-  | otherwise            = unitBag (ruleAppCheck_help phase fn args name_match_rules)
-  where
-    name_match_rules = filter match (idCoreRules fn)
-    match rule = pat `isPrefixOf` unpackFS (ruleName rule)
-
-ruleAppCheck_help :: CompilerPhase -> Id -> [CoreExpr] -> [CoreRule] -> SDoc
-ruleAppCheck_help phase fn args rules
-  =    -- The rules match the pattern, so we want to print something
-    vcat [text "Expression:" <+> ppr (mkApps (Var fn) args),
-         vcat (map check_rule rules)]
-  where
-    n_args = length args
-    i_args = args `zip` [1::Int ..]
-    rough_args = map roughTopName args
-
-    check_rule rule = rule_herald rule <> colon <+> rule_info rule
-
-    rule_herald (BuiltinRule { ru_name = name })
-       = ptext SLIT("Builtin rule") <+> doubleQuotes (ftext name)
-    rule_herald (Rule { ru_name = name })
-       = ptext SLIT("Rule") <+> doubleQuotes (ftext name)
-
-    rule_info rule
-       | Just _ <- matchRule noBlackList emptyInScopeSet args rough_args rule
-       = text "matches (which is very peculiar!)"
-
-    rule_info (BuiltinRule {}) = text "does not match"
-
-    rule_info (Rule { ru_name = name, ru_act = act, 
-                     ru_bndrs = rule_bndrs, ru_args = rule_args})
-       | not (isActive phase act)    = text "active only in later phase"
-       | n_args < n_rule_args        = text "too few arguments"
-       | n_mismatches == n_rule_args = text "no arguments match"
-       | n_mismatches == 0           = text "all arguments match (considered individually), but rule as a whole does not"
-       | otherwise                   = text "arguments" <+> ppr mismatches <+> text "do not match (1-indexing)"
-       where
-         n_rule_args  = length rule_args
-         n_mismatches = length mismatches
-         mismatches   = [i | (rule_arg, (arg,i)) <- rule_args `zip` i_args,
-                             not (isJust (match_fn rule_arg arg))]
-
-         lhs_fvs = exprsFreeVars rule_args     -- Includes template tyvars
-         match_fn rule_arg arg = match menv emptySubstEnv rule_arg arg
-               where
-                 in_scope = lhs_fvs `unionVarSet` exprFreeVars arg
-                 menv = ME { me_env   = mkRnEnv2 (mkInScopeSet in_scope)
-                           , me_tmpls = mkVarSet rule_bndrs }
-\end{code}
-