-> TcM TcGblEnv -- Input env extended by types and classes
-- and their implicit Ids,DataCons
tcTyAndClassDecls boot_details allDecls
- = do { -- Omit instances of indexed types; they are handled together
+ = do { -- Omit instances of type families; they are handled together
-- with the *heads* of class instances
; let decls = filter (not . isFamInstDecl . unLoc) allDecls
recoverM (returnM Nothing) $
setSrcSpan loc $
tcAddDeclCtxt decl $
- do { -- type families require -findexed-types and can't be in an
+ do { -- type families require -ftype-families and can't be in an
-- hs-boot file
- ; gla_exts <- doptM Opt_IndexedTypes
+ ; gla_exts <- doptM Opt_TypeFamilies
; is_boot <- tcIsHsBoot -- Are we compiling an hs-boot file?
; checkTc gla_exts $ badFamInstDecl (tcdLName decl)
; checkTc (not is_boot) $ badBootFamInstDeclErr
unless (isSynTyCon family) $
addErr (wrongKindOfFamily family)
- ; -- (1) kind check the right hand side of the type equation
+ ; -- (1) kind check the right-hand side of the type equation
; k_rhs <- kcCheckHsType (tcdSynRhs decl) resKind
-- (2) type check type equation
; t_typats <- mappM tcHsKindedType k_typats
; t_rhs <- tcHsKindedType k_rhs
- -- (3) construct representation tycon
- ; rep_tc_name <- newFamInstTyConName tc_name (srcSpanStart loc)
+ -- (3) check that
+ -- - left-hand side contains no type family applications
+ -- (vanilla synonyms are fine, though)
+ ; mappM_ checkTyFamFreeness t_typats
+
+ -- - the right-hand side is a tau type
+ ; unless (isTauTy t_rhs) $
+ addErr (polyTyErr t_rhs)
+
+ -- (4) construct representation tycon
+ ; rep_tc_name <- newFamInstTyConName tc_name loc
; tycon <- buildSynTyCon rep_tc_name t_tvs (SynonymTyCon t_rhs)
(Just (family, t_typats))
tcdCons = cons})
= kcIdxTyPats decl $ \k_tvs k_typats resKind family ->
do { -- check that the family declaration is for the right kind
- unless (new_or_data == NewType && isNewTyCon family ||
- new_or_data == DataType && isDataTyCon family) $
+ unless (isAlgTyCon family) $
addErr (wrongKindOfFamily family)
; -- (1) kind check the data declaration as usual
; tcTyVarBndrs k_tvs $ \t_tvs -> do { -- turn kinded into proper tyvars
; unbox_strict <- doptM Opt_UnboxStrictFields
- -- Check that we don't use GADT syntax for indexed types
+ -- kind check the type indexes and the context
+ ; t_typats <- mappM tcHsKindedType k_typats
+ ; stupid_theta <- tcHsKindedContext k_ctxt
+
+ -- (3) Check that
+ -- - left-hand side contains no type family applications
+ -- (vanilla synonyms are fine, though)
+ ; mappM_ checkTyFamFreeness t_typats
+
+ -- - we don't use GADT syntax for indexed types
; checkTc h98_syntax (badGadtIdxTyDecl tc_name)
- -- Check that a newtype has exactly one constructor
+ -- - a newtype has exactly one constructor
; checkTc (new_or_data == DataType || isSingleton k_cons) $
newtypeConError tc_name (length k_cons)
- ; t_typats <- mappM tcHsKindedType k_typats
- ; stupid_theta <- tcHsKindedContext k_ctxt
-
- -- (3) construct representation tycon
- ; rep_tc_name <- newFamInstTyConName tc_name (srcSpanStart loc)
+ -- (4) construct representation tycon
+ ; rep_tc_name <- newFamInstTyConName tc_name loc
; tycon <- fixM (\ tycon -> do
{ data_cons <- mappM (addLocM (tcConDecl unbox_strict tycon t_tvs))
k_cons
case new_or_data of
DataType -> return (mkDataTyConRhs data_cons)
NewType -> ASSERT( isSingleton data_cons )
- mkNewTyConRhs tc_name tycon (head data_cons)
+ mkNewTyConRhs rep_tc_name tycon (head data_cons)
; buildAlgTyCon rep_tc_name t_tvs stupid_theta tc_rhs Recursive
False h98_syntax (Just (family, t_typats))
-- We always assume that indexed types are recursive. Why?
L _ (ConDecl { con_res = ResTyGADT _ }) : _ -> False
other -> True
+-- Check that a type index does not contain any type family applications
+--
+-- * Earlier phases have already checked that there are no foralls in the
+-- type; we also cannot have PredTys and NoteTys are being skipped by using
+-- the core view.
+--
+checkTyFamFreeness :: Type -> TcM ()
+checkTyFamFreeness ty | Just (tycon, tys) <- splitTyConApp_maybe ty
+ = if isSynTyCon tycon
+ then addErr $ tyFamAppInIndexErr ty
+ else mappM_ checkTyFamFreeness tys
+ -- splitTyConApp_maybe uses the core view; hence,
+ -- any synonym tycon must be a family tycon
+
+ | Just (ty1, ty2) <- splitAppTy_maybe ty
+ = checkTyFamFreeness ty1 >> checkTyFamFreeness ty2
+
+ | otherwise -- only vars remaining
+ = return ()
+
+
-- Kind checking of indexed types
-- -
--
-- * Here we check that a type instance matches its kind signature, but we do
-- not check whether there is a pattern for each type index; the latter
--- check is only required for type functions.
+-- check is only required for type synonym instances.
--
kcIdxTyPats :: TyClDecl Name
-> ([LHsTyVarBndr Name] -> [LHsType Name] -> Kind -> TyCon -> TcM a)
use them, whereas for the mutually recursive data types D we bring into
scope kind bindings D -> k, where k is a kind variable, and do inference.
-Indexed Types
+Type families
~~~~~~~~~~~~~
This treatment of type synonyms only applies to Haskell 98-style synonyms.
General type functions can be recursive, and hence, appear in `alg_decls'.
kc_con_details (RecCon fields)
= do { fields' <- mappM kc_field fields; return (RecCon fields') }
- kc_field (HsRecField fld bty d) = do { bty' <- kc_larg_ty bty ; return (HsRecField fld bty' d) }
+ kc_field (ConDeclField fld bty d) = do { bty' <- kc_larg_ty bty
+ ; return (ConDeclField fld bty' d) }
kc_larg_ty bty = case new_or_data of
DataType -> kcHsSigType bty
-- kind checking
= tcTyVarBndrs tvs $ \ tvs' -> do
{ traceTc (text "type family: " <+> ppr tc_name)
- ; idx_tys <- doptM Opt_IndexedTypes
+ ; idx_tys <- doptM Opt_TypeFamilies
- -- Check that we don't use families without -findexed-types
+ -- Check that we don't use families without -ftype-families
; checkTc idx_tys $ badFamInstDecl tc_name
; tycon <- buildSynTyCon tc_name tvs' (OpenSynTyCon kind Nothing) Nothing
-- "newtype family" or "data family" declaration
tcTyClDecl1 _calc_isrec
- (TyFamily {tcdFlavour = DataFamily new_or_data,
+ (TyFamily {tcdFlavour = DataFamily,
tcdLName = L _ tc_name, tcdTyVars = tvs, tcdKind = mb_kind})
= tcTyVarBndrs tvs $ \ tvs' -> do
- { traceTc (text "data/newtype family: " <+> ppr tc_name)
+ { traceTc (text "data family: " <+> ppr tc_name)
; extra_tvs <- tcDataKindSig mb_kind
; let final_tvs = tvs' ++ extra_tvs -- we may not need these
- ; idx_tys <- doptM Opt_IndexedTypes
+ ; idx_tys <- doptM Opt_TypeFamilies
- -- Check that we don't use families without -findexed-types
+ -- Check that we don't use families without -ftype-families
; checkTc idx_tys $ badFamInstDecl tc_name
; tycon <- buildAlgTyCon tc_name final_tvs []
- (case new_or_data of
- DataType -> mkOpenDataTyConRhs
- NewType -> mkOpenNewTyConRhs)
- Recursive False True Nothing
+ mkOpenDataTyConRhs Recursive False True Nothing
; return [ATyCon tycon]
}
; want_generic <- doptM Opt_Generics
; unbox_strict <- doptM Opt_UnboxStrictFields
; gla_exts <- doptM Opt_GlasgowExts
+ ; gadt_ok <- doptM Opt_GADTs
; is_boot <- tcIsHsBoot -- Are we compiling an hs-boot file?
-- Check that we don't use GADT syntax in H98 world
- ; checkTc (gla_exts || h98_syntax) (badGadtDecl tc_name)
+ ; checkTc (gadt_ok || h98_syntax) (badGadtDecl tc_name)
-- Check that we don't use kind signatures without Glasgow extensions
; checkTc (gla_exts || isNothing mb_ksig) (badSigTyDecl tc_name)
InfixCon bty1 bty2 -> tc_datacon True [] [bty1,bty2]
RecCon fields -> tc_datacon False field_names btys
where
- (field_names, btys) = unzip [ (n, t) | HsRecField n t _ <- fields ]
-
+ field_names = map cd_fld_name fields
+ btys = map cd_fld_type fields
}
tcResultType :: TyCon
-- Return type is (T a b c)
; checkTc (null ex_tvs && null theta) (newtypeExError con)
-- No existentials
+ ; checkTc (not (any isMarkedStrict (dataConStrictMarks con)))
+ (newtypeStrictError con)
+ -- No strictness
}
where
(_univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _res_ty) = dataConFullSig con
badGadtDecl tc_name
= vcat [ ptext SLIT("Illegal generalised algebraic data declaration for") <+> quotes (ppr tc_name)
- , nest 2 (parens $ ptext SLIT("Use -fglasgow-exts to allow GADTs")) ]
+ , nest 2 (parens $ ptext SLIT("Use -X=GADT to allow GADTs")) ]
badStupidTheta tc_name
= ptext SLIT("A data type declared in GADT style cannot have a context:") <+> quotes (ppr tc_name)
= sep [ptext SLIT("A newtype constructor cannot have an existential context,"),
nest 2 $ ptext SLIT("but") <+> quotes (ppr con) <+> ptext SLIT("does")]
+newtypeStrictError con
+ = sep [ptext SLIT("A newtype constructor cannot have a strictness annotation,"),
+ nest 2 $ ptext SLIT("but") <+> quotes (ppr con) <+> ptext SLIT("does")]
+
newtypePredError con
= sep [ptext SLIT("A newtype constructor must have a return type of form T a1 ... an"),
nest 2 $ ptext SLIT("but") <+> quotes (ppr con) <+> ptext SLIT("does not")]
badFamInstDecl tc_name
= vcat [ ptext SLIT("Illegal family instance for") <+>
quotes (ppr tc_name)
- , nest 2 (parens $ ptext SLIT("Use -findexed-types to allow indexed type families")) ]
+ , nest 2 (parens $ ptext SLIT("Use -X=TypeFamilies to allow indexed type families")) ]
badGadtIdxTyDecl tc_name
= vcat [ ptext SLIT("Illegal generalised algebraic data declaration for") <+>
ptext SLIT("Wrong category of family instance; declaration was for a") <+>
kindOfFamily
where
- kindOfFamily | isSynTyCon family = ptext SLIT("type synonym")
- | isDataTyCon family = ptext SLIT("data type")
- | isNewTyCon family = ptext SLIT("newtype")
+ kindOfFamily | isSynTyCon family = ptext SLIT("type synonym")
+ | isAlgTyCon family = ptext SLIT("data type")
+ | otherwise = pprPanic "wrongKindOfFamily" (ppr family)
+
+polyTyErr ty
+ = hang (ptext SLIT("Illegal polymorphic type in type instance") <> colon) 4 $
+ ppr ty
+
+tyFamAppInIndexErr ty
+ = hang (ptext SLIT("Illegal type family application in type instance") <>
+ colon) 4 $
+ ppr ty
emptyConDeclsErr tycon
= sep [quotes (ppr tycon) <+> ptext SLIT("has no constructors"),