diff --git a/compiler/GHC/Core/Class.hs b/compiler/GHC/Core/Class.hs index 3c3f0a1db62f85b48dad852a46c50381e82ded6b..ffadf0e4b9f94948216c130109042f83dfc5ec45 100644 --- a/compiler/GHC/Core/Class.hs +++ b/compiler/GHC/Core/Class.hs @@ -8,7 +8,7 @@ module GHC.Core.Class ( Class, ClassOpItem, - ClassATItem(..), ATValidityInfo(..), + ClassATItem(..), TyFamEqnValidityInfo(..), ClassMinimalDef, DefMethInfo, pprDefMethInfo, @@ -33,6 +33,7 @@ import GHC.Types.Unique import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Types.SrcLoc +import GHC.Types.Var.Set import GHC.Utils.Outputable import GHC.Data.BooleanFormula (BooleanFormula, mkTrue) @@ -95,29 +96,42 @@ type DefMethInfo = Maybe (Name, DefMethSpec Type) data ClassATItem = ATI TyCon -- See Note [Associated type tyvar names] - (Maybe (Type, ATValidityInfo)) - -- Default associated type (if any) from this template - -- Note [Associated type defaults] - --- | Information about an associated type family default implementation. This --- is used solely for validity checking. + (Maybe (Type, TyFamEqnValidityInfo)) + -- ^ Default associated type (if any) from this template. + -- + -- As per Note [Associated type defaults], the Type has been renamed + -- to use the class tyvars, while the 'TyFamEqnValidityInfo' uses + -- the original user-written type variables. + +-- | Information about a type family equation, used for validity checking +-- of closed type family equations and associated type family default equations. +-- +-- This type exists to delay validity-checking after typechecking type declaration +-- groups, to avoid cyclic evaluation inside the typechecking knot. +-- -- See @Note [Type-checking default assoc decls]@ in "GHC.Tc.TyCl". -data ATValidityInfo - -- | Used for associated type families that are imported - -- from another module, for which we don't need to - -- perform any validity checking. - = NoATVI - - -- | Used for locally-defined associated type families. - | ATVI - { atvi_loc :: SrcSpan - , atvi_qtvs :: [TyVar] +data TyFamEqnValidityInfo + -- | Used for equations which don't need any validity checking, + -- for example equations imported from another module. + = NoVI + + -- | Information necessary for validity checking of a type family equation. + | VI + { vi_loc :: SrcSpan + , vi_qtvs :: [TcTyVar] -- ^ LHS quantified type variables - , atvi_pats :: [Type] + , vi_non_user_tvs :: TyVarSet + -- ^ non-user-written type variables (for error message reporting) + -- + -- Example: with -XPolyKinds, typechecking @type instance forall a. F = ()@ + -- introduces the kind variable @k@ for the kind of @a@. See #23734. + , vi_pats :: [Type] -- ^ LHS patterns - , atvi_rhs :: Type - -- ^ original RHS of the type family default declaration, - -- before applying the substitution from + , vi_rhs :: Type + -- ^ RHS of the equation + -- + -- NB: for associated type family default declarations, this is the RHS + -- *before* applying the substitution from -- Note [Type-checking default assoc decls] in GHC.Tc.TyCl. } @@ -176,9 +190,14 @@ Note that * HOWEVER, in the internal ClassATItem we rename the RHS to match the tyConTyVars of the family TyCon. So in the example above we'd get a ClassATItem of - ATI F ((x,a) -> b) - So the tyConTyVars of the family TyCon bind the free vars of - the default Type rhs + + ATI F (Just ((x,a) -> b, validity_info) + + That is, the type stored in the first component of the pair has been + renamed to use the class type variables. On the other hand, the + TyFamEqnValidityInfo, used for validity checking of the type family equation + (considered as a free-standing equation) uses the original types, e.g. + involving the type variables 'p', 'q', 'r'. The @mkClass@ function fills in the indirect superclasses. diff --git a/compiler/GHC/Core/Coercion/Axiom.hs b/compiler/GHC/Core/Coercion/Axiom.hs index c06af227ab7928376efafc8c07239b6a1b0b2a5e..bc2abf11b0ad29de23a456c746eb9508b2877492 100644 --- a/compiler/GHC/Core/Coercion/Axiom.hs +++ b/compiler/GHC/Core/Coercion/Axiom.hs @@ -235,25 +235,35 @@ data CoAxiom br -- INVARIANT: co_ax_implicit == True implies length co_ax_branches == 1. } +-- | A branch of a coercion axiom, which provides the evidence for +-- unwrapping a newtype or a type-family reduction step using a single equation. data CoAxBranch = CoAxBranch - { cab_loc :: SrcSpan -- Location of the defining equation - -- See Note [CoAxiom locations] - , cab_tvs :: [TyVar] -- Bound type variables; not necessarily fresh - -- See Note [CoAxBranch type variables] - , cab_eta_tvs :: [TyVar] -- Eta-reduced tyvars - -- cab_tvs and cab_lhs may be eta-reduced; see - -- Note [Eta reduction for data families] - , cab_cvs :: [CoVar] -- Bound coercion variables - -- Always empty, for now. - -- See Note [Constraints in patterns] - -- in GHC.Tc.TyCl - , cab_roles :: [Role] -- See Note [CoAxBranch roles] - , cab_lhs :: [Type] -- Type patterns to match against - , cab_rhs :: Type -- Right-hand side of the equality - -- See Note [CoAxioms are homogeneous] - , cab_incomps :: [CoAxBranch] -- The previous incompatible branches - -- See Note [Storing compatibility] + { cab_loc :: SrcSpan + -- ^ Location of the defining equation + -- See Note [CoAxiom locations] + , cab_tvs :: [TyVar] + -- ^ Bound type variables; not necessarily fresh + -- See Note [CoAxBranch type variables] + , cab_eta_tvs :: [TyVar] + -- ^ Eta-reduced tyvars + -- cab_tvs and cab_lhs may be eta-reduced; see + -- Note [Eta reduction for data families] + , cab_cvs :: [CoVar] + -- ^ Bound coercion variables + -- Always empty, for now. + -- See Note [Constraints in patterns] + -- in GHC.Tc.TyCl + , cab_roles :: [Role] + -- ^ See Note [CoAxBranch roles] + , cab_lhs :: [Type] + -- ^ Type patterns to match against + , cab_rhs :: Type + -- ^ Right-hand side of the equality + -- See Note [CoAxioms are homogeneous] + , cab_incomps :: [CoAxBranch] + -- ^ The previous incompatible branches + -- See Note [Storing compatibility] } deriving Data.Data diff --git a/compiler/GHC/IfaceToCore.hs b/compiler/GHC/IfaceToCore.hs index a678d5995023a4acbaf74dfeed12714dc625fd65..c51849029ca0fd498433b9b62586752da6c399ce 100644 --- a/compiler/GHC/IfaceToCore.hs +++ b/compiler/GHC/IfaceToCore.hs @@ -825,7 +825,7 @@ tc_iface_decl _parent ignore_prags Just def -> forkM (mk_at_doc tc) $ extendIfaceTyVarEnv (tyConTyVars tc) $ do { tc_def <- tcIfaceType def - ; return (Just (tc_def, NoATVI)) } + ; return (Just (tc_def, NoVI)) } -- Must be done lazily in case the RHS of the defaults mention -- the type constructor being defined here -- e.g. type AT a; type AT b = AT [b] #8002 diff --git a/compiler/GHC/Tc/Deriv/Generate.hs b/compiler/GHC/Tc/Deriv/Generate.hs index 5e6ab56609d61d2023a4205b86533035e602ab16..8b6d08cf2f795f51681f75699cd841df1420ebbb 100644 --- a/compiler/GHC/Tc/Deriv/Generate.hs +++ b/compiler/GHC/Tc/Deriv/Generate.hs @@ -52,7 +52,7 @@ import GHC.Tc.Utils.Instantiate( newFamInst ) import GHC.Tc.Utils.Env import GHC.Tc.Utils.TcType import GHC.Tc.Zonk.Type -import GHC.Tc.Validity ( checkValidCoAxBranch ) +import GHC.Tc.Validity import GHC.Core.DataCon import GHC.Core.FamInstEnv @@ -71,6 +71,7 @@ import GHC.Types.SrcLoc import GHC.Types.Unique.FM ( lookupUFM, listToUFM ) import GHC.Types.Var.Env import GHC.Types.Var +import GHC.Types.Var.Set import GHC.Builtin.Names import GHC.Builtin.Names.TH @@ -2084,6 +2085,7 @@ gen_Newtype_fam_insts loc' cls inst_tvs inst_tys rhs_ty rep_lhs_tys let axiom = mkSingleCoAxiom Nominal rep_tc_name rep_tvs' [] rep_cvs' fam_tc rep_lhs_tys rep_rhs_ty + checkFamPatBinders fam_tc (rep_tvs' ++ rep_cvs') emptyVarSet rep_lhs_tys rep_rhs_ty -- Check (c) from Note [GND and associated type families] in GHC.Tc.Deriv checkValidCoAxBranch fam_tc (coAxiomSingleBranch axiom) newFamInst SynFamilyInst axiom diff --git a/compiler/GHC/Tc/TyCl.hs b/compiler/GHC/Tc/TyCl.hs index 54bda892820886ed01e1d21155b4f16f0849e123..554d0acde4ec4c8d6d6351aefa76b6985d79a461 100644 --- a/compiler/GHC/Tc/TyCl.hs +++ b/compiler/GHC/Tc/TyCl.hs @@ -110,6 +110,7 @@ import Data.Functor.Identity import Data.List ( partition) import Data.List.NonEmpty ( NonEmpty(..) ) import qualified Data.List.NonEmpty as NE +import Data.Traversable ( for ) import Data.Tuple( swap ) {- @@ -195,12 +196,13 @@ tcTyClGroup (TyClGroup { group_tyclds = tyclds -- Step 1: Typecheck the standalone kind signatures and type/class declarations ; traceTc "---- tcTyClGroup ---- {" empty ; traceTc "Decls for" (ppr (map (tcdName . unLoc) tyclds)) - ; (tyclss, data_deriv_info, kindless) <- + ; (tyclss_with_validity_infos, data_deriv_info, kindless) <- tcExtendKindEnv (mkPromotionErrorEnv tyclds) $ -- See Note [Type environment evolution] do { kisig_env <- mkNameEnv <$> traverse tcStandaloneKindSig kisigs ; tcTyClDecls tyclds kisig_env role_annots } - + ; let tyclss = map fst tyclss_with_validity_infos -- Step 1.5: Make sure we don't have any type synonym cycles + ; traceTc "Starting synonym cycle check" (ppr tyclss) ; home_unit <- hsc_home_unit <$> getTopEnv ; checkSynCycles (homeUnitAsUnit home_unit) tyclss tyclds @@ -215,7 +217,11 @@ tcTyClGroup (TyClGroup { group_tyclds = tyclds -- NB: put the TyCons in the environment for validity checking, -- as we might look them up in checkTyConConsistentWithBoot. -- See Note [TyCon boot consistency checking]. - concatMapM checkValidTyCl tyclss + fmap concat . for tyclss_with_validity_infos $ \ (tycls, ax_validity_infos) -> + do { tcAddFamInstCtxt (text "type family") (tyConName tycls) $ + tcAddClosedTypeFamilyDeclCtxt tycls $ + mapM_ (checkTyFamEqnValidityInfo tycls) ax_validity_infos + ; checkValidTyCl tycls } ; traceTc "Done validity check" (ppr tyclss) ; mapM_ (recoverM (return ()) . checkValidRoleAnnots role_annots) tyclss @@ -246,7 +252,7 @@ tcTyClDecls :: [LTyClDecl GhcRn] -> KindSigEnv -> RoleAnnotEnv - -> TcM ([TyCon], [DerivInfo], NameSet) + -> TcM ([(TyCon, [TyFamEqnValidityInfo])], [DerivInfo], NameSet) tcTyClDecls tyclds kisig_env role_annots = do { -- Step 1: kind-check this group and returns the final -- (possibly-polymorphic) kind of each TyCon and Class @@ -266,10 +272,11 @@ tcTyClDecls tyclds kisig_env role_annots -- NB: We have to be careful here to NOT eagerly unfold -- type synonyms, as we have not tested for type synonym -- loops yet and could fall into a black hole. - ; fixM $ \ ~(rec_tyclss, _, _) -> do + ; fixM $ \ ~(rec_tyclss_with_validity_infos, _, _) -> do { tcg_env <- getGblEnv -- Forced so we don't retain a reference to the TcGblEnv ; let !src = tcg_src tcg_env + rec_tyclss = map fst rec_tyclss_with_validity_infos roles = inferRoles src role_annots rec_tyclss -- Populate environment with knot-tied ATyCon for TyCons @@ -2522,23 +2529,26 @@ The IRs are already well-equipped to handle unlifted types, and unlifted datatypes are just a new sub-class thereof. -} -tcTyClDecl :: RolesInfo -> LTyClDecl GhcRn -> TcM (TyCon, [DerivInfo]) +tcTyClDecl :: RolesInfo -> LTyClDecl GhcRn -> TcM ((TyCon, [TyFamEqnValidityInfo]), [DerivInfo]) tcTyClDecl roles_info (L loc decl) | Just thing <- wiredInNameTyThing_maybe (tcdName decl) = case thing of -- See Note [Declarations for wired-in things] - ATyCon tc -> return (tc, wiredInDerivInfo tc decl) + ATyCon tc -> return ((tc, []), wiredInDerivInfo tc decl) _ -> pprPanic "tcTyClDecl" (ppr thing) | otherwise = setSrcSpanA loc $ tcAddDeclCtxt decl $ do { traceTc "---- tcTyClDecl ---- {" (ppr decl) - ; (tc, deriv_infos) <- tcTyClDecl1 Nothing roles_info decl + ; (tc_vi@(tc, _), deriv_infos) <- tcTyClDecl1 Nothing roles_info decl ; traceTc "---- tcTyClDecl end ---- }" (ppr tc) - ; return (tc, deriv_infos) } + ; return (tc_vi, deriv_infos) } noDerivInfos :: a -> (a, [DerivInfo]) noDerivInfos a = (a, []) +noEqnValidityInfos :: a -> (a, [TyFamEqnValidityInfo]) +noEqnValidityInfos a = (a, []) + wiredInDerivInfo :: TyCon -> TyClDecl GhcRn -> [DerivInfo] wiredInDerivInfo tycon decl | DataDecl { tcdDataDefn = dataDefn } <- decl @@ -2553,7 +2563,7 @@ wiredInDerivInfo tycon decl wiredInDerivInfo _ _ = [] -- "type family" declarations -tcTyClDecl1 :: Maybe Class -> RolesInfo -> TyClDecl GhcRn -> TcM (TyCon, [DerivInfo]) +tcTyClDecl1 :: Maybe Class -> RolesInfo -> TyClDecl GhcRn -> TcM ((TyCon, [TyFamEqnValidityInfo]), [DerivInfo]) tcTyClDecl1 parent _roles_info (FamDecl { tcdFam = fd }) = fmap noDerivInfos $ tcFamDecl1 parent fd @@ -2563,7 +2573,7 @@ tcTyClDecl1 _parent roles_info (SynDecl { tcdLName = L _ tc_name , tcdRhs = rhs }) = assert (isNothing _parent ) - fmap noDerivInfos $ + fmap ( noDerivInfos . noEqnValidityInfos ) $ tcTySynRhs roles_info tc_name rhs -- "data/newtype" declaration @@ -2571,6 +2581,7 @@ tcTyClDecl1 _parent roles_info decl@(DataDecl { tcdLName = L _ tc_name , tcdDataDefn = defn }) = assert (isNothing _parent) $ + fmap (\(tc, deriv_info) -> ((tc, []), deriv_info)) $ tcDataDefn (tcMkDeclCtxt decl) roles_info tc_name defn tcTyClDecl1 _parent roles_info @@ -2584,7 +2595,7 @@ tcTyClDecl1 _parent roles_info = assert (isNothing _parent) $ do { clas <- tcClassDecl1 roles_info class_name hs_ctxt meths fundeps sigs ats at_defs - ; return (noDerivInfos (classTyCon clas)) } + ; return (noDerivInfos $ noEqnValidityInfos (classTyCon clas)) } {- ********************************************************************* @@ -2672,13 +2683,13 @@ tcClassDecl1 roles_info class_name hs_ctxt meths fundeps sigs ats at_defs {- Note [Associated type defaults] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - The following is an example of associated type defaults: - class C a where - data D a - type F a b :: * - type F a b = [a] -- Default + class C a where + data D a + + type F a b :: * + type F a b = [a] -- Default Note that we can get default definitions only for type families, not data families. @@ -2713,7 +2724,8 @@ tcClassATs class_name cls ats at_defs (at_def_tycon at_def) [at_def]) emptyNameEnv at_defs - tc_at at = do { fam_tc <- addLocMA (tcFamDecl1 (Just cls)) at + tc_at at = do { (fam_tc, val_infos) <- addLocMA (tcFamDecl1 (Just cls)) at + ; mapM_ (checkTyFamEqnValidityInfo fam_tc) val_infos ; let at_defs = lookupNameEnv at_defs_map (at_fam_name at) `orElse` [] ; atd <- tcDefaultAssocDecl fam_tc at_defs @@ -2721,9 +2733,9 @@ tcClassATs class_name cls ats at_defs ------------------------- tcDefaultAssocDecl :: - TyCon -- ^ Family TyCon (not knot-tied) - -> [LTyFamDefltDecl GhcRn] -- ^ Defaults - -> TcM (Maybe (KnotTied Type, ATValidityInfo)) -- ^ Type checked RHS + TyCon -- ^ Family TyCon (not knot-tied) + -> [LTyFamDefltDecl GhcRn] -- ^ Defaults + -> TcM (Maybe (KnotTied Type, TyFamEqnValidityInfo)) -- ^ Type checked RHS tcDefaultAssocDecl _ [] = return Nothing -- No default declaration @@ -2763,8 +2775,9 @@ tcDefaultAssocDecl fam_tc -- at an associated type. But this would be wrong, because an associated -- type default LHS can mention *different* type variables than the -- enclosing class. So it's treated more as a freestanding beast. - ; (qtvs, pats, rhs_ty) <- tcTyFamInstEqnGuts fam_tc NotAssociated - outer_bndrs hs_pats hs_rhs_ty + ; (qtvs, non_user_tvs, pats, rhs_ty) + <- tcTyFamInstEqnGuts fam_tc NotAssociated + outer_bndrs hs_pats hs_rhs_ty ; let fam_tvs = tyConTyVars fam_tc ; traceTc "tcDefaultAssocDecl 2" (vcat @@ -2784,7 +2797,12 @@ tcDefaultAssocDecl fam_tc -- over later, in GHC.Tc.Validity.checkValidAssocTyFamDeflt. -- See Note [Type-checking default assoc decls]. - ; pure $ Just (substTyUnchecked subst rhs_ty, ATVI (locA loc) qtvs pats rhs_ty) + ; pure $ Just ( substTyUnchecked subst rhs_ty + , VI { vi_loc = locA loc + , vi_qtvs = qtvs + , vi_non_user_tvs = non_user_tvs + , vi_pats = pats + , vi_rhs = rhs_ty } ) -- We perform checks for well-formedness and validity later, in -- GHC.Tc.Validity.checkValidAssocTyFamDeflt. } @@ -2887,7 +2905,7 @@ any damage is done. * * ********************************************************************* -} -tcFamDecl1 :: Maybe Class -> FamilyDecl GhcRn -> TcM TyCon +tcFamDecl1 :: Maybe Class -> FamilyDecl GhcRn -> TcM (TyCon, [TyFamEqnValidityInfo]) tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info , fdLName = tc_lname@(L _ tc_name) , fdResultSig = L _ sig @@ -2916,7 +2934,7 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info (resultVariableName sig) (DataFamilyTyCon tc_rep_name) parent inj - ; return tycon } + ; return (tycon, []) } | OpenTypeFamily <- fam_info = bindTyClTyVarsAndZonk tc_name $ \ tc_bndrs res_kind -> do @@ -2927,7 +2945,7 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info ; let tycon = mkFamilyTyCon tc_name tc_bndrs res_kind (resultVariableName sig) OpenSynFamilyTyCon parent inj' - ; return tycon } + ; return (tycon, []) } | ClosedTypeFamily mb_eqns <- fam_info = -- Closed type families are a little tricky, because they contain the definition @@ -2947,10 +2965,11 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info -- but eqns might be empty in the Just case as well ; case mb_eqns of Nothing -> - return $ mkFamilyTyCon tc_name tc_bndrs res_kind - (resultVariableName sig) - AbstractClosedSynFamilyTyCon parent - inj' + let tc = mkFamilyTyCon tc_name tc_bndrs res_kind + (resultVariableName sig) + AbstractClosedSynFamilyTyCon parent + inj' + in return (tc, []) Just eqns -> do { -- Process the equations, creating CoAxBranches @@ -2959,7 +2978,8 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info False {- this doesn't matter here -} ClosedTypeFamilyFlavour - ; branches <- mapAndReportM (tcTyFamInstEqn tc_fam_tc NotAssociated) eqns + ; (branches, axiom_validity_infos) <- + unzip <$> mapAndReportM (tcTyFamInstEqn tc_fam_tc NotAssociated) eqns -- Do not attempt to drop equations dominated by earlier -- ones here; in the case of mutual recursion with a data -- type, we get a knot-tying failure. Instead we check @@ -2979,7 +2999,7 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info -- We check for instance validity later, when doing validity -- checking for the tycon. Exception: checking equations -- overlap done by dropDominatedAxioms - ; return fam_tc } } + ; return (fam_tc, axiom_validity_infos) } } -- | Maybe return a list of Bools that say whether a type family was declared -- injective in the corresponding type arguments. Length of the list is equal to @@ -3187,7 +3207,7 @@ kcTyFamInstEqn tc_fam_tc -------------------------- tcTyFamInstEqn :: TcTyCon -> AssocInstInfo -> LTyFamInstEqn GhcRn - -> TcM (KnotTied CoAxBranch) + -> TcM (KnotTied CoAxBranch, TyFamEqnValidityInfo) -- Needs to be here, not in GHC.Tc.TyCl.Instance, because closed families -- (typechecked here) have TyFamInstEqns @@ -3206,13 +3226,22 @@ tcTyFamInstEqn fam_tc mb_clsinfo ; checkTyFamInstEqn fam_tc eqn_tc_name hs_pats - ; (qtvs, pats, rhs_ty) <- tcTyFamInstEqnGuts fam_tc mb_clsinfo - outer_bndrs hs_pats hs_rhs_ty + ; (qtvs, non_user_tvs, pats, rhs_ty) + <- tcTyFamInstEqnGuts fam_tc mb_clsinfo + outer_bndrs hs_pats hs_rhs_ty -- Don't print results they may be knot-tied -- (tcFamInstEqnGuts zonks to Type) - ; return (mkCoAxBranch qtvs [] [] pats rhs_ty - (map (const Nominal) qtvs) - (locA loc)) } + + ; let ax = mkCoAxBranch qtvs [] [] pats rhs_ty + (map (const Nominal) qtvs) + (locA loc) + vi = VI { vi_loc = locA loc + , vi_qtvs = qtvs + , vi_non_user_tvs = non_user_tvs + , vi_pats = pats + , vi_rhs = rhs_ty } + + ; return (ax, vi) } checkTyFamInstEqn :: TcTyCon -> Name -> [HsArg p tm ty] -> TcM () checkTyFamInstEqn tc_fam_tc eqn_tc_name hs_pats = @@ -3296,11 +3325,13 @@ generalising over the type of a rewrite rule. -} -------------------------- + tcTyFamInstEqnGuts :: TyCon -> AssocInstInfo -> HsOuterFamEqnTyVarBndrs GhcRn -- Implicit and explicit binders - -> HsFamEqnPats GhcRn -- Patterns + -> HsFamEqnPats GhcRn -- Patterns -> LHsType GhcRn -- RHS - -> TcM ([TyVar], [TcType], TcType) -- (tyvars, pats, rhs) + -> TcM ([TyVar], TyVarSet, [TcType], TcType) + -- (tyvars, non_user_tvs, pats, rhs) -- Used only for type families, not data families tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty = do { traceTc "tcTyFamInstEqnGuts {" (ppr fam_tc $$ ppr outer_hs_bndrs $$ ppr hs_pats) @@ -3354,11 +3385,12 @@ tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty ; return (tidy_env2, UninfTyCtx_TyFamRhs rhs_ty) } ; doNotQuantifyTyVars dvs_rhs err_ctx - ; (final_tvs, lhs_ty, rhs_ty) <- initZonkEnv NoFlexi $ + ; (final_tvs, non_user_tvs, lhs_ty, rhs_ty) <- initZonkEnv NoFlexi $ runZonkBndrT (zonkTyBndrsX final_tvs) $ \ final_tvs -> - do { lhs_ty <- zonkTcTypeToTypeX lhs_ty - ; rhs_ty <- zonkTcTypeToTypeX rhs_ty - ; return (final_tvs, lhs_ty, rhs_ty) } + do { lhs_ty <- zonkTcTypeToTypeX lhs_ty + ; rhs_ty <- zonkTcTypeToTypeX rhs_ty + ; non_user_tvs <- traverse lookupTyVarX qtvs + ; return (final_tvs, non_user_tvs, lhs_ty, rhs_ty) } ; let pats = unravelFamInstPats lhs_ty -- Note that we do this after solveEqualities @@ -3369,7 +3401,7 @@ tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty -- Don't try to print 'pats' here, because lhs_ty involves -- a knot-tied type constructor, so we get a black hole - ; return (final_tvs, pats, rhs_ty) } + ; return (final_tvs, mkVarSet non_user_tvs, pats, rhs_ty) } checkFamTelescope :: TcLevel -> HsOuterFamEqnTyVarBndrs GhcRn @@ -4887,12 +4919,17 @@ checkValidClass cls -- Check that any default declarations for associated types are valid ; whenIsJust m_dflt_rhs $ \ (_, at_validity_info) -> case at_validity_info of - NoATVI -> pure () - ATVI loc qtvs pats orig_rhs -> + NoVI -> pure () + VI { vi_loc = loc + , vi_qtvs = qtvs + , vi_non_user_tvs = non_user_tvs + , vi_pats = pats + , vi_rhs = orig_rhs } -> setSrcSpan loc $ tcAddFamInstCtxt (text "default type instance") (getName fam_tc) $ do { checkValidAssocTyFamDeflt fam_tc pats - ; checkValidTyFamEqn fam_tc qtvs pats orig_rhs }} + ; checkFamPatBinders fam_tc qtvs non_user_tvs pats orig_rhs + ; checkValidTyFamEqn fam_tc pats orig_rhs }} where fam_tvs = tyConTyVars fam_tc diff --git a/compiler/GHC/Tc/TyCl/Build.hs b/compiler/GHC/Tc/TyCl/Build.hs index e1077b490f42cee4c6cd7084692d63afd9ec1caa..0de5dc3e7a6e2694af33cf97c01061a8b62e4e71 100644 --- a/compiler/GHC/Tc/TyCl/Build.hs +++ b/compiler/GHC/Tc/TyCl/Build.hs @@ -4,7 +4,6 @@ -} - {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Tc.TyCl.Build ( diff --git a/compiler/GHC/Tc/TyCl/Instance.hs b/compiler/GHC/Tc/TyCl/Instance.hs index bb98c083754ede3a684167ce3bd10e689e46d71d..505899d474508836c5cf23fe87117f5cf420aedc 100644 --- a/compiler/GHC/Tc/TyCl/Instance.hs +++ b/compiler/GHC/Tc/TyCl/Instance.hs @@ -608,11 +608,13 @@ tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn })) -- (1) do the work of verifying the synonym group -- For some reason we don't have a location for the equation -- itself, so we make do with the location of family name - ; co_ax_branch <- tcTyFamInstEqn fam_tc mb_clsinfo - (L (na2la $ getLoc fam_lname) eqn) + ; (co_ax_branch, co_ax_validity_info) + <- tcTyFamInstEqn fam_tc mb_clsinfo + (L (na2la $ getLoc fam_lname) eqn) -- (2) check for validity ; checkConsistentFamInst mb_clsinfo fam_tc co_ax_branch + ; checkTyFamEqnValidityInfo fam_tc co_ax_validity_info ; checkValidCoAxBranch fam_tc co_ax_branch -- (3) construct coercion axiom @@ -713,7 +715,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol ; let new_or_data = dataDefnConsNewOrData hs_cons - ; (qtvs, pats, tc_res_kind, stupid_theta) + ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity hs_ctxt hs_pats m_ksig new_or_data @@ -788,7 +790,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env , text "res_kind:" <+> ppr res_kind , text "eta_pats" <+> ppr eta_pats , text "eta_tcbs" <+> ppr eta_tcbs ] - ; (rep_tc, axiom) <- fixM $ \ ~(rec_rep_tc, _) -> + ; (rep_tc, (axiom, ax_rhs)) <- fixM $ \ ~(rec_rep_tc, _) -> do { data_cons <- tcExtendTyVarEnv (binderVars tc_ty_binders) $ -- For H98 decls, the tyvars scope -- over the data constructors @@ -824,13 +826,15 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- further instance might not introduce a new recursive -- dependency. (2) They are always valid loop breakers as -- they involve a coercion. - ; return (rep_tc, axiom) } + + ; return (rep_tc, (axiom, ax_rhs)) } -- 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) ; let ax_branch = coAxiomSingleBranch axiom ; checkConsistentFamInst mb_clsinfo fam_tc ax_branch + ; checkFamPatBinders fam_tc zonked_post_eta_qtvs non_user_tvs eta_pats ax_rhs ; checkValidCoAxBranch fam_tc ax_branch ; checkValidTyCon rep_tc @@ -838,10 +842,10 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env m_deriv_info = case derivs of [] -> Nothing preds -> - Just $ DerivInfo { di_rep_tc = rep_tc + Just $ DerivInfo { di_rep_tc = rep_tc , di_scoped_tvs = scoped_tvs - , di_clauses = preds - , di_ctxt = tcMkDataFamInstCtxt decl } + , di_clauses = preds + , di_ctxt = tcMkDataFamInstCtxt decl } ; fam_inst <- newFamInst (DataFamilyInst rep_tc) axiom ; return (fam_inst, m_deriv_info) } @@ -915,7 +919,7 @@ tcDataFamInstHeader -> LexicalFixity -> Maybe (LHsContext GhcRn) -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> NewOrData - -> TcM ([TcTyVar], [TcType], TcKind, TcThetaType) + -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than -- the data constructors themselves @@ -975,14 +979,15 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- the outer_tvs. See Note [Generalising in tcTyFamInstEqnGuts] ; reportUnsolvedEqualities skol_info final_tvs tclvl wanted - ; (final_tvs,lhs_ty,master_res_kind,instance_res_kind,stupid_theta) <- + ; (final_tvs, non_user_tvs, lhs_ty, master_res_kind, instance_res_kind, stupid_theta) <- liftZonkM $ do - { final_tvs <- zonkTcTyVarsToTcTyVars final_tvs - ; lhs_ty <- zonkTcType lhs_ty - ; master_res_kind <- zonkTcType master_res_kind - ; instance_res_kind <- zonkTcType instance_res_kind - ; stupid_theta <- zonkTcTypes stupid_theta - ; return (final_tvs,lhs_ty,master_res_kind,instance_res_kind,stupid_theta) } + { final_tvs <- mapM zonkTcTyVarToTcTyVar final_tvs + ; non_user_tvs <- mapM zonkTcTyVarToTcTyVar qtvs + ; lhs_ty <- zonkTcType lhs_ty + ; master_res_kind <- zonkTcType master_res_kind + ; instance_res_kind <- zonkTcType instance_res_kind + ; stupid_theta <- zonkTcTypes stupid_theta + ; return (final_tvs, non_user_tvs, lhs_ty, master_res_kind, instance_res_kind, stupid_theta) } -- Check that res_kind is OK with checkDataKindSig. We need to -- check that it's ok because res_kind can come from a user-written @@ -994,7 +999,7 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- For the scopedSort see Note [Generalising in tcTyFamInstEqnGuts] ; let pats = unravelFamInstPats lhs_ty - ; return (final_tvs, pats, master_res_kind, stupid_theta) } + ; return (final_tvs, mkVarSet non_user_tvs, pats, master_res_kind, stupid_theta) } where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name diff --git a/compiler/GHC/Tc/Validity.hs b/compiler/GHC/Tc/Validity.hs index ece2c26c5192ed2140ac4f376e1887a9f4530cbf..b2f7830a52ff062bfd9140da42d26bc6be4ae333 100644 --- a/compiler/GHC/Tc/Validity.hs +++ b/compiler/GHC/Tc/Validity.hs @@ -1,4 +1,5 @@ {-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -14,6 +15,7 @@ module GHC.Tc.Validity ( checkValidInstance, checkValidInstHead, validDerivPred, checkTySynRhs, checkEscapingKind, checkValidCoAxiom, checkValidCoAxBranch, + checkFamPatBinders, checkTyFamEqnValidityInfo, checkValidTyFamEqn, checkValidAssocTyFamDeflt, checkConsistentFamInst, checkTyConTelescope, ) where @@ -2164,26 +2166,21 @@ checkValidCoAxiom ax@(CoAxiom { co_ax_tc = fam_tc, co_ax_branches = branches }) -- checkValidCoAxBranch :: TyCon -> CoAxBranch -> TcM () checkValidCoAxBranch fam_tc - (CoAxBranch { cab_tvs = tvs, cab_cvs = cvs - , cab_lhs = typats + (CoAxBranch { cab_lhs = typats , cab_rhs = rhs, cab_loc = loc }) = setSrcSpan loc $ - checkValidTyFamEqn fam_tc (tvs++cvs) typats rhs + checkValidTyFamEqn fam_tc typats rhs -- | Do validity checks on a type family equation, including consistency -- with any enclosing class instance head, termination, and lack of -- polytypes. -checkValidTyFamEqn :: TyCon -- ^ of the type family - -> [Var] -- ^ Bound variables in the equation - -> [Type] -- ^ Type patterns - -> Type -- ^ Rhs +checkValidTyFamEqn :: TyCon -- ^ of the type family + -> [Type] -- ^ Type patterns + -> Type -- ^ Rhs -> TcM () -checkValidTyFamEqn fam_tc qvs typats rhs +checkValidTyFamEqn fam_tc typats rhs = do { checkValidTypePats fam_tc typats - -- Check for things used on the right but not bound on the left - ; checkFamPatBinders fam_tc qvs typats rhs - -- Check for oversaturated visible kind arguments in a type family -- equation. -- See Note [Oversaturated type family equations] @@ -2285,12 +2282,28 @@ checkFamInstRhs lhs_tc lhs_tys famInsts = Nothing ----------------- + +-- | Perform scoping check on a type family equation. +-- +-- See 'TyFamEqnValidityInfo'. +checkTyFamEqnValidityInfo :: TyCon -> TyFamEqnValidityInfo -> TcM () +checkTyFamEqnValidityInfo fam_tc = \ case + NoVI -> return () + VI { vi_loc = loc + , vi_qtvs = qtvs + , vi_non_user_tvs = non_user_tvs + , vi_pats = pats + , vi_rhs = rhs } -> + setSrcSpan loc $ + checkFamPatBinders fam_tc qtvs non_user_tvs pats rhs + checkFamPatBinders :: TyCon - -> [TcTyVar] -- Bound on LHS of family instance - -> [TcType] -- LHS patterns - -> Type -- RHS + -> [TcTyVar] -- ^ Bound on LHS of family instance + -> TyVarSet -- ^ non-user-written tyvars + -> [TcType] -- ^ LHS patterns + -> TcType -- ^ RHS -> TcM () -checkFamPatBinders fam_tc qtvs pats rhs +checkFamPatBinders fam_tc qtvs non_user_tvs pats rhs = do { traceTc "checkFamPatBinders" $ vcat [ debugPprType (mkTyConApp fam_tc pats) , ppr (mkTyConApp fam_tc pats) @@ -2351,10 +2364,19 @@ checkFamPatBinders fam_tc qtvs pats rhs -- message. used_tvs = cpt_tvs `unionVarSet` fvVarSet rhs_fvs - bad_qtvs = filterOut (`elemVarSet` used_tvs) qtvs - -- Bound but not used at all + + -- Bound but not used at all + bad_qtvs = filterOut ((`elemVarSet` used_tvs) <||> (`elemVarSet` non_user_tvs)) + qtvs + -- Filter out non-user-tvs in order to only report user-written type variables, + -- e.g. type instance forall a. F = () + -- -XPolyKinds introduces the binder 'k' for the kind of 'a', but + -- we don't want the error message to complain about 'k' being unused, + -- as the user has not written it. + + -- Used on RHS but not bound on LHS bad_rhs_tvs = filterOut (`elemVarSet` inj_cpt_tvs) (fvVarList rhs_fvs) - -- Used on RHS but not bound on LHS + dodgy_tvs = cpt_tvs `minusVarSet` inj_cpt_tvs check_tvs mk_err tvs diff --git a/compiler/GHC/Tc/Zonk/Type.hs b/compiler/GHC/Tc/Zonk/Type.hs index 788f6c582b55cec723d9ec1c9975f68f893f9634..0df9ddc8cbb1c655a23c3f1aa4f7c6de228eeac6 100644 --- a/compiler/GHC/Tc/Zonk/Type.hs +++ b/compiler/GHC/Tc/Zonk/Type.hs @@ -16,7 +16,7 @@ module GHC.Tc.Zonk.Type ( zonkTopDecls, zonkTopExpr, zonkTopLExpr, zonkTopBndrs, zonkTyVarBindersX, zonkTyVarBinderX, - zonkTyBndrsX, + zonkTyBndrX, zonkTyBndrsX, zonkTcTypeToType, zonkTcTypeToTypeX, zonkTcTypesToTypesX, zonkScaledTcTypesToTypesX, zonkTyVarOcc, diff --git a/testsuite/tests/indexed-types/should_fail/ExplicitForAllFams4b.stderr b/testsuite/tests/indexed-types/should_fail/ExplicitForAllFams4b.stderr index 508938616a51f8dde9ad1aa3b022b583b7ae3d30..80bc9138403ad04a8304858da289181d455fe6d9 100644 --- a/testsuite/tests/indexed-types/should_fail/ExplicitForAllFams4b.stderr +++ b/testsuite/tests/indexed-types/should_fail/ExplicitForAllFams4b.stderr @@ -14,9 +14,9 @@ ExplicitForAllFams4b.hs:9:22: error: [GHC-53634] All such variables must be bound on the LHS. • In the type instance declaration for ‘J’ -ExplicitForAllFams4b.hs:12:24: error: [GHC-53634] - • Out of scope type variable ‘b’ in the RHS of a family instance. - All such variables must be bound on the LHS. +ExplicitForAllFams4b.hs:12:24: error: [GHC-30337] + • Type variable ‘b’ is bound by a forall, + but not used in the family instance. • In the data instance declaration for ‘K’ ExplicitForAllFams4b.hs:12:27: error: [GHC-34447] @@ -29,9 +29,9 @@ ExplicitForAllFams4b.hs:13:22: error: [GHC-30337] but not used in the family instance. • In the data instance declaration for ‘K’ -ExplicitForAllFams4b.hs:16:27: error: [GHC-53634] - • Out of scope type variable ‘b’ in the RHS of a family instance. - All such variables must be bound on the LHS. +ExplicitForAllFams4b.hs:16:27: error: [GHC-30337] + • Type variable ‘b’ is bound by a forall, + but not used in the family instance. • In the newtype instance declaration for ‘L’ ExplicitForAllFams4b.hs:16:30: error: [GHC-34447] @@ -64,9 +64,9 @@ ExplicitForAllFams4b.hs:25:3: error: [GHC-95424] • In the data instance declaration for ‘CD’ In the instance declaration for ‘C Int’ -ExplicitForAllFams4b.hs:25:17: error: [GHC-53634] - • Out of scope type variable ‘b’ in the RHS of a family instance. - All such variables must be bound on the LHS. +ExplicitForAllFams4b.hs:25:17: error: [GHC-30337] + • Type variable ‘b’ is bound by a forall, + but not used in the family instance. • In the data instance declaration for ‘CD’ In the instance declaration for ‘C Int’ @@ -88,8 +88,8 @@ ExplicitForAllFams4b.hs:32:15: error: [GHC-30337] • In the type instance declaration for ‘CT’ In the instance declaration for ‘C Double’ -ExplicitForAllFams4b.hs:33:15: error: [GHC-53634] - • Out of scope type variable ‘b’ in the RHS of a family instance. - All such variables must be bound on the LHS. +ExplicitForAllFams4b.hs:33:15: error: [GHC-30337] + • Type variable ‘b’ is bound by a forall, + but not used in the family instance. • In the data instance declaration for ‘CD’ In the instance declaration for ‘C Double’ diff --git a/testsuite/tests/indexed-types/should_fail/T17008a.stderr b/testsuite/tests/indexed-types/should_fail/T17008a.stderr index b118434a03b29f31dfb430c388e03fa8a026686e..600857e641f2a3572c48956b37ae02ec9c93ec23 100644 --- a/testsuite/tests/indexed-types/should_fail/T17008a.stderr +++ b/testsuite/tests/indexed-types/should_fail/T17008a.stderr @@ -1,7 +1,7 @@ T17008a.hs:12:5: error: [GHC-53634] - • Out of scope type variable ‘a2’ in the RHS of a family instance. + • Out of scope type variable ‘a’ in the RHS of a family instance. All such variables must be bound on the LHS. - The real LHS (expanding synonyms) is: F @a1 x + The real LHS (expanding synonyms) is: F @a x • In the equations for closed type family ‘F’ In the type family declaration for ‘F’ diff --git a/testsuite/tests/typecheck/should_fail/T23734.hs b/testsuite/tests/typecheck/should_fail/T23734.hs index f00c16a673e391933785e692a446962e40ca1cfa..69d7c77427ba0458ab68b26018884383c105fc1a 100644 --- a/testsuite/tests/typecheck/should_fail/T23734.hs +++ b/testsuite/tests/typecheck/should_fail/T23734.hs @@ -14,4 +14,4 @@ class C where type forall c. H = () data family D :: Type -data instance forall d. D = MkD +data instance forall (d :: Type). D = MkD diff --git a/testsuite/tests/typecheck/should_fail/T23734.stderr b/testsuite/tests/typecheck/should_fail/T23734.stderr new file mode 100644 index 0000000000000000000000000000000000000000..b5ffbca9fd02172ec8f60a3bb79db6e69ce69cfd --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T23734.stderr @@ -0,0 +1,22 @@ + +T23734.hs:7:22: error: [GHC-30337] + • Type variable ‘a’ is bound by a forall, + but not used in the family instance. + • In the type instance declaration for ‘F’ + +T23734.hs:10:10: error: [GHC-30337] + • Type variable ‘b’ is bound by a forall, + but not used in the family instance. + • In the equations for closed type family ‘G’ + In the type family declaration for ‘G’ + +T23734.hs:14:15: error: [GHC-30337] + • Type variable ‘c’ is bound by a forall, + but not used in the family instance. + • In the default type instance declaration for ‘H’ + In the class declaration for ‘C’ + +T23734.hs:17:23: error: [GHC-30337] + • Type variable ‘d’ is bound by a forall, + but not used in the family instance. + • In the data instance declaration for ‘D’ diff --git a/testsuite/tests/typecheck/should_fail/all.T b/testsuite/tests/typecheck/should_fail/all.T index 0eff733f82fa384bb33689018e4769306d0618e9..92bdeb40cb071629954020bd92568bc6d5d03bbc 100644 --- a/testsuite/tests/typecheck/should_fail/all.T +++ b/testsuite/tests/typecheck/should_fail/all.T @@ -685,6 +685,7 @@ test('CommonFieldTypeMismatch', normal, compile_fail, ['']) test('T17284', normal, compile_fail, ['']) test('T23427', normal, compile_fail, ['']) test('T23778', normal, compile_fail, ['']) +test('T23734', normal, compile_fail, ['']) test('T13981A', [extra_files(['T13981A.hs-boot', 'T13981B.hs', 'T13981C.hs', 'T13981F.hs'])], multimod_compile_fail, ['T13981A', '-v0']) test('T22560_fail_a', normal, compile_fail, ['']) test('T22560_fail_b', normal, compile_fail, [''])