diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2013-04-29 17:26:17 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2013-04-30 09:51:07 +0100 |
commit | d3149f6096a987e94d4989e537c1a133bcbb9a6f (patch) | |
tree | 49e1e9c87545b171417e131c5ba037fe0032097c | |
parent | 8a1b7eb6add9d873a93f8e12ccf507bfe0d1df7e (diff) | |
download | haskell-d3149f6096a987e94d4989e537c1a133bcbb9a6f.tar.gz |
Tighten up on the kind checking for foralls
In particular,
(forall a. Num a => ...)
always has kind *, becuase the "=>" really is a function.
It turned out that this was at the bottom of the crash in Trac #7778,
which is now fixed
-rw-r--r-- | compiler/typecheck/TcHsType.lhs | 31 | ||||
-rw-r--r-- | compiler/typecheck/TcValidity.lhs | 16 |
2 files changed, 33 insertions, 14 deletions
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs index 9ec0d36b02..d559f99e03 100644 --- a/compiler/typecheck/TcHsType.lhs +++ b/compiler/typecheck/TcHsType.lhs @@ -192,11 +192,22 @@ tcHsSigTypeNC ctxt (L loc hs_ty) ----------------- tcHsInstHead :: UserTypeCtxt -> LHsType Name -> TcM ([TyVar], ThetaType, Class, [Type]) -- Like tcHsSigTypeNC, but for an instance head. -tcHsInstHead ctxt lhs_ty@(L loc hs_ty) +tcHsInstHead user_ctxt lhs_ty@(L loc hs_ty) = setSrcSpan loc $ -- The "In the type..." context comes from the caller - do { ty <- tcCheckHsTypeAndGen hs_ty constraintKind - ; ty <- zonkTcType ty - ; checkValidInstance ctxt lhs_ty ty } + do { inst_ty <- tc_inst_head hs_ty + ; kvs <- kindGeneralize (tyVarsOfType inst_ty) [] + ; inst_ty <- zonkTcType (mkForAllTys kvs inst_ty) + ; checkValidInstance user_ctxt lhs_ty inst_ty } + +tc_inst_head :: HsType Name -> TcM TcType +tc_inst_head (HsForAllTy _ hs_tvs hs_ctxt hs_ty) + = tcHsTyVarBndrs hs_tvs $ \ tvs -> + do { ctxt <- tcHsContext hs_ctxt + ; ty <- tc_lhs_type hs_ty ekConstraint -- Body for forall has kind Constraint + ; return (mkSigmaTy tvs ctxt ty) } + +tc_inst_head hs_ty + = tc_hs_type hs_ty ekConstraint ----------------- tcHsDeriv :: HsType Name -> TcM ([TyVar], Class, [Type]) @@ -376,12 +387,18 @@ tc_hs_type hs_ty@(HsAppTy ty1 ty2) exp_kind (fun_ty, arg_tys) = splitHsAppTys ty1 [ty2] --------- Foralls -tc_hs_type (HsForAllTy _ hs_tvs context ty) exp_kind +tc_hs_type hs_ty@(HsForAllTy _ hs_tvs context ty) exp_kind = tcHsTyVarBndrs hs_tvs $ \ tvs' -> -- Do not kind-generalise here! See Note [Kind generalisation] do { ctxt' <- tcHsContext context - ; ty' <- tc_lhs_type ty exp_kind - -- Why exp_kind? See Note [Body kind of forall] + ; ty' <- if null (unLoc context) then -- Plain forall, no context + tc_lhs_type ty exp_kind -- Why exp_kind? See Note [Body kind of forall] + else + -- If there is a context, then this forall is really a + -- *function*, so the kind of the result really is * + -- The body kind (result of the function can be * or #, hence ekOpen + do { checkExpectedKind hs_ty liftedTypeKind exp_kind + ; tc_lhs_type ty ekOpen } ; return (mkSigmaTy tvs' ctxt' ty') } --------- Lists, arrays, and tuples diff --git a/compiler/typecheck/TcValidity.lhs b/compiler/typecheck/TcValidity.lhs index ee0d9ecaca..3a828da2eb 100644 --- a/compiler/typecheck/TcValidity.lhs +++ b/compiler/typecheck/TcValidity.lhs @@ -8,7 +8,7 @@ module TcValidity ( Rank, UserTypeCtxt(..), checkValidType, checkValidMonoType, expectedKindInCtxt, checkValidTheta, checkValidFamPats, - checkValidInstHead, checkValidInstance, validDerivPred, + checkValidInstance, validDerivPred, checkInstTermination, checkValidTyFamInst, checkTyFamFreeness, checkConsistentFamInst, arityErr, badATErr @@ -827,11 +827,9 @@ validDerivPred tv_set pred checkValidInstance :: UserTypeCtxt -> LHsType Name -> Type -> TcM ([TyVar], ThetaType, Class, [Type]) checkValidInstance ctxt hs_type ty - = do { let (tvs, theta, tau) = tcSplitSigmaTy ty - ; case getClassPredTys_maybe tau of { - Nothing -> failWithTc (ptext (sLit "Malformed instance type")) ; - Just (clas,inst_tys) -> - do { setSrcSpan head_loc (checkValidInstHead ctxt clas inst_tys) + | Just (clas,inst_tys) <- getClassPredTys_maybe tau + , inst_tys `lengthIs` classArity clas + = do { setSrcSpan head_loc (checkValidInstHead ctxt clas inst_tys) ; checkValidTheta ctxt theta -- The Termination and Coverate Conditions @@ -853,8 +851,12 @@ checkValidInstance ctxt hs_type ty ; checkTc (checkInstCoverage clas inst_tys) (instTypeErr clas inst_tys msg) } - ; return (tvs, theta, clas, inst_tys) } } } + ; return (tvs, theta, clas, inst_tys) } + + | otherwise + = failWithTc (ptext (sLit "Malformed instance head:") <+> ppr tau) where + (tvs, theta, tau) = tcSplitSigmaTy ty msg = parens (vcat [ptext (sLit "the Coverage Condition fails for one of the functional dependencies;"), undecidableMsg]) |