Skip to content
  • Simon Peyton Jones's avatar
    Improve RULE matching a bit more · 7d44782f
    Simon Peyton Jones authored
    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'.
    7d44782f