diff options
author | simonpj@microsoft.com <unknown> | 2006-05-04 11:24:30 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2006-05-04 11:24:30 +0000 |
commit | c276b9b6d9b6f57cb99c0509d8a5a246d675e2b2 (patch) | |
tree | 4560efad5a20092b92301f71c8f9f9752c5fce38 /compiler/specialise/Rules.lhs | |
parent | 64f00b23e172aae40609b5deca87f83aa6f5447a (diff) | |
download | haskell-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.lhs | 15 |
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 |