X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcRules.lhs;h=b14c2c94499f7feef61035c2168846aa47d04352;hb=50bc39808cd5b483a048a4d387f937963bd0e00f;hp=0367f69689c6a6bc3d64ad5be843fdeddb6ebbb0;hpb=05afb7485eea44d6410139f8a20c94b6f66c46f2;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcRules.lhs b/ghc/compiler/typecheck/TcRules.lhs index 0367f69..b14c2c9 100644 --- a/ghc/compiler/typecheck/TcRules.lhs +++ b/ghc/compiler/typecheck/TcRules.lhs @@ -8,64 +8,37 @@ module TcRules ( tcRules ) where #include "HsVersions.h" -import HsSyn ( RuleDecl(..), RuleBndr(..), collectRuleBndrSigTys ) -import CoreSyn ( CoreRule(..) ) -import RnHsSyn ( RenamedRuleDecl ) -import TcHsSyn ( TypecheckedRuleDecl, mkHsLet ) +import HsSyn ( RuleDecl(..), LRuleDecl, RuleBndr(..), mkHsDictLet ) import TcRnMonad import TcSimplify ( tcSimplifyToDicts, tcSimplifyInferCheck ) -import TcMType ( newTyVarTy ) -import TcType ( tyVarsOfTypes, openTypeKind ) -import TcIfaceSig ( tcCoreExpr, tcCoreLamBndrs ) -import TcMonoType ( tcHsSigType, UserTypeCtxt(..), tcAddScopedTyVars ) -import TcExpr ( tcCheckRho ) -import TcEnv ( tcExtendLocalValEnv, tcLookupGlobalId, tcLookupId ) +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 Outputable \end{code} \begin{code} -tcRules :: [RenamedRuleDecl] -> TcM [TypecheckedRuleDecl] -tcRules decls = mappM tcRule decls - -tcRule :: RenamedRuleDecl -> TcM TypecheckedRuleDecl -tcRule (IfaceRule name act vars fun args rhs src_loc) - = addSrcLoc src_loc $ - addErrCtxt (ruleCtxt name) $ - tcLookupGlobalId fun `thenM` \ fun' -> - tcCoreLamBndrs vars $ \ vars' -> - mappM tcCoreExpr args `thenM` \ args' -> - tcCoreExpr rhs `thenM` \ rhs' -> - returnM (IfaceRuleOut fun' (Rule name act vars' args' rhs')) - -tcRule (IfaceRuleOut fun rule) -- Built-in rules, and only built-in rules, - -- come this way. Usually IfaceRuleOut is only - -- used for the *output* of the type checker - = tcLookupId fun `thenM` \ fun' -> - -- NB: tcLookupId, not tcLookupGlobalId - -- Reason: when compiling GHC.Base, where eqString is defined, - -- we'll get the builtin rule for eqString, but eqString - -- will be in the *local* type environment. - -- Seems like a bit of a hack - returnM (IfaceRuleOut fun' rule) - -tcRule (HsRule name act vars lhs rhs src_loc) - = addSrcLoc src_loc $ - addErrCtxt (ruleCtxt name) $ - newTyVarTy openTypeKind `thenM` \ rule_ty -> +tcRules :: [LRuleDecl Name] -> TcM [LRuleDecl TcId] +tcRules decls = mappM (wrapLocM tcRule) decls - -- Deal with the tyvars mentioned in signatures - tcAddScopedTyVars (collectRuleBndrSigTys vars) ( +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 -> - -- Ditto forall'd variables - mappM new_id vars `thenM` \ ids -> - tcExtendLocalValEnv ids $ - + -- Deal with the tyvars mentioned in signatures + tcRuleBndrs vars (\ ids -> -- Now LHS and RHS - getLIE (tcCheckRho lhs rule_ty) `thenM` \ (lhs', lhs_lie) -> - getLIE (tcCheckRho rhs rule_ty) `thenM` \ (rhs', rhs_lie) -> - + 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) -> @@ -88,7 +61,7 @@ tcRule (HsRule name act vars lhs rhs src_loc) -- See the 'lhs_dicts' in tcSimplifyAndCheck for the RHS -- We initially quantify over any tyvars free in *either* the rule - -- *or* the bound variables. The latter is important. Consider + -- *or* the bound variables. The latter is important. Consider -- ss (x,(y,z)) = (x,z) -- RULE: forall v. fst (ss v) = fst v -- The type of the rhs of the rule is just a, but v::(a,(b,c)) @@ -106,17 +79,33 @@ tcRule (HsRule name act vars lhs rhs src_loc) 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 (forall_tvs1 ++ tpl_ids)) -- yuk - (mkHsLet lhs_binds lhs') - (mkHsLet rhs_binds rhs') - src_loc) + (map (RuleBndr . noLoc) (forall_tvs2 ++ tpl_ids)) -- yuk + (mkHsDictLet lhs_binds lhs') fv_lhs + (mkHsDictLet rhs_binds rhs') fv_rhs) where - new_id (RuleBndr var) = newTyVarTy openTypeKind `thenM` \ ty -> - returnM (mkLocalId var ty) - new_id (RuleBndrSig var rn_ty) = tcHsSigType (RuleSigCtxt var) rn_ty `thenM` \ ty -> - returnM (mkLocalId var ty) + +tcRuleBndrs [] thing_inside = thing_inside [] +tcRuleBndrs (RuleBndr var : vars) thing_inside + = do { ty <- newFlexiTyVarTy openTypeKind + ; let id = mkLocalId (unLoc var) ty + ; tcExtendIdEnv [id] $ + tcRuleBndrs vars (\ids -> thing_inside (id:ids)) } +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) + ; (tyvars, ty) <- tcHsPatSigType ctxt rn_ty + ; let skol_tvs = tcSkolSigTyVars (SigSkol ctxt) tyvars + id_ty = substTyWith tyvars (mkTyVarTys skol_tvs) ty + id = mkLocalId (unLoc var) id_ty + ; tcExtendTyVarEnv skol_tvs $ + tcExtendIdEnv [id] $ + tcRuleBndrs vars (\ids -> thing_inside (id:ids)) } ruleCtxt name = ptext SLIT("When checking the transformation rule") <+> doubleQuotes (ftext name)