diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2018-11-15 23:29:34 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2018-11-26 09:56:14 +0000 |
commit | e49adfb7cfb2737c422af7b4ce76ab10eb4be0a1 (patch) | |
tree | 1fbd80b554239ac83560aa46f5d7a83d2ea3660d /compiler | |
parent | df8140dff1cbcb9826e42495479ad1817dff3525 (diff) | |
download | haskell-e49adfb7cfb2737c422af7b4ce76ab10eb4be0a1.tar.gz |
Better validity checks, simplification
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/typecheck/TcGenDeriv.hs | 3 | ||||
-rw-r--r-- | compiler/typecheck/TcHsType.hs | 66 | ||||
-rw-r--r-- | compiler/typecheck/TcInstDcls.hs | 43 | ||||
-rw-r--r-- | compiler/typecheck/TcTyClsDecls.hs | 223 | ||||
-rw-r--r-- | compiler/typecheck/TcValidity.hs | 239 |
5 files changed, 285 insertions, 289 deletions
diff --git a/compiler/typecheck/TcGenDeriv.hs b/compiler/typecheck/TcGenDeriv.hs index 7c632c8d80..16a4e1279d 100644 --- a/compiler/typecheck/TcGenDeriv.hs +++ b/compiler/typecheck/TcGenDeriv.hs @@ -1871,8 +1871,7 @@ gen_Newtype_binds loc cls inst_tvs inst_tys rhs_ty let axiom = mkSingleCoAxiom Nominal rep_tc_name rep_tvs' rep_cvs' fam_tc rep_lhs_tys rep_rhs_ty -- Check (c) from Note [GND and associated type families] in TcDeriv - checkValidCoAxBranch (Just (cls, cls_tvs, lhs_env)) fam_tc - (coAxiomSingleBranch axiom) + checkValidCoAxBranch fam_tc (coAxiomSingleBranch axiom) newFamInst SynFamilyInst axiom where cls_tvs = classTyVars cls diff --git a/compiler/typecheck/TcHsType.hs b/compiler/typecheck/TcHsType.hs index 5272fd46c8..6261b6a440 100644 --- a/compiler/typecheck/TcHsType.hs +++ b/compiler/typecheck/TcHsType.hs @@ -47,7 +47,7 @@ module TcHsType ( typeLevelMode, kindLevelMode, kindGeneralize, checkExpectedKindX, - instantiateTyN, instantiateTyUntilN, + instantiateTyN, reportFloatingKvs, -- Sort-checking kinds @@ -875,7 +875,7 @@ tcInferApps :: TcTyMode -> TcType -- ^ Function -> TcKind -- ^ Function kind (zonked) -> [LHsType GhcRn] -- ^ Args - -> TcM (TcType, [TcType], TcKind) -- ^ (f args, args, result kind) + -> TcM (TcType, TcKind) -- ^ (f args, args, result kind) -- Precondition: typeKind fun_ty = fun_ki -- Reason: we will return a type application like (fun_ty arg1 ... argn), -- and that type must be well-kinded @@ -883,39 +883,37 @@ tcInferApps :: TcTyMode -- Postcondition: Result kind is zonked. tcInferApps mode orig_hs_ty fun_ty fun_ki orig_hs_args = do { traceTc "tcInferApps {" (ppr orig_hs_ty $$ ppr orig_hs_args $$ ppr fun_ki) - ; (f_args, args, res_k) <- go 1 [] empty_subst fun_ty orig_ki_binders orig_inner_ki orig_hs_args + ; (f_args, res_k) <- go 1 empty_subst fun_ty orig_ki_binders orig_inner_ki orig_hs_args ; traceTc "tcInferApps }" empty - ; res_k <- zonkTcType res_k -- nec'y to uphold (IT4) of Note [The tcType invariant] - ; return (f_args, args, res_k) } + ; res_k <- zonkTcType res_k -- Uphold (IT4) of Note [The tcType invariant] + ; return (f_args, res_k) } where empty_subst = mkEmptyTCvSubst $ mkInScopeSet $ tyCoVarsOfType fun_ki (orig_ki_binders, orig_inner_ki) = tcSplitPiTys fun_ki go :: Int -- the # of the next argument - -> [TcType] -- already type-checked args, in reverse order -> TCvSubst -- instantiating substitution -> TcType -- function applied to some args -> [TyBinder] -- binders in function kind (both vis. and invis.) -> TcKind -- function kind body (not a Pi-type) -> [LHsType GhcRn] -- un-type-checked args - -> TcM (TcType, [TcType], TcKind) -- same as overall return type + -> TcM (TcType, TcKind) -- same as overall return type -- no user-written args left. We're done! - go _ acc_args subst fun ki_binders inner_ki [] + go _ subst fun ki_binders inner_ki [] = return ( fun - , reverse acc_args , nakedSubstTy subst $ mkPiTys ki_binders inner_ki) -- nakedSubstTy: see Note [The well-kinded type invariant] -- The function's kind has a binder. Is it visible or invisible? - go n acc_args subst fun (ki_binder:ki_binders) inner_ki + go n subst fun (ki_binder:ki_binders) inner_ki all_args@(arg:args) | isInvisibleBinder ki_binder -- It's invisible. Instantiate. = do { traceTc "tcInferApps (invis)" (ppr ki_binder $$ ppr subst) ; (subst', arg') <- tcInstTyBinder Nothing subst ki_binder - ; go n (arg' : acc_args) subst' (mkNakedAppTy fun arg') + ; go n subst' (mkNakedAppTy fun arg') ki_binders inner_ki all_args } | otherwise @@ -929,15 +927,15 @@ tcInferApps mode orig_hs_ty fun_ty fun_ki orig_hs_args tc_lhs_type mode arg exp_kind ; traceTc "tcInferApps (vis 1)" (ppr exp_kind) ; let subst' = extendTvSubstBinderAndInScope subst ki_binder arg' - ; go (n+1) (arg' : acc_args) subst' + ; go (n+1) subst' (mkNakedAppTy fun arg') -- See Note [The well-kinded type invariant] ki_binders inner_ki args } -- We've run out of known binders in the functions's kind. - go n acc_args subst fun [] inner_ki all_args + go n subst fun [] inner_ki all_args | not (null new_ki_binders) -- But, after substituting, we have more binders. - = go n acc_args zapped_subst fun new_ki_binders new_inner_ki all_args + = go n zapped_subst fun new_ki_binders new_inner_ki all_args | otherwise -- Even after substituting, still no binders. Use matchExpectedFunKind @@ -945,7 +943,7 @@ tcInferApps mode orig_hs_ty fun_ty fun_ki orig_hs_args ; (co, arg_k, res_k) <- matchExpectedFunKind hs_ty substed_inner_ki ; let new_in_scope = tyCoVarsOfTypes [arg_k, res_k] subst' = zapped_subst `extendTCvInScopeSet` new_in_scope - ; go n acc_args subst' + ; go n subst' (fun `mkNakedCastTy` co) -- See Note [The well-kinded type invariant] [mkAnonBinder arg_k] res_k all_args } @@ -968,7 +966,7 @@ tcTyApps :: TcTyMode -> TcM (TcType, TcKind) -- ^ (f args, result kind) result kind is zonked -- Precondition: see precondition for tcInferApps tcTyApps mode orig_hs_ty fun_ty fun_ki args - = do { (ty', _args, ki') <- tcInferApps mode orig_hs_ty fun_ty fun_ki args + = do { (ty', ki') <- tcInferApps mode orig_hs_ty fun_ty fun_ki args ; return (ty' `mkNakedCastTy` mkNomReflCo ki', ki') } -- The mkNakedCastTy is for (IT3) of Note [The tcType invariant] @@ -981,22 +979,20 @@ checkExpectedKind :: HasDebugCallStack -> TcKind -- the known kind of that type -> TcKind -- the expected kind -> TcM TcType -checkExpectedKind hs_ty ty act exp - = fstOf3 <$> checkExpectedKindX Nothing (ppr hs_ty) ty act exp +checkExpectedKind hs_ty ty act exp = checkExpectedKindX (ppr hs_ty) ty act exp checkExpectedKindX :: HasDebugCallStack - => Maybe (VarEnv Kind) -- Possibly, instantiations for kind vars - -> SDoc -- HsType whose kind we're checking + => SDoc -- HsType whose kind we're checking -> TcType -- the type whose kind we're checking -> TcKind -- the known kind of that type, k -> TcKind -- the expected kind, exp_kind - -> TcM (TcType, [TcType], TcCoercionN) + -> TcM TcType -- (the new args, the coercion) -- Instantiate a kind (if necessary) and then call unifyType -- (checkExpectedKind ty act_kind exp_kind) -- checks that the actual kind act_kind is compatible -- with the expected kind exp_kind -checkExpectedKindX mb_kind_env pp_hs_ty ty act_kind exp_kind +checkExpectedKindX pp_hs_ty ty act_kind exp_kind = do { -- We need to make sure that both kinds have the same number of implicit -- foralls out front. If the actual kind has more, instantiate accordingly. -- Otherwise, just pass the type & kind through: the errors are caught @@ -1004,7 +1000,7 @@ checkExpectedKindX mb_kind_env pp_hs_ty ty act_kind exp_kind let (exp_bndrs, _) = splitPiTysInvisible exp_kind (act_bndrs, act_inner_ki) = splitPiTysInvisible act_kind n_to_inst = length act_bndrs - length exp_bndrs - ; (new_args, act_kind') <- instantiateTyN mb_kind_env n_to_inst act_bndrs act_inner_ki + ; (new_args, act_kind') <- instantiateTyN n_to_inst act_bndrs act_inner_ki ; let origin = TypeEqOrigin { uo_actual = act_kind' , uo_expected = exp_kind @@ -1019,33 +1015,31 @@ checkExpectedKindX mb_kind_env pp_hs_ty ty act_kind exp_kind , text "exp_kind:" <+> ppr exp_kind ] ; if act_kind' `tcEqType` exp_kind - then return (ty', new_args, mkTcNomReflCo exp_kind) -- This is very common + then return ty' -- This is very common else do { co_k <- uType KindLevel origin act_kind' exp_kind ; traceTc "checkExpectedKind" (vcat [ ppr act_kind , ppr exp_kind , ppr co_k ]) ; let result_ty = ty' `mkNakedCastTy` co_k -- See Note [The tcType invariant] - ; return (result_ty, new_args, co_k) } } + ; return result_ty } } -- | Instantiate @n@ invisible arguments to a type. If @n <= 0@, no instantiation -- occurs. If @n@ is too big, then all available invisible arguments are instantiated. -- (In other words, this function is very forgiving about bad values of @n@.) -- Why zonk the result? So that tcTyVar can obey (IT6) of Note [The tcType invariant] instantiateTyN :: HasDebugCallStack - => Maybe (VarEnv Kind) -- ^ Predetermined instantiations - -- (for assoc. type patterns) - -> Int -- ^ @n@ + => Int -- ^ @n@ -> [TyBinder] -> TcKind -- ^ its kind (zonked) -> TcM ([TcType], TcKind) -- ^ The inst'ed type, new args, kind (zonked) -instantiateTyN mb_kind_env n bndrs inner_ki +instantiateTyN n bndrs inner_ki | n <= 0 -- It's fine for it to be < 0. E.g. = return ([], ki) -- Check that (Maybe :: forall {k}. k->*), -- and see the call to instantiateTyN in checkExpectedKind -- A user bug to be reported as such; it is not a compiler crash! | otherwise - = do { (subst, inst_args) <- tcInstTyBinders empty_subst mb_kind_env inst_bndrs + = do { (subst, inst_args) <- tcInstTyBinders empty_subst Nothing inst_bndrs ; let rebuilt_ki = mkPiTys leftover_bndrs inner_ki ; ki' <- zonkTcType (substTy subst rebuilt_ki) ; traceTc "instantiateTyN" (vcat [ ppr ki @@ -1060,16 +1054,6 @@ instantiateTyN mb_kind_env n bndrs inner_ki ki = mkPiTys bndrs inner_ki empty_subst = mkEmptyTCvSubst (mkInScopeSet (tyCoVarsOfType ki)) --- | Instantiate a type to have at most @n@ invisible arguments. -instantiateTyUntilN :: Maybe (VarEnv Kind) -- ^ Possibly, instantiations for vars - -> Int -- ^ @n@ - -> TcKind -- ^ its kind - -> TcM ([TcType], TcKind) -- ^ The new args, final kind -instantiateTyUntilN mb_kind_env n ki - = let (bndrs, inner_ki) = splitPiTysInvisible ki - num_to_inst = length bndrs - n - in - instantiateTyN mb_kind_env num_to_inst bndrs inner_ki --------------------------- tcHsMbContext :: Maybe (LHsContext GhcRn) -> TcM [PredType] @@ -1159,7 +1143,7 @@ tcTyVar mode name -- Could be a tyvar, a tycon, or a datacon | otherwise = do { tc_kind <- zonkTcType (tyConKind tc) ; let (tc_kind_bndrs, tc_inner_ki) = splitPiTysInvisible tc_kind - ; (tc_args, kind) <- instantiateTyN Nothing (length (tyConBinders tc)) + ; (tc_args, kind) <- instantiateTyN (length (tyConBinders tc)) tc_kind_bndrs tc_inner_ki ; let is_saturated = tc_args `lengthAtLeast` tyConArity tc tc_ty diff --git a/compiler/typecheck/TcInstDcls.hs b/compiler/typecheck/TcInstDcls.hs index b498c07c34..914114f508 100644 --- a/compiler/typecheck/TcInstDcls.hs +++ b/compiler/typecheck/TcInstDcls.hs @@ -547,20 +547,23 @@ lot of kinding and type checking code with ordinary algebraic data types (and GADTs). -} -tcFamInstDeclCombined :: Maybe ClsInstInfo +tcFamInstDeclChecks :: Maybe ClsInstInfo -> Located Name -> TcM TyCon -tcFamInstDeclCombined mb_clsinfo fam_tc_lname +tcFamInstDeclChecks mb_clsinfo fam_tc_lname = do { -- Type family instances require -XTypeFamilies -- and can't (currently) be in an hs-boot file ; traceTc "tcFamInstDecl" (ppr fam_tc_lname) ; type_families <- xoptM LangExt.TypeFamilies - ; is_boot <- tcIsHsBootOrSig -- Are we compiling an hs-boot file? + ; is_boot <- tcIsHsBootOrSig -- Are we compiling an hs-boot file? ; checkTc type_families $ badFamInstDecl fam_tc_lname ; checkTc (not is_boot) $ badBootFamInstDeclErr -- Look up the family TyCon and check for validity including -- check that toplevel type instances are not for associated types. ; fam_tc <- tcLookupLocatedTyCon fam_tc_lname + + ; checkTc (isFamilyTyCon fam_tc) (notFamily fam_tc) + ; when (isNothing mb_clsinfo && -- Not in a class decl isTyConAssoc fam_tc) -- but an associated type (addErr $ assocInClassErr fam_tc_lname) @@ -570,14 +573,14 @@ tcFamInstDeclCombined mb_clsinfo fam_tc_lname tcTyFamInstDecl :: Maybe ClsInstInfo -> LTyFamInstDecl GhcRn -> TcM FamInst -- "type instance" + -- See Note [Associated type instances] tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn })) = setSrcSpan loc $ tcAddTyFamInstCtxt decl $ do { let fam_lname = feqn_tycon (hsib_body eqn) - ; fam_tc <- tcFamInstDeclCombined mb_clsinfo fam_lname + ; fam_tc <- tcFamInstDeclChecks mb_clsinfo fam_lname -- (0) Check it's an open type family - ; checkTc (isFamilyTyCon fam_tc) (notFamily fam_tc) ; checkTc (isTypeFamilyTyCon fam_tc) (wrongKindOfFamily fam_tc) ; checkTc (isOpenTypeFamilyTyCon fam_tc) (notOpenFamily fam_tc) @@ -586,7 +589,7 @@ tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn })) (L (getLoc fam_lname) eqn) -- (2) check for validity - ; checkValidCoAxBranch mb_clsinfo fam_tc co_ax_branch + ; checkValidCoAxBranch fam_tc co_ax_branch -- (3) construct coercion axiom ; rep_tc_name <- newFamInstAxiomName fam_lname [coAxBranchLHS co_ax_branch] @@ -611,10 +614,9 @@ tcDataFamInstDecl mb_clsinfo , dd_derivs = derivs } }}})) = setSrcSpan loc $ tcAddDataFamInstCtxt decl $ - do { fam_tc <- tcFamInstDeclCombined mb_clsinfo lfam_name + do { fam_tc <- tcFamInstDeclChecks mb_clsinfo lfam_name -- Check that the family declaration is for the right kind - ; checkTc (isFamilyTyCon fam_tc) (notFamily fam_tc) ; checkTc (isDataFamilyTyCon fam_tc) (wrongKindOfFamily fam_tc) ; gadt_syntax <- dataDeclChecks fam_name new_or_data ctxt cons -- Do /not/ check that the number of patterns = tyConArity fam_tc @@ -636,7 +638,7 @@ tcDataFamInstDecl mb_clsinfo ; exp_res_kind <- case m_ksig of Nothing -> return liftedTypeKind Just hs_k -> tcLHsKindSig data_ctxt hs_k - ; _ <- checkExpectedKindX Nothing pp_hs_pats bogus_ty + ; _ <- checkExpectedKindX pp_hs_pats bogus_ty res_kind exp_res_kind -- ToDo: what about a non-triv result? @@ -676,6 +678,9 @@ tcDataFamInstDecl mb_clsinfo orig_res_ty = mkTyConApp fam_tc all_pats ty_binders = full_tcbs `chkAppend` extra_tcbs + -- Check that type patterns match the class instance head + ; checkConsistentFamInst mb_clsinfo fam_tc all_pats + ; traceTc "tcDataFamInstDecl" (ppr fam_tc $$ ppr pats $$ ppr imp_vars $$ ppr exp_bndrs $$ ppr cons) ; (rep_tc, axiom) <- fixM $ \ ~(rec_rep_tc, _) -> @@ -713,7 +718,7 @@ tcDataFamInstDecl mb_clsinfo -- Remember to check validity; no recursion to worry about here -- Check that left-hand sides are ok (mono-types, no type families, -- consistent instantiations, etc) - ; checkValidCoAxBranch mb_clsinfo fam_tc (coAxiomSingleBranch axiom) + ; checkValidCoAxBranch fam_tc (coAxiomSingleBranch axiom) -- Result kind must be '*' (otherwise, we have too few patterns) ; checkTc (tcIsLiftedTypeKind final_res_kind) $ @@ -761,6 +766,24 @@ tcDataFamInstDecl _ (L _ (DataFamInstDecl (HsIB _ (XFamEqn _)))) = panic "tcDataFamInstDecl" +{- Note [Associated type instances] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We allow this: + class C a where + type T x a + instance C Int where + type T (S y) Int = y + type T Z Int = Char + +Note that + a) The variable 'x' is not bound by the class decl + b) 'x' is instantiated to a non-type-variable in the instance + c) There are several type instance decls for T in the instance + +All this is fine. Of course, you can't give any *more* instances +for (T ty Int) elsewhere, because it's an *associated* type. +-} + {- ********************************************************************* * * Type-checking instance declarations, pass 2 diff --git a/compiler/typecheck/TcTyClsDecls.hs b/compiler/typecheck/TcTyClsDecls.hs index bea2882669..c7b1ede246 100644 --- a/compiler/typecheck/TcTyClsDecls.hs +++ b/compiler/typecheck/TcTyClsDecls.hs @@ -18,7 +18,8 @@ module TcTyClsDecls ( kcConDecl, tcConDecls, dataDeclChecks, checkValidTyCon, tcFamTyPats, tcTyFamInstEqn, tcAddTyFamInstCtxt, tcMkDataFamInstCtxt, tcAddDataFamInstCtxt, - wrongKindOfFamily, dataConCtxt + wrongKindOfFamily, + ClsInstInfo, checkConsistentFamInst ) where #include "HsVersions.h" @@ -1823,7 +1824,7 @@ tcFamTyPatsAndGen :: TyCon -> Maybe ClsInstInfo -> HsTyPats GhcRn -- Patterns -> LHsType GhcRn -- RHS type -> TcM ([TyVar], [TcType], TcType) -- (tyvars, pats, rhs) -tcFamTyPatsAndGen fam_tc mb_cls_info imp_vars exp_bndrs hs_pats rhs_hs_ty +tcFamTyPatsAndGen fam_tc mb_clsinfo imp_vars exp_bndrs hs_pats rhs_hs_ty = do { traceTc "tcTyFamInstEqn {" (vcat [ ppr fam_tc <+> ppr hs_pats ]) -- First, check the arity of visible arguments @@ -1838,10 +1839,13 @@ tcFamTyPatsAndGen fam_tc mb_cls_info imp_vars exp_bndrs hs_pats rhs_hs_ty solveEqualities $ bindImplicitTKBndrs_Q_Skol imp_vars $ bindExplicitTKBndrs_Q_Skol AnyKind exp_bndrs $ - do { (pats, res_kind) <- tcFamTyPats fam_tc mb_cls_info hs_pats + do { (pats, res_kind) <- tcFamTyPats fam_tc mb_clsinfo hs_pats ; rhs_ty <- tcCheckLHsType rhs_hs_ty res_kind ; return (pats, rhs_ty) } + -- Check that type patterns match the class instance head + ; checkConsistentFamInst mb_clsinfo fam_tc pats + ; let scoped_tvs = imp_tvs ++ exp_tvs ; dvs <- candidateQTyVarsOfTypes (pats ++ mkTyVarTys scoped_tvs) ; qtvs <- quantifyTyVars emptyVarSet dvs @@ -1868,13 +1872,20 @@ tcFamTyPats fam_tc mb_clsinfo hs_pats ; (subst, invis_pats) <- tcInstTyBinders emptyTCvSubst mb_kind_env invis_bndrs ; let fun_ty = mkTyConApp fam_tc invis_pats - ; (_, pats, res_kind) <- tcInferApps typeLevelMode lhs_fun fun_ty + ; (fam_app, res_kind) <- tcInferApps typeLevelMode lhs_fun fun_ty (substTy subst body_kind) hs_pats ; traceTc "End tcFamTyPats }" $ vcat [ ppr fam_tc <+> dcolon <+> ppr fun_kind , text "res_kind:" <+> ppr res_kind ] - ; return (invis_pats ++ pats, res_kind) } + + -- We expect fam_app to look like (F t1 .. tn) + -- tcInferApps is capable of returning ((F ty1 |> co) ty2), + -- but that can't happen here because we already checked the + -- arity of F matches the number of pattern + ; case splitTyConApp_maybe fam_app of + Just (_, pats) -> return (pats, res_kind) + Nothing -> pprPanic "tcFamTyPats" bad_lhs } where fam_name = tyConName fam_tc fam_arity = tyConArity fam_tc @@ -1883,6 +1894,8 @@ tcFamTyPats fam_tc mb_clsinfo hs_pats (invis_bndrs, body_kind) = splitPiTysInvisibleN fam_arity fun_kind mb_kind_env = thdOf3 <$> mb_clsinfo + bad_lhs = hang (text "Ill-typed LHS of family instance") + 2 (ppr fam_tc <+> sep (map ppr hs_pats)) {- Note [Constraints in patterns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3028,8 +3041,6 @@ checkValidClass cls cls_arity = length (tyConVisibleTyVars (classTyCon cls)) -- Ignore invisible variables cls_tv_set = mkVarSet tyvars - mini_env = zipVarEnv tyvars (mkTyVarTys tyvars) - mb_cls = Just (cls, tyvars, mini_env) check_op constrained_class_methods (sel_id, dm) = setSrcSpan (getSrcSpan sel_id) $ @@ -3081,7 +3092,8 @@ checkValidClass cls -- Check that any default declarations for associated types are valid ; whenIsJust m_dflt_rhs $ \ (rhs, loc) -> setSrcSpan loc $ - checkValidTyFamEqn mb_cls fam_tc fam_tvs (mkTyVarTys fam_tvs) rhs } + tcAddFamInstCtxt (text "default type instance") (getName fam_tc) $ + checkValidTyFamEqn fam_tc fam_tvs (mkTyVarTys fam_tvs) rhs } where fam_tvs = tyConTyVars fam_tc @@ -3173,8 +3185,199 @@ checkFamFlag tc_name err_msg = hang (text "Illegal family declaration for" <+> quotes (ppr tc_name)) 2 (text "Enable TypeFamilies to allow indexed type families") -{- Note [Class method constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Extra information about the parent instance declaration, needed +-- when type-checking associated types. The 'Class' is the enclosing +-- class, the [TyVar] are the type variable of the instance decl, +-- and and the @VarEnv Type@ maps class variables to their instance +-- types. +type ClsInstInfo = (Class, [TyVar], VarEnv Type) + +type AssocInstArgShape = (Maybe Type, Type) + -- AssocInstArgShape is used only for associated family instances + -- (mb_exp, actual) + -- mb_exp = Just ty => this arg corresponds to a class variable + -- = Nothing => it doesn't correspond to a class variable + -- e.g. class C b where + -- type F a b c + -- instance C [x] where + -- type F p [x] q + -- We get [AssocInstArgShape] = [ (Nothing, p) + -- , (Just [x], [x]) + -- , (Nothing, q)] + + +checkConsistentFamInst :: Maybe ClsInstInfo + -> TyCon -- ^ Family tycon + -> [Type] -- ^ Type patterns from instance + -> TcM () +-- See Note [Checking consistent instantiation] + +checkConsistentFamInst Nothing _ _ = return () +checkConsistentFamInst (Just (clas, inst_tvs, mini_env)) fam_tc at_tys + = do { -- Check that the associated type indeed comes from this class + -- See [Mismatched class methods and associated type families] + -- in TcInstDecls. + + checkTc (Just (classTyCon clas) == tyConAssoc_maybe fam_tc) + (badATErr (className clas) (tyConName fam_tc)) + + -- Check type args first (more comprehensible) + ; checkTc (all check_arg type_shapes) pp_wrong_at_arg + + -- And now kind args + ; checkTcM (all check_arg kind_shapes) + (tidy_env2, pp_wrong_at_arg $$ ppSuggestExplicitKinds) + + ; traceTc "checkConsistentFamInst" (vcat [ ppr inst_tvs + , ppr arg_shapes + , ppr mini_env ]) } + where + arg_shapes :: [AssocInstArgShape] + arg_shapes = [ (lookupVarEnv mini_env fam_tc_tv, at_ty) + | (fam_tc_tv, at_ty) <- tyConTyVars fam_tc `zip` at_tys ] + + kind_shapes, type_shapes :: [AssocInstArgShape] + (kind_shapes, type_shapes) = partitionInvisibles $ + arg_shapes `zip` tyConArgFlags fam_tc at_tys + + check_arg :: AssocInstArgShape -> Bool + check_arg (Just exp_ty, at_ty) = exp_ty `tcEqType` at_ty + check_arg (Nothing, _ ) = True -- Arg position does not correspond + -- to a class variable + + pp_wrong_at_arg + = vcat [ text "Type indexes must match class instance head" + , pp_exp_act ] + + pp_exp_act + = vcat [ text "Expected:" <+> ppr (mkTyConApp fam_tc expected_args) + , text " Actual:" <+> ppr (mkTyConApp fam_tc at_tys) + , sdocWithDynFlags $ \dflags -> + ppWhen (has_poly_args dflags) $ + vcat [ text "where the `<tv>' arguments are type variables," + , text "distinct from each other and from the instance variables" ] ] + + -- We need to tidy, since it's possible that expected_args will contain + -- inferred kind variables with names identical to those in at_tys. If we + -- don't, we'll end up with horrible messages like this one (#13972): + -- + -- Expected: T (a -> Either a b) + -- Actual: T (a -> Either a b) + (tidy_env1, _) = tidyOpenTypes emptyTidyEnv at_tys + (tidy_env2, expected_args) + = tidyOpenTypes tidy_env1 [ exp_ty `orElse` mk_tv at_ty + | (exp_ty, at_ty) <- arg_shapes ] + mk_tv at_ty = mkTyVarTy (mkTyVar tv_name (typeKind at_ty)) + tv_name = mkInternalName (mkAlphaTyVarUnique 1) (mkTyVarOcc "<tv>") noSrcSpan + + has_poly_args dflags = any (isNothing . fst) shapes + where + shapes | gopt Opt_PrintExplicitKinds dflags = arg_shapes + | otherwise = type_shapes + +badATErr :: Name -> Name -> SDoc +badATErr clas op + = hsep [text "Class", quotes (ppr clas), + text "does not have an associated type", quotes (ppr op)] + + +{- Note [Checking consistent instantiation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +See Trac #11450 for background discussion on this check. + + class C a b where + type T a x b + +With this class decl, if we have an instance decl + instance C ty1 ty2 where ... +then the type instance must look like + type T ty1 v ty2 = ... +with exactly 'ty1' for 'a', 'ty2' for 'b', and some type 'v' for 'x'. +For example: + + instance C [p] Int + type T [p] y Int = (p,y,y) + +Note that + +* We used to allow completely different bound variables in the + associated type instance; e.g. + instance C [p] Int + type T [q] y Int = ... + But from GHC 8.2 onwards, we don't. It's much simpler this way. + See Trac #11450. + +* When the class variable isn't used on the RHS of the type instance, + it's tempting to allow wildcards, thus + instance C [p] Int + type T [_] y Int = (y,y) + But it's awkward to do the test, and it doesn't work if the + variable is repeated: + instance C (p,p) Int + type T (_,_) y Int = (y,y) + Even though 'p' is not used on the RHS, we still need to use 'p' + on the LHS to establish the repeated pattern. So to keep it simple + we just require equality. + +* For variables in associated type families that are not bound by the class + itself, we do _not_ check if they are over-specific. In other words, + it's perfectly acceptable to have an instance like this: + + instance C [p] Int where + type T [p] (Maybe x) Int = x + + While the first and third arguments to T are required to be exactly [p] and + Int, respectively, since they are bound by C, the second argument is allowed + to be more specific than just a type variable. Furthermore, it is permissible + to define multiple equations for T that differ only in the non-class-bound + argument: + + instance C [p] Int where + type T [p] (Maybe x) Int = x + type T [p] (Either x y) Int = x -> y + + We once considered requiring that non-class-bound variables in associated + type family instances be instantiated with distinct type variables. However, + that requirement proved too restrictive in practice, as there were examples + of extremely simple associated type family instances that this check would + reject, and fixing them required tiresome boilerplate in the form of + auxiliary type families. For instance, you would have to define the above + example as: + + instance C [p] Int where + type T [p] x Int = CAux x + + type family CAux x where + CAux (Maybe x) = x + CAux (Either x y) = x -> y + + We decided that this restriction wasn't buying us much, so we opted not + to pursue that design (see also GHC Trac #13398). + +Implementation + * Form the mini-envt from the class type variables a,b + to the instance decl types [p],Int: [a->[p], b->Int] + + * Look at the tyvars a,x,b of the type family constructor T + (it shares tyvars with the class C) + + * Apply the mini-evnt to them, and check that the result is + consistent with the instance types [p] y Int. (where y can be any type, as + it is not scoped over the class type variables. + +We make all the instance type variables scope over the +type instances, of course, which picks up non-obvious kinds. Eg + class Foo (a :: k) where + type F a + instance Foo (b :: k -> k) where + type F b = Int +Here the instance is kind-indexed and really looks like + type F (k->k) (b::k->k) = Int +But if the 'b' didn't scope, we would make F's instance too +poly-kinded. + +Note [Class method constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Haskell 2010 is supposed to reject class C a where op :: Eq a => a -> a diff --git a/compiler/typecheck/TcValidity.hs b/compiler/typecheck/TcValidity.hs index 88107da4b2..d59c4da0f3 100644 --- a/compiler/typecheck/TcValidity.hs +++ b/compiler/typecheck/TcValidity.hs @@ -10,9 +10,9 @@ module TcValidity ( checkValidTheta, checkValidFamPats, checkValidInstance, checkValidInstHead, validDerivPred, checkTySynRhs, - ClsInstInfo, checkValidCoAxiom, checkValidCoAxBranch, + checkValidCoAxiom, checkValidCoAxBranch, checkValidTyFamEqn, - arityErr, badATErr, + arityErr, checkValidTelescope, allDistinctTyVars ) where @@ -50,8 +50,8 @@ import FamInst ( makeInjectivityErrors ) import Name import VarEnv import VarSet +import Var ( VarBndr(..) ) import Id ( idType, idName ) -import Var ( VarBndr(..), mkTyVar ) import FV import ErrUtils import DynFlags @@ -60,7 +60,6 @@ import ListSetOps import SrcLoc import Outputable import Bag ( emptyBag ) -import Unique ( mkAlphaTyVarUnique ) import qualified GHC.LanguageExtensions as LangExt import Control.Monad @@ -1621,118 +1620,6 @@ arbitrarily large type, depending on how 'a' is instantiated. So we require UndecidableInstances if we have a type family in the instance head. Trac #15172. -Note [Associated type instances] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We allow this: - class C a where - type T x a - instance C Int where - type T (S y) Int = y - type T Z Int = Char - -Note that - a) The variable 'x' is not bound by the class decl - b) 'x' is instantiated to a non-type-variable in the instance - c) There are several type instance decls for T in the instance - -All this is fine. Of course, you can't give any *more* instances -for (T ty Int) elsewhere, because it's an *associated* type. - -Note [Checking consistent instantiation] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See Trac #11450 for background discussion on this check. - - class C a b where - type T a x b - -With this class decl, if we have an instance decl - instance C ty1 ty2 where ... -then the type instance must look like - type T ty1 v ty2 = ... -with exactly 'ty1' for 'a', 'ty2' for 'b', and some type 'v' for 'x'. -For example: - - instance C [p] Int - type T [p] y Int = (p,y,y) - -Note that - -* We used to allow completely different bound variables in the - associated type instance; e.g. - instance C [p] Int - type T [q] y Int = ... - But from GHC 8.2 onwards, we don't. It's much simpler this way. - See Trac #11450. - -* When the class variable isn't used on the RHS of the type instance, - it's tempting to allow wildcards, thus - instance C [p] Int - type T [_] y Int = (y,y) - But it's awkward to do the test, and it doesn't work if the - variable is repeated: - instance C (p,p) Int - type T (_,_) y Int = (y,y) - Even though 'p' is not used on the RHS, we still need to use 'p' - on the LHS to establish the repeated pattern. So to keep it simple - we just require equality. - -* For variables in associated type families that are not bound by the class - itself, we do _not_ check if they are over-specific. In other words, - it's perfectly acceptable to have an instance like this: - - instance C [p] Int where - type T [p] (Maybe x) Int = x - - While the first and third arguments to T are required to be exactly [p] and - Int, respectively, since they are bound by C, the second argument is allowed - to be more specific than just a type variable. Furthermore, it is permissible - to define multiple equations for T that differ only in the non-class-bound - argument: - - instance C [p] Int where - type T [p] (Maybe x) Int = x - type T [p] (Either x y) Int = x -> y - - We once considered requiring that non-class-bound variables in associated - type family instances be instantiated with distinct type variables. However, - that requirement proved too restrictive in practice, as there were examples - of extremely simple associated type family instances that this check would - reject, and fixing them required tiresome boilerplate in the form of - auxiliary type families. For instance, you would have to define the above - example as: - - instance C [p] Int where - type T [p] x Int = CAux x - - type family CAux x where - CAux (Maybe x) = x - CAux (Either x y) = x -> y - - We decided that this restriction wasn't buying us much, so we opted not - to pursue that design (see also GHC Trac #13398). - -Implementation - * Form the mini-envt from the class type variables a,b - to the instance decl types [p],Int: [a->[p], b->Int] - - * Look at the tyvars a,x,b of the type family constructor T - (it shares tyvars with the class C) - - * Apply the mini-evnt to them, and check that the result is - consistent with the instance types [p] y Int. (where y can be any type, as - it is not scoped over the class type variables. - -We make all the instance type variables scope over the -type instances, of course, which picks up non-obvious kinds. Eg - class Foo (a :: k) where - type F a - instance Foo (b :: k -> k) where - type F b = Int -Here the instance is kind-indexed and really looks like - type F (k->k) (b::k->k) = Int -But if the 'b' didn't scope, we would make F's instance too -poly-kinded. - Note [Invisible arguments and termination] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When checking the ​Paterson conditions for termination an instance @@ -1748,101 +1635,6 @@ described in Trac #15177, which contains a number of examples. The suspicious bits are the calls to filterOutInvisibleTypes. -} --- | Extra information about the parent instance declaration, needed --- when type-checking associated types. The 'Class' is the enclosing --- class, the [TyVar] are the type variable of the instance decl, --- and and the @VarEnv Type@ maps class variables to their instance --- types. -type ClsInstInfo = (Class, [TyVar], VarEnv Type) - -type AssocInstArgShape = (Maybe Type, Type) - -- AssocInstArgShape is used only for associated family instances - -- (mb_exp, actual) - -- mb_exp = Just ty => this arg corresponds to a class variable - -- = Nothing => it doesn't correspond to a class variable - -- e.g. class C b where - -- type F a b c - -- instance C [x] where - -- type F p [x] q - -- We get [AssocInstArgShape] = [ (Nothing, p) - -- , (Just [x], [x]) - -- , (Nothing, q)] - -checkConsistentFamInst - :: Maybe ClsInstInfo - -> TyCon -- ^ Family tycon - -> [Type] -- ^ Type patterns from instance - -> TcM () --- See Note [Checking consistent instantiation] - -checkConsistentFamInst Nothing _ _ = return () -checkConsistentFamInst (Just (clas, inst_tvs, mini_env)) fam_tc at_tys - = do { -- Check that the associated type indeed comes from this class - -- See [Mismatched class methods and associated type families] - -- in TcInstDecls. - - checkTc (Just (classTyCon clas) == tyConAssoc_maybe fam_tc) - (badATErr (className clas) (tyConName fam_tc)) - - -- Check type args first (more comprehensible) - ; checkTc (all check_arg type_shapes) pp_wrong_at_arg - - -- And now kind args - ; checkTcM (all check_arg kind_shapes) - (tidy_env2, pprWithExplicitKindsWhen True pp_wrong_at_arg) - - ; traceTc "checkConsistentFamInst" (vcat [ ppr inst_tvs - , ppr arg_shapes - , ppr mini_env ]) } - where - arg_shapes :: [AssocInstArgShape] - arg_shapes = [ (lookupVarEnv mini_env fam_tc_tv, at_ty) - | (fam_tc_tv, at_ty) <- tyConTyVars fam_tc `zip` at_tys ] - - kind_shapes, type_shapes :: [AssocInstArgShape] - (kind_shapes, type_shapes) = partitionInvisibles $ - arg_shapes `zip` tyConArgFlags fam_tc at_tys - - check_arg :: AssocInstArgShape -> Bool - check_arg (Just exp_ty, at_ty) = exp_ty `tcEqType` at_ty - check_arg (Nothing, _ ) = True -- Arg position does not correspond - -- to a class variable - - pp_wrong_at_arg - = vcat [ text "Type indexes must match class instance head" - , pp_exp_act ] - - pp_exp_act - = vcat [ text "Expected:" <+> ppr (mkTyConApp fam_tc expected_args) - , text " Actual:" <+> ppr (mkTyConApp fam_tc at_tys) - , sdocWithDynFlags $ \dflags -> - ppWhen (has_poly_args dflags) $ - vcat [ text "where the `<tv>' arguments are type variables," - , text "distinct from each other and from the instance variables" ] ] - - -- We need to tidy, since it's possible that expected_args will contain - -- inferred kind variables with names identical to those in at_tys. If we - -- don't, we'll end up with horrible messages like this one (#13972): - -- - -- Expected: T (a -> Either a b) - -- Actual: T (a -> Either a b) - (tidy_env1, _) = tidyOpenTypes emptyTidyEnv at_tys - (tidy_env2, expected_args) - = tidyOpenTypes tidy_env1 [ exp_ty `orElse` mk_tv at_ty - | (exp_ty, at_ty) <- arg_shapes ] - mk_tv at_ty = mkTyVarTy (mkTyVar tv_name (typeKind at_ty)) - tv_name = mkInternalName (mkAlphaTyVarUnique 1) (mkTyVarOcc "<tv>") noSrcSpan - - has_poly_args dflags = any (isNothing . fst) shapes - where - shapes | gopt Opt_PrintExplicitKinds dflags = arg_shapes - | otherwise = type_shapes - -badATErr :: Name -> Name -> SDoc -badATErr clas op - = hsep [text "Class", quotes (ppr clas), - text "does not have an associated type", quotes (ppr op)] - {- ************************************************************************ @@ -1854,7 +1646,7 @@ badATErr clas op checkValidCoAxiom :: CoAxiom Branched -> TcM () checkValidCoAxiom ax@(CoAxiom { co_ax_tc = fam_tc, co_ax_branches = branches }) - = do { mapM_ (checkValidCoAxBranch Nothing fam_tc) branch_list + = do { mapM_ (checkValidCoAxBranch fam_tc) branch_list ; foldlM_ check_branch_compat [] branch_list } where branch_list = fromBranches branches @@ -1907,26 +1699,24 @@ checkValidCoAxiom ax@(CoAxiom { co_ax_tc = fam_tc, co_ax_branches = branches }) -- Check that a "type instance" is well-formed (which includes decidability -- unless -XUndecidableInstances is given). -- -checkValidCoAxBranch :: Maybe ClsInstInfo - -> TyCon -> CoAxBranch -> TcM () -checkValidCoAxBranch mb_clsinfo fam_tc +checkValidCoAxBranch :: TyCon -> CoAxBranch -> TcM () +checkValidCoAxBranch fam_tc (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs , cab_lhs = typats , cab_rhs = rhs, cab_loc = loc }) = setSrcSpan loc $ - checkValidTyFamEqn mb_clsinfo fam_tc (tvs++cvs) typats rhs + checkValidTyFamEqn fam_tc (tvs++cvs) typats rhs -- | Do validity checks on a type family equation, including consistency -- with any enclosing class instance head, termination, and lack of -- polytypes. -checkValidTyFamEqn :: Maybe ClsInstInfo - -> TyCon -- ^ of the type family +checkValidTyFamEqn :: TyCon -- ^ of the type family -> [Var] -- ^ Bound variables in the equation -> [Type] -- ^ Type patterns -> Type -- ^ Rhs -> TcM () -checkValidTyFamEqn mb_clsinfo fam_tc qvs typats rhs - = do { checkValidFamPats mb_clsinfo fam_tc qvs typats rhs +checkValidTyFamEqn fam_tc qvs typats rhs + = do { checkValidFamPats fam_tc qvs typats rhs -- The argument patterns, and RHS, are all boxed tau types -- E.g Reject type family F (a :: k1) :: k2 @@ -1971,23 +1761,20 @@ checkFamInstRhs lhs_tc lhs_tys famInsts -- [a,b,a,a] \\ [a,a] = [b,a] -- So we are counting repetitions -checkValidFamPats :: Maybe ClsInstInfo - -> TyCon -> [Var] +checkValidFamPats :: TyCon -> [Var] -> [Type] -- ^ patterns -> Type -- ^ RHS -> TcM () -- Patterns in a 'type instance' or 'data instance' decl should --- a) contain no type family applications +-- a) Shoule contain no type family applications -- (vanilla synonyms are fine, though) -- b) For associated types, are consistently instantiated -checkValidFamPats mb_clsinfo fam_tc qvs pats rhs +checkValidFamPats fam_tc qvs pats rhs = do { checkValidTypePats fam_tc pats -- Check for things used on the right but not bound on the left ; checkFamPatBinders fam_tc qvs pats rhs - -- Check that type patterns match the class instance head - ; checkConsistentFamInst mb_clsinfo fam_tc pats ; traceTc "checkValidFamPats" (ppr fam_tc <+> ppr pats) } |