New syntax for GADT-style record declarations, and associated refactoring
[ghc-hetmet.git] / compiler / typecheck / TcRules.lhs
index c7e951f..a95251d 100644 (file)
@@ -1,49 +1,49 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The AQUA Project, Glasgow University, 1993-1998
 %
-\section[TcRules]{Typechecking transformation rules}
+
+TcRules: Typechecking transformation rules
 
 \begin{code}
 module TcRules ( tcRules ) where
 
-#include "HsVersions.h"
-
-import HsSyn           ( RuleDecl(..), LRuleDecl, RuleBndr(..), mkHsDictLet )
+import HsSyn
 import TcRnMonad
-import TcSimplify      ( tcSimplifyRuleLhs, tcSimplifyInferCheck )
-import TcMType         ( newFlexiTyVarTy, zonkQuantifiedTyVar, tcSkolSigTyVars )
-import TcType          ( tyVarsOfTypes, openTypeKind, SkolemInfo(..), substTyWith, mkTyVarTys )
-import TcHsType                ( UserTypeCtxt(..), tcHsPatSigType )
-import TcExpr          ( tcMonoExpr )
-import TcEnv           ( tcExtendIdEnv, tcExtendTyVarEnv )
-import Inst            ( instToId )
-import Id              ( idType, mkLocalId )
-import Name            ( Name )
-import SrcLoc          ( noLoc, unLoc )
+import TcSimplify
+import TcMType
+import TcType
+import TcHsType
+import TcExpr
+import TcEnv
+import Inst
+import Id
+import Name
+import SrcLoc
 import Outputable
+import FastString
 \end{code}
 
 \begin{code}
 tcRules :: [LRuleDecl Name] -> TcM [LRuleDecl TcId]
-tcRules decls = mappM (wrapLocM tcRule) decls
+tcRules decls = mapM (wrapLocM tcRule) decls
 
 tcRule :: RuleDecl Name -> TcM (RuleDecl TcId)
 tcRule (HsRule name act vars lhs fv_lhs rhs fv_rhs)
-  = addErrCtxt (ruleCtxt name)                 $
-    traceTc (ptext SLIT("---- Rule ------")
-                <+> ppr name)                  `thenM_` 
-    newFlexiTyVarTy openTypeKind               `thenM` \ rule_ty ->
+  = addErrCtxt (ruleCtxt name)                 $ do
+    traceTc (ptext (sLit "---- Rule ------") <+> ppr name)
+    rule_ty <- newFlexiTyVarTy openTypeKind
 
        -- Deal with the tyvars mentioned in signatures
-    tcRuleBndrs vars (\ ids ->
+    (ids, lhs', rhs', lhs_lie, rhs_lie) <-
+      tcRuleBndrs vars $ \ ids -> do
                -- Now LHS and RHS
-       getLIE (tcMonoExpr lhs rule_ty) `thenM` \ (lhs', lhs_lie) ->
-       getLIE (tcMonoExpr rhs rule_ty) `thenM` \ (rhs', rhs_lie) ->
-       returnM (ids, lhs', rhs', lhs_lie, rhs_lie)
-    )                          `thenM` \ (ids, lhs', rhs', lhs_lie, rhs_lie) ->
+        (lhs', lhs_lie) <- getLIE (tcMonoExpr lhs rule_ty)
+        (rhs', rhs_lie) <- getLIE (tcMonoExpr rhs rule_ty)
+        return (ids, lhs', rhs', lhs_lie, rhs_lie)
 
                -- Check that LHS has no overloading at all
-    tcSimplifyRuleLhs lhs_lie  `thenM` \ (lhs_dicts, lhs_binds) ->
+    (lhs_dicts, lhs_binds) <- tcSimplifyRuleLhs lhs_lie
 
        -- Gather the template variables and tyvars
     let
@@ -70,24 +70,23 @@ tcRule (HsRule name act vars lhs fv_lhs rhs fv_rhs)
        -- during zonking (see TcHsSyn.zonkRule)
        --
        forall_tvs = tyVarsOfTypes (rule_ty : map idType tpl_ids)
-    in
+
        -- RHS can be a bit more lenient.  In particular,
        -- we let constant dictionaries etc float outwards
        --
        -- NB: tcSimplifyInferCheck zonks the forall_tvs, and 
        --     knocks out any that are constrained by the environment
-    tcSimplifyInferCheck (text "tcRule")
-                        forall_tvs
-                        lhs_dicts rhs_lie      `thenM` \ (forall_tvs1, rhs_binds) ->
-    mappM zonkQuantifiedTyVar forall_tvs1      `thenM` \ forall_tvs2 ->
-       -- This zonk is exactly the same as the one in TcBinds.tcBindWithSigs
-
-    returnM (HsRule name act
-                   (map (RuleBndr . noLoc) (forall_tvs2 ++ tpl_ids))   -- yuk
+    loc <- getInstLoc (SigOrigin (RuleSkol name))
+    (forall_tvs1, rhs_binds) <- tcSimplifyInferCheck loc
+                                        forall_tvs
+                                        lhs_dicts rhs_lie
+
+    return (HsRule name act
+                   (map (RuleBndr . noLoc) (forall_tvs1 ++ tpl_ids))   -- yuk
                    (mkHsDictLet lhs_binds lhs') fv_lhs
                    (mkHsDictLet rhs_binds rhs') fv_rhs)
 
-
+tcRuleBndrs :: [RuleBndr Name] -> ([Id] -> TcM a) -> TcM a
 tcRuleBndrs [] thing_inside = thing_inside []
 tcRuleBndrs (RuleBndr var : vars) thing_inside
   = do         { ty <- newFlexiTyVarTy openTypeKind
@@ -98,7 +97,7 @@ tcRuleBndrs (RuleBndrSig var rn_ty : vars) thing_inside
 --  e.g        x :: a->a
 --  The tyvar 'a' is brought into scope first, just as if you'd written
 --             a::*, x :: a->a
-  = do { let ctxt = RuleSigCtxt (unLoc var)
+  = do { let ctxt = FunSigCtxt (unLoc var)
        ; (tyvars, ty) <- tcHsPatSigType ctxt rn_ty
        ; let skol_tvs = tcSkolSigTyVars (SigSkol ctxt) tyvars
              id_ty = substTyWith tyvars (mkTyVarTys skol_tvs) ty
@@ -107,7 +106,8 @@ tcRuleBndrs (RuleBndrSig var rn_ty : vars) thing_inside
          tcExtendIdEnv [id] $
          tcRuleBndrs vars (\ids -> thing_inside (id:ids)) }
 
-ruleCtxt name = ptext SLIT("When checking the transformation rule") <+> 
+ruleCtxt :: FastString -> SDoc
+ruleCtxt name = ptext (sLit "When checking the transformation rule") <+> 
                doubleQuotes (ftext name)
 \end{code}