+\subsection{Rules}
+%* *
+%*********************************************************
+
+\begin{code}
+rnDecl (RuleD (IfaceRule rule_name vars fn args rhs src_loc))
+ = pushSrcLocRn src_loc $
+ lookupOccRn fn `thenRn` \ fn' ->
+ rnCoreBndrs vars $ \ vars' ->
+ mapFvRn rnCoreExpr args `thenRn` \ (args', fvs1) ->
+ rnCoreExpr rhs `thenRn` \ (rhs', fvs2) ->
+ returnRn (RuleD (IfaceRule rule_name vars' fn' args' rhs' src_loc),
+ (fvs1 `plusFV` fvs2) `addOneFV` fn')
+
+rnDecl (RuleD (IfaceRuleOut fn rule))
+ -- This one is used for BuiltInRules
+ -- The rule itself is already done, but the thing
+ -- to attach it to is not.
+ = lookupOccRn fn `thenRn` \ fn' ->
+ returnRn (RuleD (IfaceRuleOut fn' rule), unitFV fn')
+
+rnDecl (RuleD (HsRule rule_name tvs vars lhs rhs src_loc))
+ = ASSERT( null tvs )
+ pushSrcLocRn src_loc $
+
+ bindTyVarsFV2Rn doc (map UserTyVar sig_tvs) $ \ sig_tvs' _ ->
+ bindLocalsFVRn doc (map get_var vars) $ \ ids ->
+ mapFvRn rn_var (vars `zip` ids) `thenRn` \ (vars', fv_vars) ->
+
+ rnExpr lhs `thenRn` \ (lhs', fv_lhs) ->
+ rnExpr rhs `thenRn` \ (rhs', fv_rhs) ->
+ checkRn (validRuleLhs ids lhs')
+ (badRuleLhsErr rule_name lhs') `thenRn_`
+ let
+ bad_vars = [var | var <- ids, not (var `elemNameSet` fv_lhs)]
+ in
+ mapRn (addErrRn . badRuleVar rule_name) bad_vars `thenRn_`
+ returnRn (RuleD (HsRule rule_name sig_tvs' vars' lhs' rhs' src_loc),
+ fv_vars `plusFV` fv_lhs `plusFV` fv_rhs)
+ where
+ doc = text "the transformation rule" <+> ptext rule_name
+ sig_tvs = extractRuleBndrsTyVars vars
+
+ get_var (RuleBndr v) = v
+ get_var (RuleBndrSig v _) = v
+
+ rn_var (RuleBndr v, id) = returnRn (RuleBndr id, emptyFVs)
+ rn_var (RuleBndrSig v t, id) = rnHsType doc t `thenRn` \ (t', fvs) ->
+ returnRn (RuleBndrSig id t', fvs)
+\end{code}
+
+
+%*********************************************************
+%* *