summaryrefslogtreecommitdiff
path: root/compiler/specialise/Rules.lhs
diff options
context:
space:
mode:
authorsimonpj@microsoft.com <unknown>2006-05-04 11:24:30 +0000
committersimonpj@microsoft.com <unknown>2006-05-04 11:24:30 +0000
commitc276b9b6d9b6f57cb99c0509d8a5a246d675e2b2 (patch)
tree4560efad5a20092b92301f71c8f9f9752c5fce38 /compiler/specialise/Rules.lhs
parent64f00b23e172aae40609b5deca87f83aa6f5447a (diff)
downloadhaskell-c276b9b6d9b6f57cb99c0509d8a5a246d675e2b2.tar.gz
Fix a bug in rule matching
The rule matcher uses a "rough-match" pre-filter, which was being too aggressive. The case looked like this: rule: f True expr: case e of x { True -> f x } Jues because x doesn't immediately look like True, we shouldn't say "can't match", but that is exactly what ruleCantMatch was doing.
Diffstat (limited to 'compiler/specialise/Rules.lhs')
-rw-r--r--compiler/specialise/Rules.lhs15
1 files changed, 10 insertions, 5 deletions
diff --git a/compiler/specialise/Rules.lhs b/compiler/specialise/Rules.lhs
index 4d743140ea..4c223d40d6 100644
--- a/compiler/specialise/Rules.lhs
+++ b/compiler/specialise/Rules.lhs
@@ -115,8 +115,13 @@ ruleCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool
-- definitely can't match 'tpl' by instantiating 'tpl'.
-- It's only a one-way match; unlike instance matching we
-- don't consider unification
+--
+-- Notice that there is no case
+-- ruleCantMatch (Just n1 : ts) (Nothing : as) = True
+-- Reason: a local variable 'v' in the actuals might
+-- have an unfolding which is a global.
+-- This quite often happens with case scrutinees.
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}
@@ -403,10 +408,10 @@ match menv subst@(tv_subst, id_subst) (Var v1) e2
other -> Nothing
- | otherwise -- v1 is not a template variable
- = case e2 of
- Var v2 | v1' == rnOccR rn_env v2 -> Just subst
- other -> Nothing
+ | -- v1 is not a template variable; check for an exact match with e2
+ Var v2 <- e2, v1' == rnOccR rn_env v2
+ = Just subst
+
where
rn_env = me_env menv
v1' = rnOccL rn_env v1