From ec81fddea750b1ad21f63b7c4307c15f89f10dfd Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Fri, 30 Mar 2007 14:43:44 +0000 Subject: [PATCH] The ru_local field of a CoreRule is False for implicit Ids MERGE to 6.6.1 For class-ops, record selectors, data constructors, we want the ru_local field of the Rule to be False. We do not attach the rule to the binding for the Id, because there simply isn't a binding until the code gen stage. (NB: the ru_local field is different to the orphan-hood of the rule.) This fixes a bug that meant that RULES on class ops were never exported. --- compiler/coreSyn/CoreSyn.lhs | 4 ++++ compiler/deSugar/Desugar.lhs | 7 ++++--- compiler/iface/TcIface.lhs | 5 +++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/coreSyn/CoreSyn.lhs b/compiler/coreSyn/CoreSyn.lhs index 09e41aa..9b9d8fae 100644 --- a/compiler/coreSyn/CoreSyn.lhs +++ b/compiler/coreSyn/CoreSyn.lhs @@ -218,6 +218,10 @@ data CoreRule -- Locality ru_local :: Bool -- The fn at the head of the rule is -- defined in the same module as the rule + -- and is not an implicit Id (like a record sel + -- class op, or data con) + -- NB: ru_local is *not* used to decide orphan-hood + -- c.g. MkIface.coreRuleToIfaceRule } | BuiltinRule { -- Built-in rules are used for constant folding diff --git a/compiler/deSugar/Desugar.lhs b/compiler/deSugar/Desugar.lhs index 99be1b0..0801b1c 100644 --- a/compiler/deSugar/Desugar.lhs +++ b/compiler/deSugar/Desugar.lhs @@ -293,9 +293,10 @@ dsRule mod in_scope (L loc (HsRule name act vars lhs tv_lhs rhs fv_rhs)) -- Substitute the dict bindings eagerly, -- and take the body apart into a (f args) form - { let local_rule = nameIsLocalOrFrom mod fn_name - -- NB we can't use isLocalId in the orphan test, - -- because isLocalId isn't true of class methods + { let local_rule = isLocalId fn_id + -- NB: isLocalId is False of implicit Ids. This is good becuase + -- we don't want to attach rules to the bindings of implicit Ids, + -- because they don't show up in the bindings until just before code gen fn_name = idName fn_id rule = Rule { ru_name = name, ru_fn = fn_name, ru_act = act, diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs index d5cc5fd..b6f1f48 100644 --- a/compiler/iface/TcIface.lhs +++ b/compiler/iface/TcIface.lhs @@ -547,12 +547,13 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd ; return (bndrs', args', rhs') } ; let mb_tcs = map ifTopFreeName args ; lcl <- getLclEnv - ; let this_module = if_mod lcl ; returnM (Rule { ru_name = name, ru_fn = fn, ru_act = act, ru_bndrs = bndrs', ru_args = args', ru_rhs = rhs', ru_rough = mb_tcs, - ru_local = nameModule fn == this_module }) } + ru_local = False }) } -- An imported RULE is never for a local Id + -- or, even if it is (module loop, perhaps) + -- we'll just leave it in the non-local set where -- This function *must* mirror exactly what Rules.topFreeName does -- We could have stored the ru_rough field in the iface file -- 1.7.10.4