Skip to content

Allow plugins to define built-in rules

Conal Elliott has an application in which he wants a plugin to add some new BuiltinRules to the mg_rules of the ModGuts of the module being compiled. He needs a built-in rule (which runs some custom code) rather than a vanilla CoreRule (which pattern-matches the argument).

But then he got a GHC panic

get a GHC panic: “No match in record selector ru_args”. 

Turns out it comes from these lines in OccAnal

    imp_rule_edges = foldr (plusVarEnv_C unionVarSet) emptyVarEnv
                            [ mapVarEnv (const maps_to) (exprFreeIds arg `delVarSetList` ru_bndrs imp_rule)
                            | imp_rule <- imp_rules
                            , let maps_to = exprFreeIds (ru_rhs imp_rule)
                                             `delVarSetList` ru_bndrs imp_rule
                            , arg <- ru_args imp_rule ]

This code is just working out what locally-defined variables should be kept alive by the mg_rules for imported Ids. But BuiltinRules don't have any ru_args.

Easy fix: just don't traverse builtin rules in this scan. In Conal's case, the rules that his plugin adds certainly don't mention locally-defined Ids.

I'll do this shortly.

Edited by conal
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information