summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2018-08-21 15:57:56 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2018-08-21 16:03:21 +0100
commit43b08cfbac5ce7ad6fc245651329094896de06e0 (patch)
tree9011abea19ca52380cbbff8fcaf2a9fbaddc9512 /compiler
parent828e949318399752630f80f1fbefbbea08c55995 (diff)
downloadhaskell-43b08cfbac5ce7ad6fc245651329094896de06e0.tar.gz
Add a solveEqualities to tcClassDecl1
Trac #15505 showed that, when we have a type error, we could have an unfilled-in coercion hole. We don't want an assertion error in that case. The underlying cause is that tcClassDecl1 should call solveEqualities to fully solve all top-level equalities (or fail in the attempt). I also refactored the ClassDecl case for tcTyClDecl1 into a new function tcClassDecl1. That makes it symmetrical with the others.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/deSugar/DsMeta.hs4
-rw-r--r--compiler/hsSyn/Convert.hs2
-rw-r--r--compiler/hsSyn/HsDecls.hs7
-rw-r--r--compiler/parser/RdrHsSyn.hs3
-rw-r--r--compiler/rename/RnSource.hs3
-rw-r--r--compiler/typecheck/TcHsType.hs10
-rw-r--r--compiler/typecheck/TcTyClsDecls.hs395
7 files changed, 222 insertions, 202 deletions
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index ed2c612e94..085cfc5ec3 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -470,10 +470,10 @@ repAssocTyFamDefaults = mapM rep_deflt
-------------------------
-- represent fundeps
--
-repLFunDeps :: [Located (FunDep (Located Name))] -> DsM (Core [TH.FunDep])
+repLFunDeps :: [LHsFunDep GhcRn] -> DsM (Core [TH.FunDep])
repLFunDeps fds = repList funDepTyConName repLFunDep fds
-repLFunDep :: Located (FunDep (Located Name)) -> DsM (Core TH.FunDep)
+repLFunDep :: LHsFunDep GhcRn -> DsM (Core TH.FunDep)
repLFunDep (L _ (xs, ys))
= do xs' <- repList nameTyConName (lookupBinder . unLoc) xs
ys' <- repList nameTyConName (lookupBinder . unLoc) ys
diff --git a/compiler/hsSyn/Convert.hs b/compiler/hsSyn/Convert.hs
index fbecf9ce9e..66a2681f0b 100644
--- a/compiler/hsSyn/Convert.hs
+++ b/compiler/hsSyn/Convert.hs
@@ -598,7 +598,7 @@ cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs)
cvtDerivs cs = do { cs' <- mapM cvtDerivClause cs
; returnL cs' }
-cvt_fundep :: FunDep -> CvtM (Located (Class.FunDep (Located RdrName)))
+cvt_fundep :: FunDep -> CvtM (LHsFunDep GhcPs)
cvt_fundep (FunDep xs ys) = do { xs' <- mapM tNameL xs
; ys' <- mapM tNameL ys
; returnL (xs', ys') }
diff --git a/compiler/hsSyn/HsDecls.hs b/compiler/hsSyn/HsDecls.hs
index 6dde482c9a..2d2e911645 100644
--- a/compiler/hsSyn/HsDecls.hs
+++ b/compiler/hsSyn/HsDecls.hs
@@ -18,7 +18,7 @@
-- @InstDecl@, @DefaultDecl@ and @ForeignDecl@.
module HsDecls (
-- * Toplevel declarations
- HsDecl(..), LHsDecl, HsDataDefn(..), HsDeriving,
+ HsDecl(..), LHsDecl, HsDataDefn(..), HsDeriving, LHsFunDep,
HsDerivingClause(..), LHsDerivingClause, NewOrData(..), newOrDataToFlavour,
-- ** Class or type declarations
@@ -528,8 +528,7 @@ data TyClDecl pass
tcdLName :: Located (IdP pass), -- ^ Name of the class
tcdTyVars :: LHsQTyVars pass, -- ^ Class type variables
tcdFixity :: LexicalFixity, -- ^ Fixity used in the declaration
- tcdFDs :: [Located (FunDep (Located (IdP pass)))],
- -- ^ Functional deps
+ tcdFDs :: [LHsFunDep pass], -- ^ Functional deps
tcdSigs :: [LSig pass], -- ^ Methods' signatures
tcdMeths :: LHsBinds pass, -- ^ Default methods
tcdATs :: [LFamilyDecl pass], -- ^ Associated types;
@@ -546,6 +545,8 @@ data TyClDecl pass
-- For details on above see note [Api annotations] in ApiAnnotation
| XTyClDecl (XXTyClDecl pass)
+type LHsFunDep pass = Located (FunDep (Located (IdP pass)))
+
data DataDeclRn = DataDeclRn
{ tcdDataCusk :: Bool -- ^ does this have a CUSK?
, tcdFVs :: NameSet }
diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 681ecdeae0..5784b9ecdb 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -78,7 +78,6 @@ module RdrHsSyn (
import GhcPrelude
import HsSyn -- Lots of it
-import Class ( FunDep )
import TyCon ( TyCon, isTupleTyCon, tyConSingleDataCon_maybe )
import DataCon ( DataCon, dataConTyCon )
import ConLike ( ConLike(..) )
@@ -142,7 +141,7 @@ mkInstD (L loc d) = L loc (InstD noExt d)
mkClassDecl :: SrcSpan
-> Located (Maybe (LHsContext GhcPs), LHsType GhcPs)
- -> Located (a,[Located (FunDep (Located RdrName))])
+ -> Located (a,[LHsFunDep GhcPs])
-> OrdList (LHsDecl GhcPs)
-> P (LTyClDecl GhcPs)
diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs
index 596852031a..987ed177aa 100644
--- a/compiler/rename/RnSource.hs
+++ b/compiler/rename/RnSource.hs
@@ -2141,8 +2141,7 @@ extendPatSynEnv val_decls local_fix_env thing = do {
*********************************************************
-}
-rnFds :: [Located (FunDep (Located RdrName))]
- -> RnM [Located (FunDep (Located Name))]
+rnFds :: [LHsFunDep GhcPs] -> RnM [LHsFunDep GhcRn]
rnFds fds
= mapM (wrapLocM rn_fds) fds
where
diff --git a/compiler/typecheck/TcHsType.hs b/compiler/typecheck/TcHsType.hs
index 6048caa97b..ed488320b0 100644
--- a/compiler/typecheck/TcHsType.hs
+++ b/compiler/typecheck/TcHsType.hs
@@ -207,7 +207,8 @@ tcHsSigType ctxt sig_ty
-- of kind * in a Template Haskell quote eg [t| Maybe |]
-- Generalise here: see Note [Kind generalisation]
- ; ty <- tc_hs_sig_type_and_gen skol_info sig_ty kind >>= zonkTcType
+ ; ty <- tc_hs_sig_type_and_gen skol_info sig_ty kind
+ ; ty <- zonkTcType ty
; checkValidType ctxt ty
; traceTc "end tcHsSigType }" (ppr ty)
@@ -226,10 +227,9 @@ tc_hs_sig_type_and_gen skol_info (HsIB { hsib_ext = sig_vars
= do { ((tkvs, ty), wanted) <- captureConstraints $
tcImplicitTKBndrs skol_info sig_vars $
tc_lhs_type typeLevelMode hs_ty kind
- -- Any remaining variables (unsolved in the solveLocalEqualities in the
- -- tcImplicitTKBndrs)
- -- should be in the global tyvars, and therefore won't be quantified
- -- over.
+ -- Any remaining variables (unsolved in the solveLocalEqualities
+ -- in the tcImplicitTKBndrs) should be in the global tyvars,
+ -- and therefore won't be quantified over
; let ty1 = mkSpecForAllTys tkvs ty
; kvs <- kindGeneralizeLocal wanted ty1
diff --git a/compiler/typecheck/TcTyClsDecls.hs b/compiler/typecheck/TcTyClsDecls.hs
index 97f794deae..fd032f8530 100644
--- a/compiler/typecheck/TcTyClsDecls.hs
+++ b/compiler/typecheck/TcTyClsDecls.hs
@@ -987,52 +987,222 @@ tcTyClDecl1 _parent roles_info
tcTyClDecl1 _parent roles_info
(ClassDecl { tcdLName = L _ class_name
- , tcdCtxt = ctxt, tcdMeths = meths
+ , tcdCtxt = hs_ctxt, tcdMeths = meths
, tcdFDs = fundeps, tcdSigs = sigs
, tcdATs = ats, tcdATDefs = at_defs })
= ASSERT( isNothing _parent )
- do { clas <- fixM $ \ clas ->
- -- We need the knot because 'clas' is passed into tcClassATs
- tcTyClTyVars class_name $ \ binders res_kind ->
- do { MASSERT2( tcIsConstraintKind res_kind
- , ppr class_name $$ ppr res_kind )
- ; traceTc "tcClassDecl 1" (ppr class_name $$ ppr binders)
- ; let tycon_name = class_name -- We use the same name
- roles = roles_info tycon_name -- for TyCon and Class
-
- ; ctxt' <- solveEqualities $ tcHsContext ctxt
- ; ctxt' <- zonkTcTypeToTypes emptyZonkEnv ctxt'
- -- Squeeze out any kind unification variables
- ; fds' <- mapM (addLocM tc_fundep) fundeps
- ; sig_stuff <- tcClassSigs class_name sigs meths
- ; at_stuff <- tcClassATs class_name clas ats at_defs
- ; mindef <- tcClassMinimalDef class_name sigs sig_stuff
- -- TODO: Allow us to distinguish between abstract class,
- -- and concrete class with no methods (maybe by
- -- specifying a trailing where or not
- ; sig_stuff' <- mapM zonkTcMethInfoToMethInfo sig_stuff
- -- this zonk is really just to squeeze out the TcTyCons
- -- and convert, e.g., Skolems to tyvars. We won't
- -- see any unfilled metavariables here.
-
- ; is_boot <- tcIsHsBootOrSig
- ; let body | is_boot, null ctxt', null at_stuff, null sig_stuff
- = Nothing
- | otherwise
- = Just (ctxt', at_stuff, sig_stuff', mindef)
-
- ; clas <- buildClass class_name binders roles fds' body
- ; traceTc "tcClassDecl" (ppr fundeps $$ ppr binders $$
- ppr fds')
- ; return clas }
-
- ; return (classTyCon clas) }
+ do { clas <- tcClassDecl1 roles_info class_name hs_ctxt
+ meths fundeps sigs ats at_defs
+ ; return (classTyCon clas) }
+
+tcTyClDecl1 _ _ (XTyClDecl _) = panic "tcTyClDecl1"
+
+
+{- *********************************************************************
+* *
+ Class declarations
+* *
+********************************************************************* -}
+
+tcClassDecl1 :: RolesInfo -> Name -> LHsContext GhcRn
+ -> LHsBinds GhcRn -> [LHsFunDep GhcRn] -> [LSig GhcRn]
+ -> [LFamilyDecl GhcRn] -> [LTyFamDefltEqn GhcRn]
+ -> TcM Class
+tcClassDecl1 roles_info class_name hs_ctxt meths fundeps sigs ats at_defs
+ = fixM $ \ clas ->
+ -- We need the knot because 'clas' is passed into tcClassATs
+ tcTyClTyVars class_name $ \ binders res_kind ->
+ do { MASSERT2( tcIsConstraintKind res_kind
+ , ppr class_name $$ ppr res_kind )
+ ; traceTc "tcClassDecl 1" (ppr class_name $$ ppr binders)
+ ; let tycon_name = class_name -- We use the same name
+ roles = roles_info tycon_name -- for TyCon and Class
+
+ ; (ctxt, fds, sig_stuff, at_stuff)
+ <- solveEqualities $
+ do { ctxt <- tcHsContext hs_ctxt
+ ; fds <- mapM (addLocM tc_fundep) fundeps
+ ; sig_stuff <- tcClassSigs class_name sigs meths
+ ; at_stuff <- tcClassATs class_name clas ats at_defs
+ ; return (ctxt, fds, sig_stuff, at_stuff) }
+
+ -- The solveEqualities will report errors for any
+ -- unsolved equalities, so these zonks should not encounter
+ -- any unfilled coercion variables unless there is such an error
+ -- The zonk also squeeze out the TcTyCons, and converts
+ -- Skolems to tyvars.
+ ; ctxt <- zonkTcTypeToTypes emptyZonkEnv ctxt
+ ; sig_stuff <- mapM zonkTcMethInfoToMethInfo sig_stuff
+ -- ToDo: do we need to zonk at_stuff?
+
+ -- TODO: Allow us to distinguish between abstract class,
+ -- and concrete class with no methods (maybe by
+ -- specifying a trailing where or not
+
+ ; mindef <- tcClassMinimalDef class_name sigs sig_stuff
+ ; is_boot <- tcIsHsBootOrSig
+ ; let body | is_boot, null ctxt, null at_stuff, null sig_stuff
+ = Nothing
+ | otherwise
+ = Just (ctxt, at_stuff, sig_stuff, mindef)
+
+ ; clas <- buildClass class_name binders roles fds body
+ ; traceTc "tcClassDecl" (ppr fundeps $$ ppr binders $$
+ ppr fds)
+ ; return clas }
where
tc_fundep (tvs1, tvs2) = do { tvs1' <- mapM (tcLookupTyVar . unLoc) tvs1 ;
; tvs2' <- mapM (tcLookupTyVar . unLoc) tvs2 ;
; return (tvs1', tvs2') }
-tcTyClDecl1 _ _ (XTyClDecl _) = panic "tcTyClDecl1"
+
+{- 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
+
+Note that we can get default definitions only for type families, not data
+families.
+-}
+
+tcClassATs :: Name -- The class name (not knot-tied)
+ -> Class -- The class parent of this associated type
+ -> [LFamilyDecl GhcRn] -- Associated types.
+ -> [LTyFamDefltEqn GhcRn] -- Associated type defaults.
+ -> TcM [ClassATItem]
+tcClassATs class_name cls ats at_defs
+ = do { -- Complain about associated type defaults for non associated-types
+ sequence_ [ failWithTc (badATErr class_name n)
+ | n <- map at_def_tycon at_defs
+ , not (n `elemNameSet` at_names) ]
+ ; mapM tc_at ats }
+ where
+ at_def_tycon :: LTyFamDefltEqn GhcRn -> Name
+ at_def_tycon (L _ eqn) = unLoc (feqn_tycon eqn)
+
+ at_fam_name :: LFamilyDecl GhcRn -> Name
+ at_fam_name (L _ decl) = unLoc (fdLName decl)
+
+ at_names = mkNameSet (map at_fam_name ats)
+
+ at_defs_map :: NameEnv [LTyFamDefltEqn GhcRn]
+ -- Maps an AT in 'ats' to a list of all its default defs in 'at_defs'
+ at_defs_map = foldr (\at_def nenv -> extendNameEnv_C (++) nenv
+ (at_def_tycon at_def) [at_def])
+ emptyNameEnv at_defs
+
+ tc_at at = do { fam_tc <- addLocM (tcFamDecl1 (Just cls)) at
+ ; let at_defs = lookupNameEnv at_defs_map (at_fam_name at)
+ `orElse` []
+ ; atd <- tcDefaultAssocDecl fam_tc at_defs
+ ; return (ATI fam_tc atd) }
+
+-------------------------
+tcDefaultAssocDecl :: TyCon -- ^ Family TyCon (not knot-tied)
+ -> [LTyFamDefltEqn GhcRn] -- ^ Defaults
+ -> TcM (Maybe (KnotTied Type, SrcSpan)) -- ^ Type checked RHS
+tcDefaultAssocDecl _ []
+ = return Nothing -- No default declaration
+
+tcDefaultAssocDecl _ (d1:_:_)
+ = failWithTc (text "More than one default declaration for"
+ <+> ppr (feqn_tycon (unLoc d1)))
+
+tcDefaultAssocDecl fam_tc [L loc (FamEqn { feqn_tycon = L _ tc_name
+ , feqn_pats = hs_tvs
+ , feqn_rhs = rhs })]
+ | HsQTvs { hsq_ext = HsQTvsRn { hsq_implicit = imp_vars}
+ , hsq_explicit = exp_vars } <- hs_tvs
+ = -- See Note [Type-checking default assoc decls]
+ setSrcSpan loc $
+ tcAddFamInstCtxt (text "default type instance") tc_name $
+ do { traceTc "tcDefaultAssocDecl" (ppr tc_name)
+ ; let fam_tc_name = tyConName fam_tc
+ fam_arity = length (tyConVisibleTyVars fam_tc)
+
+ -- Kind of family check
+ ; ASSERT( fam_tc_name == tc_name )
+ checkTc (isTypeFamilyTyCon fam_tc) (wrongKindOfFamily fam_tc)
+
+ -- Arity check
+ ; checkTc (exp_vars `lengthIs` fam_arity)
+ (wrongNumberOfParmsErr fam_arity)
+
+ -- Typecheck RHS
+ ; let all_vars = imp_vars ++ map hsLTyVarName exp_vars
+ pats = map hsLTyVarBndrToType exp_vars
+
+ -- NB: Use tcFamTyPats, not tcTyClTyVars. The latter expects to get
+ -- the LHsQTyVars used for declaring a tycon, but the names here
+ -- are different.
+
+ -- You might think we should pass in some ClsInstInfo, as we're looking
+ -- 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.
+ ; (pats', rhs_ty)
+ <- tcFamTyPats fam_tc Nothing all_vars pats
+ (kcTyFamEqnRhs Nothing rhs) $
+ \tvs pats rhs_kind ->
+ do { rhs_ty <- solveEqualities $
+ tcCheckLHsType rhs rhs_kind
+
+ -- Zonk the patterns etc into the Type world
+ ; (ze, _) <- zonkTyBndrsX emptyZonkEnv tvs
+ ; pats' <- zonkTcTypeToTypes ze pats
+ ; rhs_ty' <- zonkTcTypeToType ze rhs_ty
+ ; return (pats', rhs_ty') }
+
+ -- See Note [Type-checking default assoc decls]
+ ; case tcMatchTys pats' (mkTyVarTys (tyConTyVars fam_tc)) of
+ Just subst -> return (Just (substTyUnchecked subst rhs_ty, loc) )
+ Nothing -> failWithTc (defaultAssocKindErr fam_tc)
+ -- We check for well-formedness and validity later,
+ -- in checkValidClass
+ }
+tcDefaultAssocDecl _ [L _ (XFamEqn _)] = panic "tcDefaultAssocDecl"
+tcDefaultAssocDecl _ [L _ (FamEqn _ (L _ _) (XLHsQTyVars _) _ _)]
+ = panic "tcDefaultAssocDecl"
+
+{- Note [Type-checking default assoc decls]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider this default declaration for an associated type
+
+ class C a where
+ type F (a :: k) b :: *
+ type F x y = Proxy x -> y
+
+Note that the class variable 'a' doesn't scope over the default assoc
+decl (rather oddly I think), and (less oddly) neither does the second
+argument 'b' of the associated type 'F', or the kind variable 'k'.
+Instead, the default decl is treated more like a top-level type
+instance.
+
+However we store the default rhs (Proxy x -> y) in F's TyCon, using
+F's own type variables, so we need to convert it to (Proxy a -> b).
+We do this by calling tcMatchTys to match them up. This also ensures
+that x's kind matches a's and similarly for y and b. The error
+message isn't great, mind you. (Trac #11361 was caused by not doing a
+proper tcMatchTys here.)
+
+Recall also that the left-hand side of an associated type family
+default is always just variables -- no tycons here. Accordingly,
+the patterns used in the tcMatchTys won't actually be knot-tied,
+even though we're in the knot. This is too delicate for my taste,
+but it works.
+
+-}
+
+{- *********************************************************************
+* *
+ Type family declarations
+* *
+********************************************************************* -}
tcFamDecl1 :: Maybe Class -> FamilyDecl GhcRn -> TcM TyCon
tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info, fdLName = tc_lname@(L _ tc_name)
@@ -1246,155 +1416,6 @@ tcDataDefn roles_info
mkNewTyConRhs tc_name tycon (head data_cons)
tcDataDefn _ _ _ _ (XHsDataDefn _) = panic "tcDataDefn"
-{-
-************************************************************************
-* *
- Typechecking associated types (in class decls)
- (including the associated-type defaults)
-* *
-************************************************************************
-
-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
-
-Note that we can get default definitions only for type families, not data
-families.
--}
-
-tcClassATs :: Name -- The class name (not knot-tied)
- -> Class -- The class parent of this associated type
- -> [LFamilyDecl GhcRn] -- Associated types.
- -> [LTyFamDefltEqn GhcRn] -- Associated type defaults.
- -> TcM [ClassATItem]
-tcClassATs class_name cls ats at_defs
- = do { -- Complain about associated type defaults for non associated-types
- sequence_ [ failWithTc (badATErr class_name n)
- | n <- map at_def_tycon at_defs
- , not (n `elemNameSet` at_names) ]
- ; mapM tc_at ats }
- where
- at_def_tycon :: LTyFamDefltEqn GhcRn -> Name
- at_def_tycon (L _ eqn) = unLoc (feqn_tycon eqn)
-
- at_fam_name :: LFamilyDecl GhcRn -> Name
- at_fam_name (L _ decl) = unLoc (fdLName decl)
-
- at_names = mkNameSet (map at_fam_name ats)
-
- at_defs_map :: NameEnv [LTyFamDefltEqn GhcRn]
- -- Maps an AT in 'ats' to a list of all its default defs in 'at_defs'
- at_defs_map = foldr (\at_def nenv -> extendNameEnv_C (++) nenv
- (at_def_tycon at_def) [at_def])
- emptyNameEnv at_defs
-
- tc_at at = do { fam_tc <- addLocM (tcFamDecl1 (Just cls)) at
- ; let at_defs = lookupNameEnv at_defs_map (at_fam_name at)
- `orElse` []
- ; atd <- tcDefaultAssocDecl fam_tc at_defs
- ; return (ATI fam_tc atd) }
-
--------------------------
-tcDefaultAssocDecl :: TyCon -- ^ Family TyCon (not knot-tied)
- -> [LTyFamDefltEqn GhcRn] -- ^ Defaults
- -> TcM (Maybe (KnotTied Type, SrcSpan)) -- ^ Type checked RHS
-tcDefaultAssocDecl _ []
- = return Nothing -- No default declaration
-
-tcDefaultAssocDecl _ (d1:_:_)
- = failWithTc (text "More than one default declaration for"
- <+> ppr (feqn_tycon (unLoc d1)))
-
-tcDefaultAssocDecl fam_tc [L loc (FamEqn { feqn_tycon = L _ tc_name
- , feqn_pats = hs_tvs
- , feqn_rhs = rhs })]
- | HsQTvs { hsq_ext = HsQTvsRn { hsq_implicit = imp_vars}
- , hsq_explicit = exp_vars } <- hs_tvs
- = -- See Note [Type-checking default assoc decls]
- setSrcSpan loc $
- tcAddFamInstCtxt (text "default type instance") tc_name $
- do { traceTc "tcDefaultAssocDecl" (ppr tc_name)
- ; let fam_tc_name = tyConName fam_tc
- fam_arity = length (tyConVisibleTyVars fam_tc)
-
- -- Kind of family check
- ; ASSERT( fam_tc_name == tc_name )
- checkTc (isTypeFamilyTyCon fam_tc) (wrongKindOfFamily fam_tc)
-
- -- Arity check
- ; checkTc (exp_vars `lengthIs` fam_arity)
- (wrongNumberOfParmsErr fam_arity)
-
- -- Typecheck RHS
- ; let all_vars = imp_vars ++ map hsLTyVarName exp_vars
- pats = map hsLTyVarBndrToType exp_vars
-
- -- NB: Use tcFamTyPats, not tcTyClTyVars. The latter expects to get
- -- the LHsQTyVars used for declaring a tycon, but the names here
- -- are different.
-
- -- You might think we should pass in some ClsInstInfo, as we're looking
- -- 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.
- ; (pats', rhs_ty)
- <- tcFamTyPats fam_tc Nothing all_vars pats
- (kcTyFamEqnRhs Nothing rhs) $
- \tvs pats rhs_kind ->
- do { rhs_ty <- solveEqualities $
- tcCheckLHsType rhs rhs_kind
-
- -- Zonk the patterns etc into the Type world
- ; (ze, _) <- zonkTyBndrsX emptyZonkEnv tvs
- ; pats' <- zonkTcTypeToTypes ze pats
- ; rhs_ty' <- zonkTcTypeToType ze rhs_ty
- ; return (pats', rhs_ty') }
-
- -- See Note [Type-checking default assoc decls]
- ; case tcMatchTys pats' (mkTyVarTys (tyConTyVars fam_tc)) of
- Just subst -> return (Just (substTyUnchecked subst rhs_ty, loc) )
- Nothing -> failWithTc (defaultAssocKindErr fam_tc)
- -- We check for well-formedness and validity later,
- -- in checkValidClass
- }
-tcDefaultAssocDecl _ [L _ (XFamEqn _)] = panic "tcDefaultAssocDecl"
-tcDefaultAssocDecl _ [L _ (FamEqn _ (L _ _) (XLHsQTyVars _) _ _)]
- = panic "tcDefaultAssocDecl"
-
-{- Note [Type-checking default assoc decls]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider this default declaration for an associated type
-
- class C a where
- type F (a :: k) b :: *
- type F x y = Proxy x -> y
-
-Note that the class variable 'a' doesn't scope over the default assoc
-decl (rather oddly I think), and (less oddly) neither does the second
-argument 'b' of the associated type 'F', or the kind variable 'k'.
-Instead, the default decl is treated more like a top-level type
-instance.
-
-However we store the default rhs (Proxy x -> y) in F's TyCon, using
-F's own type variables, so we need to convert it to (Proxy a -> b).
-We do this by calling tcMatchTys to match them up. This also ensures
-that x's kind matches a's and similarly for y and b. The error
-message isn't great, mind you. (Trac #11361 was caused by not doing a
-proper tcMatchTys here.)
-
-Recall also that the left-hand side of an associated type family
-default is always just variables -- no tycons here. Accordingly,
-the patterns used in the tcMatchTys won't actually be knot-tied,
-even though we're in the knot. This is too delicate for my taste,
-but it works.
-
--}
-------------------------
kcTyFamInstEqn :: TcTyCon -> LTyFamInstEqn GhcRn -> TcM ()