The ru_local field of a CoreRule is False for implicit Ids
authorsimonpj@microsoft.com <unknown>
Fri, 30 Mar 2007 14:43:44 +0000 (14:43 +0000)
committersimonpj@microsoft.com <unknown>
Fri, 30 Mar 2007 14:43:44 +0000 (14:43 +0000)
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
compiler/deSugar/Desugar.lhs
compiler/iface/TcIface.lhs

index 09e41aa..9b9d8fa 100644 (file)
@@ -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
index 99be1b0..0801b1c 100644 (file)
@@ -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,
index d5cc5fd..b6f1f48 100644 (file)
@@ -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