diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs index 88078e84cdc9d13a775b6665a716efed948740e9..3bf5e6f2f7e50d33c89f717196bd79cd600bae01 100644 --- a/ghc/compiler/basicTypes/MkId.lhs +++ b/ghc/compiler/basicTypes/MkId.lhs @@ -252,7 +252,7 @@ mkDataConWrapId data_con wrap_rhs | isNewTyCon tycon = ASSERT( null ex_tyvars && null ex_dict_args && length orig_arg_tys == 1 ) - -- No existentials on a newtype, but it can have a contex + -- No existentials on a newtype, but it can have a context -- e.g. newtype Eq a => T a = MkT (...) mkLams tyvars $ mkLams dict_args $ Lam id_arg1 $ diff --git a/ghc/compiler/basicTypes/OccName.lhs b/ghc/compiler/basicTypes/OccName.lhs index 94b50bb38ebf293f5dd0ce44cbef5a40193ea6de..90d6d9f60567a67615d78f2d5e5fa369190c7a67 100644 --- a/ghc/compiler/basicTypes/OccName.lhs +++ b/ghc/compiler/basicTypes/OccName.lhs @@ -1,4 +1,4 @@ - +% % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % diff --git a/ghc/compiler/basicTypes/RdrName.lhs b/ghc/compiler/basicTypes/RdrName.lhs index 8686f708b4e064d7f7b99eec844d99798a8f53ad..df6fc9c8bbababa0110edd555d87effa28f76616 100644 --- a/ghc/compiler/basicTypes/RdrName.lhs +++ b/ghc/compiler/basicTypes/RdrName.lhs @@ -1,4 +1,4 @@ - +% % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % diff --git a/ghc/compiler/basicTypes/Var.lhs b/ghc/compiler/basicTypes/Var.lhs index 63152610e313720007e291fc3864f6fc36f05ac1..54f010cc94119b1795d0a681e03019c81c4ee03e 100644 --- a/ghc/compiler/basicTypes/Var.lhs +++ b/ghc/compiler/basicTypes/Var.lhs @@ -1,4 +1,4 @@ -s% +% % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % \section{@Vars@: Variables} diff --git a/ghc/compiler/coreSyn/CoreLint.lhs b/ghc/compiler/coreSyn/CoreLint.lhs index 9b45e65dad2a6f7ff30e93f3154d840bbbb919cb..cacfee7eca2deeccf38566acc99c331a07f928c3 100644 --- a/ghc/compiler/coreSyn/CoreLint.lhs +++ b/ghc/compiler/coreSyn/CoreLint.lhs @@ -7,7 +7,7 @@ module CoreLint ( lintCoreBindings, lintUnfolding, - beginPass, endPass + beginPass, endPass, endPassWithRules ) where #include "HsVersions.h" @@ -16,8 +16,9 @@ import IO ( hPutStr, hPutStrLn, stderr, stdout ) import CmdLineOpts ( opt_D_show_passes, opt_DoCoreLinting, opt_PprStyle_Debug ) import CoreSyn +import Rules ( RuleBase, pprRuleBase ) import CoreFVs ( idFreeVars, mustHaveLocalBinding ) -import CoreUtils ( exprOkForSpeculation, coreBindsSize ) +import CoreUtils ( exprOkForSpeculation, coreBindsSize, mkPiType ) import Bag import Literal ( Literal, literalType ) @@ -29,11 +30,12 @@ import Subst ( mkTyVarSubst, substTy ) import Name ( isLocallyDefined, getSrcLoc ) import PprCore import ErrUtils ( doIfSet, dumpIfSet, ghcExit, Message, - ErrMsg, addErrLocHdrLine, pprBagOfErrors ) + ErrMsg, addErrLocHdrLine, pprBagOfErrors, + WarnMsg, pprBagOfWarnings) import PrimRep ( PrimRep(..) ) import SrcLoc ( SrcLoc, noSrcLoc, isNoSrcLoc ) import Type ( Type, Kind, tyVarsOfType, - splitFunTy_maybe, mkPiType, mkTyVarTy, unUsgTy, + splitFunTy_maybe, mkTyVarTy, splitForAllTy_maybe, splitTyConApp_maybe, isUnLiftedType, typeKind, isUnboxedTupleType, @@ -42,6 +44,7 @@ import Type ( Type, Kind, tyVarsOfType, import PprType ( {- instance Outputable Type -} ) import TyCon ( TyCon, isPrimTyCon, tyConDataCons ) import BasicTypes ( RecFlag(..), isNonRec ) +import Maybe import Outputable infixr 9 `thenL`, `seqL` @@ -68,7 +71,16 @@ beginPass pass_name endPass :: String -> Bool -> [CoreBind] -> IO [CoreBind] endPass pass_name dump_flag binds + = do + (binds, _) <- endPassWithRules pass_name dump_flag binds Nothing + return binds + +endPassWithRules :: String -> Bool -> [CoreBind] -> Maybe RuleBase + -> IO ([CoreBind], Maybe RuleBase) +endPassWithRules pass_name dump_flag binds rules = do + -- ToDo: force the rules? + -- Report result size if required -- This has the side effect of forcing the intermediate to be evaluated if opt_D_show_passes then @@ -78,12 +90,15 @@ endPass pass_name dump_flag binds -- Report verbosely, if required dumpIfSet dump_flag pass_name - (pprCoreBindings binds) + (pprCoreBindings binds $$ case rules of + Nothing -> empty + Just rb -> pprRuleBase rb) -- Type check lintCoreBindings pass_name binds + -- ToDo: lint the rules - return binds + return (binds, rules) \end{code} @@ -126,11 +141,13 @@ lintCoreBindings whoDunnit binds lintCoreBindings whoDunnit binds = case (initL (lint_binds binds)) of - Nothing -> doIfSet opt_D_show_passes - (hPutStr stderr ("*** Core Linted result of " ++ whoDunnit ++ "\n")) + (Nothing, Nothing) -> done_lint + + (Nothing, Just warnings) -> printDump (warn warnings) >> + done_lint - Just bad_news -> printDump (display bad_news) >> - ghcExit 1 + (Just bad_news, warns) -> printDump (display bad_news warns) >> + ghcExit 1 where -- Put all the top-level binders in scope at the start -- This is because transformation rules can bring something @@ -142,10 +159,24 @@ lintCoreBindings whoDunnit binds returnL () lint_bind (NonRec bndr rhs) = lintSingleBinding NonRecursive (bndr,rhs) - display bad_news + done_lint = doIfSet opt_D_show_passes + (hPutStr stderr ("*** Core Linted result of " ++ whoDunnit ++ "\n")) + warn warnings + = vcat [ + text ("*** Core Lint Warnings: in result of " ++ whoDunnit ++ " ***"), + warnings, + offender + ] + + display bad_news warns = vcat [ text ("*** Core Lint Errors: in result of " ++ whoDunnit ++ " ***"), bad_news, + maybe offender warn warns -- either offender or warnings (with offender) + ] + + offender + = vcat [ ptext SLIT("*** Offending Program ***"), pprCoreBindings binds, ptext SLIT("*** End of Offense ***") @@ -165,11 +196,11 @@ We use this to check all unfoldings that come in from interfaces lintUnfolding :: SrcLoc -> [Var] -- Treat these as in scope -> CoreExpr - -> Maybe Message -- Nothing => OK + -> (Maybe Message, Maybe Message) -- (Nothing,_) => OK lintUnfolding locn vars expr | not opt_DoCoreLinting - = Nothing + = (Nothing, Nothing) | otherwise = initL (addLoc (ImportedUnfolding locn) $ @@ -197,7 +228,8 @@ lintSingleBinding rec_flag (binder,rhs) checkTys binder_ty ty (mkRhsMsg binder ty) `seqL` -- Check (not isUnLiftedType) (also checks for bogus unboxed tuples) - checkL (not (isUnLiftedType binder_ty) || (isNonRec rec_flag && exprOkForSpeculation rhs)) + checkL (not (isUnLiftedType binder_ty) + || (isNonRec rec_flag && exprOkForSpeculation rhs)) (mkRhsPrimMsg binder rhs) `seqL` -- Check whether binder's specialisations contain any out-of-scope variables @@ -227,7 +259,7 @@ lintCoreExpr (Note (Coerce to_ty from_ty) expr) = lintCoreExpr expr `thenL` \ expr_ty -> lintTy to_ty `seqL` lintTy from_ty `seqL` - checkTys from_ty (unUsgTy expr_ty) (mkCoerceErr from_ty expr_ty) `seqL` + checkTys from_ty expr_ty (mkCoerceErr from_ty expr_ty) `seqL` returnL to_ty lintCoreExpr (Note other_note expr) @@ -252,10 +284,14 @@ lintCoreExpr e@(App fun arg) lintCoreExpr (Lam var expr) = addLoc (LambdaBodyOf var) $ - checkL (not (isUnboxedTupleType (idType var))) (mkUnboxedTupleMsg var) + (if isId var then + checkL (not (isUnboxedTupleType (idType var))) (mkUnboxedTupleMsg var) + else + returnL ()) `seqL` (addInScopeVars [var] $ lintCoreExpr expr `thenL` \ ty -> + returnL (mkPiType var ty)) lintCoreExpr e@(Case scrut var alts) @@ -277,7 +313,8 @@ lintCoreExpr e@(Case scrut var alts) addInScopeVars [var] ( -- Check the alternatives - checkAllCasesCovered e scrut_ty alts `seqL` + checkAllCasesCovered e scrut_ty alts `seqL` + mapL (lintCoreAlt scrut_ty) alts `thenL` \ (alt_ty : alt_tys) -> mapL (check alt_ty) alt_tys `seqL` returnL alt_ty) @@ -294,31 +331,40 @@ lintCoreExpr e@(Type ty) %* * %************************************************************************ -The boolean argument indicates whether we should flag type -applications to primitive types as being errors. +The basic version of these functions checks that the argument is a +subtype of the required type, as one would expect. \begin{code} lintCoreArgs :: Type -> [CoreArg] -> LintM Type +lintCoreArgs = lintCoreArgs0 checkTys -lintCoreArgs ty [] = returnL ty -lintCoreArgs ty (a : args) - = lintCoreArg ty a `thenL` \ res -> - lintCoreArgs res args +lintCoreArg :: Type -> CoreArg -> LintM Type +lintCoreArg = lintCoreArg0 checkTys \end{code} +The primitive version of these functions takes a check argument, +allowing a different comparison. + \begin{code} -lintCoreArg :: Type -> CoreArg -> LintM Type +lintCoreArgs0 check_tys ty [] = returnL ty +lintCoreArgs0 check_tys ty (a : args) + = lintCoreArg0 check_tys ty a `thenL` \ res -> + lintCoreArgs0 check_tys res args -lintCoreArg ty a@(Type arg_ty) +lintCoreArg0 check_tys ty a@(Type arg_ty) = lintTy arg_ty `seqL` lintTyApp ty arg_ty -lintCoreArg fun_ty arg +lintCoreArg0 check_tys fun_ty arg = -- Make sure function type matches argument lintCoreExpr arg `thenL` \ arg_ty -> - case (splitFunTy_maybe fun_ty) of - Just (arg,res) | (arg_ty == arg) -> returnL res - _ -> addErrL (mkAppMsg fun_ty arg_ty) + let + err = mkAppMsg fun_ty arg_ty + in + case splitFunTy_maybe fun_ty of + Just (arg,res) -> check_tys arg arg_ty err `seqL` + returnL res + _ -> addErrL err \end{code} \begin{code} @@ -327,6 +373,7 @@ lintTyApp ty arg_ty Nothing -> addErrL (mkTyAppMsg ty arg_ty) Just (tyvar,body) -> + if not (isTyVar tyvar) then addErrL (mkTyAppMsg ty arg_ty) else let tyvar_kind = tyVarKind tyvar argty_kind = typeKind arg_ty @@ -358,6 +405,8 @@ lintTyApps fun_ty (arg_ty : arg_tys) %************************************************************************ \begin{code} +checkAllCasesCovered :: CoreExpr -> Type -> [CoreAlt] -> LintM () + checkAllCasesCovered e ty [] = addErrL (mkNullAltsMsg e) checkAllCasesCovered e ty [(DEFAULT,_,_)] = nopL @@ -418,7 +467,7 @@ lintCoreAlt scrut_ty alt@(LitAlt lit, args, rhs) lintCoreAlt scrut_ty alt@(DataAlt con, args, rhs) = addLoc (CaseAlt alt) ( - mapL (\arg -> checkL (not (isUnboxedTupleType (idType arg))) + mapL (\arg -> checkL (not (isUnboxedTupleType (idType arg))) (mkUnboxedTupleMsg arg)) args `seqL` addInScopeVars args ( @@ -438,7 +487,8 @@ lintCoreAlt scrut_ty alt@(DataAlt con, args, rhs) )) where mk_arg b | isTyVar b = Type (mkTyVarTy b) - | otherwise = Var b + | isId b = Var b + | otherwise = pprPanic "lintCoreAlt:mk_arg " (ppr b) \end{code} %************************************************************************ @@ -451,6 +501,7 @@ lintCoreAlt scrut_ty alt@(DataAlt con, args, rhs) lintBinder :: Var -> LintM () lintBinder v = nopL -- ToDo: lint its type +-- ToDo: lint its rules lintTy :: Type -> LintM () lintTy ty = mapL checkIdInScope (varSetElems (tyVarsOfType ty)) `seqL` @@ -469,7 +520,8 @@ lintTy ty = mapL checkIdInScope (varSetElems (tyVarsOfType ty)) `seqL` type LintM a = [LintLocInfo] -- Locations -> IdSet -- Local vars in scope -> Bag ErrMsg -- Error messages so far - -> (Maybe a, Bag ErrMsg) -- Result and error messages (if any) + -> Bag WarnMsg -- Warning messages so far + -> (Maybe a, Bag ErrMsg, Bag WarnMsg) -- Result and error/warning messages (if any) data LintLocInfo = RhsOf Id -- The variable bound @@ -481,31 +533,31 @@ data LintLocInfo \end{code} \begin{code} -initL :: LintM a -> Maybe Message +initL :: LintM a -> (Maybe Message {- errors -}, Maybe Message {- warnings -}) initL m - = case (m [] emptyVarSet emptyBag) of { (_, errs) -> - if isEmptyBag errs then - Nothing - else - Just (pprBagOfErrors errs) - } + = case m [] emptyVarSet emptyBag emptyBag of + (_, errs, warns) -> (ifNonEmptyBag errs pprBagOfErrors, + ifNonEmptyBag warns pprBagOfWarnings) + where + ifNonEmptyBag bag f | isEmptyBag bag = Nothing + | otherwise = Just (f bag) returnL :: a -> LintM a -returnL r loc scope errs = (Just r, errs) +returnL r loc scope errs warns = (Just r, errs, warns) nopL :: LintM a -nopL loc scope errs = (Nothing, errs) +nopL loc scope errs warns = (Nothing, errs, warns) thenL :: LintM a -> (a -> LintM b) -> LintM b -thenL m k loc scope errs - = case m loc scope errs of - (Just r, errs') -> k r loc scope errs' - (Nothing, errs') -> (Nothing, errs') +thenL m k loc scope errs warns + = case m loc scope errs warns of + (Just r, errs', warns') -> k r loc scope errs' warns' + (Nothing, errs', warns') -> (Nothing, errs', warns') seqL :: LintM a -> LintM b -> LintM b -seqL m k loc scope errs - = case m loc scope errs of - (_, errs') -> k loc scope errs' +seqL m k loc scope errs warns + = case m loc scope errs warns of + (_, errs', warns') -> k loc scope errs' warns' mapL :: (a -> LintM b) -> [a] -> LintM [b] mapL f [] = returnL [] @@ -517,16 +569,19 @@ mapL f (x:xs) \begin{code} checkL :: Bool -> Message -> LintM () -checkL True msg loc scope errs = (Nothing, errs) -checkL False msg loc scope errs = (Nothing, addErr errs msg loc) +checkL True msg = nopL +checkL False msg = addErrL msg addErrL :: Message -> LintM a -addErrL msg loc scope errs = (Nothing, addErr errs msg loc) +addErrL msg loc scope errs warns = (Nothing, addErr errs msg loc, warns) -addErr :: Bag ErrMsg -> Message -> [LintLocInfo] -> Bag ErrMsg +addWarnL :: Message -> LintM a +addWarnL msg loc scope errs warns = (Nothing, errs, addErr warns msg loc) +addErr :: Bag ErrMsg -> Message -> [LintLocInfo] -> Bag ErrMsg +-- errors or warnings, actually... they're the same type. addErr errs_so_far msg locs - = ASSERT (not (null locs)) + = ASSERT( not (null locs) ) errs_so_far `snocBag` mk_msg msg where (loc, cxt1) = dumpLoc (head locs) @@ -539,12 +594,12 @@ addErr errs_so_far msg locs | otherwise = addErrLocHdrLine loc context msg addLoc :: LintLocInfo -> LintM a -> LintM a -addLoc extra_loc m loc scope errs - = m (extra_loc:loc) scope errs +addLoc extra_loc m loc scope errs warns + = m (extra_loc:loc) scope errs warns addInScopeVars :: [Var] -> LintM a -> LintM a -addInScopeVars ids m loc scope errs - = m loc (scope `unionVarSet` mkVarSet ids) errs +addInScopeVars ids m loc scope errs warns + = m loc (scope `unionVarSet` mkVarSet ids) errs warns \end{code} \begin{code} @@ -560,16 +615,18 @@ checkBndrIdInScope binder id ppr binder checkInScope :: SDoc -> Var -> LintM () -checkInScope loc_msg var loc scope errs +checkInScope loc_msg var loc scope errs warns | mustHaveLocalBinding var && not (var `elemVarSet` scope) - = (Nothing, addErr errs (hsep [ppr var, loc_msg]) loc) + = (Nothing, addErr errs (hsep [ppr var, loc_msg]) loc, warns) | otherwise - = (Nothing,errs) + = nopL loc scope errs warns checkTys :: Type -> Type -> Message -> LintM () -checkTys ty1 ty2 msg loc scope errs - | ty1 == ty2 = (Nothing, errs) - | otherwise = (Nothing, addErr errs msg loc) +-- check ty2 is subtype of ty1 (ie, has same structure but usage +-- annotations need only be consistent, not equal) +checkTys ty1 ty2 msg + | ty1 == ty2 = nopL + | otherwise = addErrL msg \end{code} @@ -586,7 +643,10 @@ dumpLoc (RhsOf v) dumpLoc (LambdaBodyOf b) = (getSrcLoc b, brackets (ptext SLIT("in body of lambda with binder") <+> pp_binder b)) -dumpLoc (BodyOfLetRec bs) +dumpLoc (BodyOfLetRec []) + = (noSrcLoc, brackets (ptext SLIT("In body of a letrec with no binders"))) + +dumpLoc (BodyOfLetRec bs@(_:_)) = ( getSrcLoc (head bs), brackets (ptext SLIT("in body of letrec with binders") <+> pp_binders bs)) dumpLoc (AnExpr e) @@ -598,11 +658,12 @@ dumpLoc (CaseAlt (con, args, rhs)) dumpLoc (ImportedUnfolding locn) = (locn, brackets (ptext SLIT("in an imported unfolding"))) -pp_binders :: [Id] -> SDoc +pp_binders :: [Var] -> SDoc pp_binders bs = sep (punctuate comma (map pp_binder bs)) -pp_binder :: Id -> SDoc -pp_binder b = hsep [ppr b, dcolon, ppr (idType b)] +pp_binder :: Var -> SDoc +pp_binder b | isId b = hsep [ppr b, dcolon, ppr (idType b)] + | isTyVar b = hsep [ppr b, dcolon, ppr (tyVarKind b)] \end{code} \begin{code} @@ -651,6 +712,7 @@ mkBadPatMsg con_result_ty scrut_ty ------------------------------------------------------ -- Other error messages +mkAppMsg :: Type -> Type -> Message mkAppMsg fun arg = vcat [ptext SLIT("Argument value doesn't match argument type:"), hang (ptext SLIT("Fun type:")) 4 (ppr fun), diff --git a/ghc/compiler/coreSyn/CoreUtils.lhs b/ghc/compiler/coreSyn/CoreUtils.lhs index 64ddad21e2c7cbdf1b2220ea6351ecb47deb6d43..5147bfd1e8fdca95056cc445456efb6f897c11b8 100644 --- a/ghc/compiler/coreSyn/CoreUtils.lhs +++ b/ghc/compiler/coreSyn/CoreUtils.lhs @@ -8,6 +8,7 @@ module CoreUtils ( -- Construction mkNote, mkInlineMe, mkSCC, mkCoerce, bindNonRec, mkIfThenElse, mkAltExpr, + mkPiType, -- Properties of expressions exprType, coreAltsType, exprArity, @@ -85,13 +86,7 @@ exprType (Case _ _ alts) = coreAltsType alts exprType (Note (Coerce ty _) e) = ty -- **! should take usage from e exprType (Note (TermUsg u) e) = mkUsgTy u (unUsgTy (exprType e)) exprType (Note other_note e) = exprType e -exprType (Lam binder expr) - | isId binder = (case idLBVarInfo binder of - IsOneShotLambda -> mkUsgTy UsOnce - otherwise -> id) $ - idType binder `mkFunTy` exprType expr - | isTyVar binder = mkForAllTy binder (exprType expr) - +exprType (Lam binder expr) = mkPiType binder (exprType expr) exprType e@(App _ _) = case collectArgs e of (fun, args) -> applyTypeToArgs e (exprType fun) args @@ -102,6 +97,20 @@ coreAltsType :: [CoreAlt] -> Type coreAltsType ((_,_,rhs) : _) = exprType rhs \end{code} +@mkPiType@ makes a (->) type or a forall type, depending on whether +it is given a type variable or a term variable. We cleverly use the +lbvarinfo field to figure out the right annotation for the arrove in +case of a term variable. + +\begin{code} +mkPiType :: Var -> Type -> Type -- The more polymorphic version doesn't work... +mkPiType v ty | isId v = (case idLBVarInfo v of + IsOneShotLambda -> mkUsgTy UsOnce + otherwise -> id) $ + mkFunTy (idType v) ty + | isTyVar v = mkForAllTy v ty +\end{code} + \begin{code} -- The first argument is just for debugging applyTypeToArgs :: CoreExpr -> Type -> [CoreExpr] -> Type diff --git a/ghc/compiler/specialise/Rules.lhs b/ghc/compiler/specialise/Rules.lhs index 6e7c6c233d57785070c499d07e4462eebe24c18a..7a70d519c5a4baa87a965b9c4843e1b3b85aa783 100644 --- a/ghc/compiler/specialise/Rules.lhs +++ b/ghc/compiler/specialise/Rules.lhs @@ -7,7 +7,7 @@ module Rules ( RuleBase, prepareLocalRuleBase, prepareOrphanRuleBase, unionRuleBase, lookupRule, addRule, addIdSpecialisations, - ProtoCoreRule(..), pprProtoCoreRule, + ProtoCoreRule(..), pprProtoCoreRule, pprRuleBase, localRule, orphanRule ) where @@ -494,6 +494,11 @@ unionRuleBase (rule_ids1, black_ids1) (rule_ids2, black_ids2) in setIdSpecialisation id1 new_rules +pprRuleBase :: RuleBase -> SDoc +pprRuleBase (rules,_) = vcat [ pprCoreRule (ppr id) rs + | id <- varSetElems rules, + rs <- rulesRules $ idSpecialisation id ] + -- prepareLocalRuleBase takes the CoreBinds and rules defined in this module. -- It attaches those rules that are for local Ids to their binders, and -- returns the remainder attached to Ids in an IdSet. It also returns diff --git a/ghc/compiler/types/Type.lhs b/ghc/compiler/types/Type.lhs index 877b115203c77629aaebeb4dc8ccd2d2598e40f0..a855e1d57538e4e9144a684039b40d0be87d83e9 100644 --- a/ghc/compiler/types/Type.lhs +++ b/ghc/compiler/types/Type.lhs @@ -44,7 +44,7 @@ module Type ( mkUsForAllTy, mkUsForAllTys, splitUsForAllTys, substUsTy, mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys, - applyTy, applyTys, mkPiType, hoistForAllTys, + applyTy, applyTys, hoistForAllTys, TauType, RhoType, SigmaType, PredType(..), ThetaType, ClassPred, ClassContext, mkClassPred, @@ -618,14 +618,7 @@ splitForAllTys ty = case splitUsgTy_maybe ty of split orig_ty t tvs = (reverse tvs, orig_ty) \end{code} -@mkPiType@ makes a (->) type or a forall type, depending on whether -it is given a type variable or a term variable. - -\begin{code} -mkPiType :: Var -> Type -> Type -- The more polymorphic version doesn't work... -mkPiType v ty | isId v = mkFunTy (idType v) ty - | otherwise = mkForAllTy v ty -\end{code} +-- (mkPiType now in CoreUtils) Applying a for-all to its arguments