Improve RULE matching a bit more
authorsimonpj@microsoft.com <unknown>
Sat, 24 Jun 2006 16:04:21 +0000 (16:04 +0000)
committersimonpj@microsoft.com <unknown>
Sat, 24 Jun 2006 16:04:21 +0000 (16:04 +0000)
commit7d44782fdfab8c280ae8de1846cb40a78b6edb95
tree78de30fa4dc288860e2d8f996730e32b0dfb4b06
parentc21d7cede2478d147340cd1ebdb26875d3ba333b
Improve RULE matching a bit more

Consider this example (provided by Roman)

foo :: Int -> Maybe Int -> Int
foo 0 (Just n) = n
foo m (Just n) = foo (m-n) (Just n)

SpecConstr sees this fragment:

case w_smT of wild_Xf [Just A] {
  Data.Maybe.Nothing -> lvl_smf;
  Data.Maybe.Just n_acT [Just S(L)] ->
    case n_acT of wild1_ams [Just A] { GHC.Base.I# y_amr [Just L] ->
    $wfoo_smW (GHC.Prim.-# ds_Xmb y_amr) wild_Xf
    }};

and correctly generates the rule

RULES: "SC:$wfoo1" [0] __forall {y_amr [Just L] :: GHC.Prim.Int#
  sc_snn :: GHC.Prim.Int#}
  $wfoo_smW sc_snn (Data.Maybe.Just @ GHC.Base.Int (GHC.Base.I# y_amr))
  = $s$wfoo_sno y_amr sc_snn ;]

BUT we must ensure that this rule matches in the original function!
Note that the call to $wfoo is
    $wfoo_smW (GHC.Prim.-# ds_Xmb y_amr) wild_Xf

During matching we expand wild_Xf to (Just n_acT).  But then we must also
expand n_acT to (I# y_amr).  And we can only do that if we look up n_acT
in the in-scope set, because in wild_Xf's unfolding it won't have an unfolding
at all.

Happily, fixing the bug is easy: add a call to 'lookupRnInScope' in the
(Var v2) case of 'match'.
compiler/basicTypes/VarEnv.lhs
compiler/specialise/Rules.lhs