X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcRules.lhs;h=e4898708d8eafe23ebd8e0ed6c029e74861fa46b;hb=2662dbc5b2c30fc11ccb99e7f9b2dba794d680ba;hp=3ee95cf4a28109d8ec3039be942ca80bcf99b4dd;hpb=3220e36e51df973b2634cd800f9d6e761d4f01be;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcRules.lhs b/compiler/typecheck/TcRules.lhs index 3ee95cf..e489870 100644 --- a/compiler/typecheck/TcRules.lhs +++ b/compiler/typecheck/TcRules.lhs @@ -6,13 +6,6 @@ TcRules: Typechecking transformation rules \begin{code} -{-# OPTIONS -w #-} --- The above warning supression flag is a temporary kludge. --- While working on this module you are encouraged to remove it and fix --- any warnings in the module. See --- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings --- for details - module TcRules ( tcRules ) where import HsSyn @@ -31,6 +24,22 @@ import Outputable import FastString \end{code} +Note [Typechecking rules] +~~~~~~~~~~~~~~~~~~~~~~~~~ +We *infer* the typ of the LHS, and use that type to *check* the type of +the RHS. That means that higher-rank rules work reasonably well. Here's +an example (test simplCore/should_compile/rule2.hs) produced by Roman: + + foo :: (forall m. m a -> m b) -> m a -> m b + foo f = ... + + bar :: (forall m. m a -> m a) -> m a -> m a + bar f = ... + + {-# RULES "foo/bar" foo = bar #-} + +He wanted the rule to typecheck. + \begin{code} tcRules :: [LRuleDecl Name] -> TcM [LRuleDecl TcId] tcRules decls = mapM (wrapLocM tcRule) decls @@ -39,15 +48,14 @@ tcRule :: RuleDecl Name -> TcM (RuleDecl TcId) tcRule (HsRule name act vars lhs fv_lhs rhs fv_rhs) = addErrCtxt (ruleCtxt name) $ do traceTc (ptext (sLit "---- Rule ------") <+> ppr name) - rule_ty <- newFlexiTyVarTy openTypeKind -- Deal with the tyvars mentioned in signatures - (ids, lhs', rhs', lhs_lie, rhs_lie) <- + (ids, lhs', rhs', lhs_lie, rhs_lie, rule_ty) <- tcRuleBndrs vars $ \ ids -> do - -- Now LHS and RHS - (lhs', lhs_lie) <- getLIE (tcMonoExpr lhs rule_ty) + -- Now LHS and RHS; see Note [Typechecking rules] + ((lhs', rule_ty), lhs_lie) <- getLIE (tcInferRho lhs) (rhs', rhs_lie) <- getLIE (tcMonoExpr rhs rule_ty) - return (ids, lhs', rhs', lhs_lie, rhs_lie) + return (ids, lhs', rhs', lhs_lie, rhs_lie, rule_ty) -- Check that LHS has no overloading at all (lhs_dicts, lhs_binds) <- tcSimplifyRuleLhs lhs_lie @@ -93,7 +101,7 @@ tcRule (HsRule name act vars lhs fv_lhs rhs fv_rhs) (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 @@ -113,6 +121,7 @@ tcRuleBndrs (RuleBndrSig var rn_ty : vars) thing_inside tcExtendIdEnv [id] $ tcRuleBndrs vars (\ids -> thing_inside (id:ids)) } +ruleCtxt :: FastString -> SDoc ruleCtxt name = ptext (sLit "When checking the transformation rule") <+> doubleQuotes (ftext name) \end{code}