)
import TcGenDeriv -- Deriv stuff
import InstEnv ( simpleDFunClassTyCon, extendInstEnv )
-import TcHsType ( tcHsPred )
+import TcHsType ( tcHsDeriv )
import TcSimplify ( tcSimplifyDeriv )
import RnBinds ( rnMethodBinds, rnTopBinds )
import RnEnv ( bindLocalNames )
-import TcRnMonad ( thenM, returnM, mapAndUnzipM )
import HscTypes ( DFunId, FixityEnv )
import Class ( className, classArity, classKey, classTyVars, classSCTheta, Class )
-import Subst ( mkTyVarSubst, substTheta )
+import Type ( zipTvSubst, substTheta )
import ErrUtils ( dumpIfSet_dyn )
import MkId ( mkDictFunId )
-import DataCon ( dataConOrigArgTys, isNullaryDataCon, isExistentialDataCon )
+import DataCon ( isNullarySrcDataCon, isVanillaDataCon, dataConOrigArgTys )
import Maybes ( catMaybes )
import RdrName ( RdrName )
import Name ( Name, getSrcLoc )
import NameSet ( NameSet, emptyNameSet, duDefs )
-import Unique ( Unique, getUnique )
import Kind ( splitKindFunTys )
import TyCon ( tyConTyVars, tyConDataCons, tyConArity, tyConHasGenerics,
- tyConTheta, isProductTyCon, isDataTyCon,
+ tyConStupidTheta, isProductTyCon, isDataTyCon, newTyConRhs,
isEnumerationTyCon, isRecursiveTyCon, TyCon
)
-import TcType ( TcType, ThetaType, mkTyVarTy, mkTyVarTys, mkTyConApp,
- getClassPredTys_maybe, tcTyConAppTyCon,
+import TcType ( TcType, ThetaType, mkTyVarTys, mkTyConApp, tcTyConAppTyCon,
isUnLiftedType, mkClassPred, tyVarsOfTypes, isArgTypeKind,
tcEqTypes, tcSplitAppTys, mkAppTys, tcSplitDFunTy )
import Var ( TyVar, tyVarKind, idType, varName )
import VarSet ( mkVarSet, subVarSet )
import PrelNames
import SrcLoc ( srcLocSpan, Located(..) )
-import Util ( zipWithEqual, sortLt, notNull )
+import Util ( zipWithEqual, sortLe, notNull )
import ListSetOps ( removeDups, assocMaybe )
import Outputable
import Bag
gives rise to the constraints for that context -- or at least the thinned
version. So now all classes are "offending".
+[Newtype deriving]
+~~~~~~~~~~~~~~~~~~
+Consider this:
+ class C a b
+ instance C [a] Char
+ newtype T = T Char deriving( C [a] )
+
+Notice the free 'a' in the deriving. We have to fill this out to
+ newtype T = T Char deriving( forall a. C [a] )
+
+And then translate it to:
+ instance C [a] Char => C [a] T where ...
+
+
%************************************************************************
\begin{code}
tcDeriving :: [LTyClDecl Name] -- All type constructors
-> TcM ([InstInfo], -- The generated "instance decls"
- [HsBindGroup Name], -- Extra generated top-level bindings
- NameSet) -- Binders to keep alive
+ [HsBindGroup Name]) -- Extra generated top-level bindings
tcDeriving tycl_decls
- = recoverM (returnM ([], [], emptyNameSet)) $
+ = recoverM (returnM ([], [])) $
do { -- Fish the "deriving"-related information out of the TcEnv
-- and make the necessary "equations".
; (ordinary_eqns, newtype_inst_info) <- makeDerivEqns tycl_decls
-- Rename these extra bindings, discarding warnings about unused bindings etc
-- Set -fglasgow exts so that we can have type signatures in patterns,
-- which is used in the generic binds
- ; (rn_binds, gen_bndrs)
+ ; rn_binds
<- discardWarnings $ setOptM Opt_GlasgowExts $ do
{ (rn_deriv, _dus1) <- rnTopBinds deriv_binds []
; (rn_gen, dus_gen) <- rnTopBinds gen_binds []
- ; return (rn_deriv ++ rn_gen, duDefs dus_gen) }
+ ; keepAliveSetTc (duDefs dus_gen) -- Mark these guys to
+ -- be kept alive
+ ; return (rn_deriv ++ rn_gen) }
; dflags <- getDOpts
; ioToTcRn (dumpIfSet_dyn dflags Opt_D_dump_deriv "Derived instances"
(ddump_deriving inst_info rn_binds))
- ; returnM (inst_info, rn_binds, gen_bndrs)
+ ; returnM (inst_info, rn_binds)
}
where
ddump_deriving :: [InstInfo] -> [HsBindGroup Name] -> SDoc
-----------------------------------------
deriveOrdinaryStuff [] -- Short cut
- = returnM ([], emptyBag)
+ = returnM ([], emptyLHsBinds)
deriveOrdinaryStuff eqns
= do { -- Take the equation list and solve it, to deliver a list of
returnM (catMaybes maybe_ordinaries, catMaybes maybe_newtypes)
where
------------------------------------------------------------------
- derive_these :: [(NewOrData, Name, LHsPred Name)]
+ derive_these :: [(NewOrData, Name, LHsType Name)]
-- Find the (nd, TyCon, Pred) pairs that must be `derived'
derive_these = [ (nd, tycon, pred)
| L _ (TyData { tcdND = nd, tcdLName = L _ tycon,
- tcdDerivs = Just (L _ preds) }) <- tycl_decls,
+ tcdDerivs = Just preds }) <- tycl_decls,
pred <- preds ]
------------------------------------------------------------------
- mk_eqn :: (NewOrData, Name, LHsPred Name) -> TcM (Maybe DerivEqn, Maybe InstInfo)
+ mk_eqn :: (NewOrData, Name, LHsType Name) -> TcM (Maybe DerivEqn, Maybe InstInfo)
-- We swizzle the tyvars and datacons out of the tycon
-- to make the rest of the equation
+ --
+ -- The "deriv_ty" is a LHsType to take account of the fact that for newtype derivign
+ -- we allow deriving (forall a. C [a]).
- mk_eqn (new_or_data, tycon_name, pred)
+ mk_eqn (new_or_data, tycon_name, hs_deriv_ty)
= tcLookupTyCon tycon_name `thenM` \ tycon ->
- addSrcSpan (srcLocSpan (getSrcLoc tycon)) $
+ setSrcSpan (srcLocSpan (getSrcLoc tycon)) $
addErrCtxt (derivCtxt Nothing tycon) $
tcExtendTyVarEnv (tyConTyVars tycon) $ -- Deriving preds may (now) mention
-- the type variables for the type constructor
- tcHsPred pred `thenM` \ pred' ->
- case getClassPredTys_maybe pred' of
- Nothing -> bale_out (malformedPredErr tycon pred)
- Just (clas, tys) -> doptM Opt_GlasgowExts `thenM` \ gla_exts ->
- mk_eqn_help gla_exts new_or_data tycon clas tys
+ tcHsDeriv hs_deriv_ty `thenM` \ (deriv_tvs, clas, tys) ->
+ doptM Opt_GlasgowExts `thenM` \ gla_exts ->
+ mk_eqn_help gla_exts new_or_data tycon deriv_tvs clas tys
------------------------------------------------------------------
- mk_eqn_help gla_exts DataType tycon clas tys
- | Just err <- checkSideConditions gla_exts clas tycon tys
+ mk_eqn_help gla_exts DataType tycon deriv_tvs clas tys
+ | Just err <- checkSideConditions gla_exts tycon deriv_tvs clas tys
= bale_out (derivingThingErr clas tys tycon (tyConTyVars tycon) err)
| otherwise
= do { eqn <- mkDataTypeEqn tycon clas
; returnM (Just eqn, Nothing) }
- mk_eqn_help gla_exts NewType tycon clas tys
+ mk_eqn_help gla_exts NewType tycon deriv_tvs clas tys
| can_derive_via_isomorphism && (gla_exts || std_class_via_iso clas)
= -- Go ahead and use the isomorphism
traceTc (text "newtype deriving:" <+> ppr tycon <+> ppr rep_tys) `thenM_`
returnM (Nothing, Just (InstInfo { iDFunId = mk_dfun dfun_name,
iBinds = NewTypeDerived rep_tys }))
| std_class gla_exts clas
- = mk_eqn_help gla_exts DataType tycon clas tys -- Go via bale-out route
+ = mk_eqn_help gla_exts DataType tycon deriv_tvs clas tys -- Go via bale-out route
| otherwise -- Non-standard instance
= bale_out (if gla_exts then
where
-- Here is the plan for newtype derivings. We see
-- newtype T a1...an = T (t ak...an) deriving (.., C s1 .. sm, ...)
- -- where aj...an do not occur free in t, and the (C s1 ... sm) is a
- -- *partial applications* of class C with the last parameter missing
+ -- where t is a type,
+ -- ak...an is a suffix of a1..an
+ -- ak...an do not occur free in t,
+ -- (C s1 ... sm) is a *partial applications* of class C
+ -- with the last parameter missing
--
-- We generate the instances
- -- instance C s1 .. sm (t ak...aj) => C s1 .. sm (T a1...aj)
- -- where T a1...aj is the partial application of the LHS of the correct kind
+ -- instance C s1 .. sm (t ak...ap) => C s1 .. sm (T a1...ap)
+ -- where T a1...ap is the partial application of the LHS of the correct kind
+ -- and p >= k
--
-- Running example: newtype T s a = MkT (ST s a) deriving( Monad )
-- instance Monad (ST s) => Monad (T s) where
-- fail = coerce ... (fail @ ST s)
+ -- (Actually we don't need the coerce, because non-rec newtypes are transparent
clas_tyvars = classTyVars clas
kind = tyVarKind (last clas_tyvars)
-- to get instance Monad (ST s) => Monad (T s)
-- Note [newtype representation]
- -- We must not use newTyConRep to get the representation
- -- type, because that looks through all intermediate newtypes
- -- To get the RHS of *this* newtype, just look at the data
- -- constructor. For example
+ -- Need newTyConRhs *not* newTyConRep to get the representation
+ -- type, because the latter looks through all intermediate newtypes
+ -- For example
-- newtype B = MkB Int
-- newtype A = MkA B deriving( Num )
-- We want the Num instance of B, *not* the Num instance of Int,
-- when making the Num instance of A!
- tyvars = tyConTyVars tycon
- rep_ty = head (dataConOrigArgTys (head (tyConDataCons tycon)))
+ (tc_tvs, rep_ty) = newTyConRhs tycon
(rep_fn, rep_ty_args) = tcSplitAppTys rep_ty
n_tyvars_to_keep = tyConArity tycon - n_args_to_drop
- tyvars_to_drop = drop n_tyvars_to_keep tyvars
- tyvars_to_keep = take n_tyvars_to_keep tyvars
+ tyvars_to_drop = drop n_tyvars_to_keep tc_tvs
+ tyvars_to_keep = take n_tyvars_to_keep tc_tvs
n_args_to_keep = length rep_ty_args - n_args_to_drop
args_to_drop = drop n_args_to_keep rep_ty_args
-- There's no 'corece' needed because after the type checker newtypes
-- are transparent.
- sc_theta = substTheta (mkTyVarSubst clas_tyvars inst_tys)
+ sc_theta = substTheta (zipTvSubst clas_tyvars inst_tys)
(classSCTheta clas)
-- If there are no tyvars, there's no need
-- to abstract over the dictionaries we need
- dict_args | null tyvars = []
- | otherwise = rep_pred : sc_theta
+ dict_tvs = deriv_tvs ++ tc_tvs
+ dict_args | null dict_tvs = []
+ | otherwise = rep_pred : sc_theta
-- Finally! Here's where we build the dictionary Id
- mk_dfun dfun_name = mkDictFunId dfun_name tyvars dict_args clas inst_tys
+ mk_dfun dfun_name = mkDictFunId dfun_name dict_tvs dict_args clas inst_tys
-------------------------------------------------------------------
-- Figuring out whether we can only do this newtype-deriving thing
-- newtype A = MkA [A]
-- Don't want
-- instance Eq [A] => Eq A !!
-
-- Here's a recursive newtype that's actually OK
-- newtype S1 = S1 [T1 ()]
-- newtype T1 a = T1 (StateT S1 IO a ) deriving( Monad )
-- It's currently rejected. Oh well.
+ -- In fact we generate an instance decl that has method of form
+ -- meth @ instTy = meth @ repTy
+ -- (no coerce's). We'd need a coerce if we wanted to handle
+ -- recursive newtypes too
-- Check that eta reduction is OK
-- (a) the dropped-off args are identical
-- data T a b = ... deriving( Typeable )
-- gives
-- instance Typeable2 T where ...
+ -- Notice that:
-- 1. There are no constraints in the instance
-- 2. There are no type variables either
- -- 2. The actual class we want to generate isn't necessarily
+ -- 3. The actual class we want to generate isn't necessarily
-- Typeable; it depends on the arity of the type
do { real_clas <- tcLookupClass (typeableClassNames !! tyConArity tycon)
; dfun_name <- new_dfun_name real_clas tycon
where
tyvars = tyConTyVars tycon
constraints = extra_constraints ++ ordinary_constraints
- extra_constraints = tyConTheta tycon
+ extra_constraints = tyConStupidTheta tycon
-- "extra_constraints": see note [Data decl contexts] above
ordinary_constraints
= [ mkClassPred clas [arg_ty]
| data_con <- tyConDataCons tycon,
arg_ty <- dataConOrigArgTys data_con,
- -- Use the same type variables
- -- as the type constructor,
- -- hence no need to instantiate
not (isUnLiftedType arg_ty) -- No constraints for unlifted types?
]
-- Check side conditions that dis-allow derivability for particular classes
-- This is *apart* from the newtype-deriving mechanism
-checkSideConditions :: Bool -> Class -> TyCon -> [TcType] -> Maybe SDoc
-checkSideConditions gla_exts clas tycon tys
- | notNull tys
+checkSideConditions :: Bool -> TyCon -> [TyVar] -> Class -> [TcType] -> Maybe SDoc
+checkSideConditions gla_exts tycon deriv_tvs clas tys
+ | notNull deriv_tvs || notNull tys
= Just ty_args_why -- e.g. deriving( Foo s )
| otherwise
= case [cond | (key,cond) <- sideConditions, key == getUnique clas] of
[cond] -> cond (gla_exts, tycon)
other -> pprPanic "checkSideConditions" (ppr clas)
where
- ty_args_why = quotes (ppr (mkClassPred clas tys)) <+> ptext SLIT("is not a class")
+ ty_args_why = quotes (ppr (mkClassPred clas tys)) <+> ptext SLIT("is not a class")
non_std_why clas = quotes (ppr clas) <+> ptext SLIT("is not a derivable class")
(enumClassKey, cond_std `andCond` cond_isEnumeration),
(ixClassKey, cond_std `andCond` (cond_isEnumeration `orCond` cond_isProduct)),
(boundedClassKey, cond_std `andCond` (cond_isEnumeration `orCond` cond_isProduct)),
- (typeableClassKey, cond_glaExts `andCond` cond_allTypeKind),
+ (typeableClassKey, cond_glaExts `andCond` cond_typeableOK),
(dataClassKey, cond_glaExts `andCond` cond_std)
]
cond_std :: Condition
cond_std (gla_exts, tycon)
- | any isExistentialDataCon data_cons = Just existential_why
- | null data_cons = Just no_cons_why
- | otherwise = Nothing
+ | any (not . isVanillaDataCon) data_cons = Just existential_why
+ | null data_cons = Just no_cons_why
+ | otherwise = Nothing
where
data_cons = tyConDataCons tycon
no_cons_why = quotes (ppr tycon) <+> ptext SLIT("has no data constructors")
where
why = quotes (ppr tycon) <+> ptext SLIT("has more than one constructor")
-cond_allTypeKind :: Condition
-cond_allTypeKind (gla_exts, tycon)
- | all (isArgTypeKind . tyVarKind) (tyConTyVars tycon) = Nothing
- | otherwise = Just why
+cond_typeableOK :: Condition
+-- OK for Typeable class
+-- Currently: (a) args all of kind *
+-- (b) 7 or fewer args
+cond_typeableOK (gla_exts, tycon)
+ | tyConArity tycon > 7 = Just too_many
+ | not (all (isArgTypeKind . tyVarKind) (tyConTyVars tycon)) = Just bad_kind
+ | otherwise = Nothing
where
- why = quotes (ppr tycon) <+> ptext SLIT("is parameterised over arguments of kind other than `*'")
+ too_many = quotes (ppr tycon) <+> ptext SLIT("has too many arguments")
+ bad_kind = quotes (ppr tycon) <+> ptext SLIT("has arguments of kind other than `*'")
cond_glaExts :: Condition
cond_glaExts (gla_exts, tycon) | gla_exts = Nothing
------------------------------------------------------------------
gen_soln (_, clas, tc,tyvars,deriv_rhs)
- = addSrcSpan (srcLocSpan (getSrcLoc tc)) $
+ = setSrcSpan (srcLocSpan (getSrcLoc tc)) $
addErrCtxt (derivCtxt (Just clas) tc) $
tcSimplifyDeriv tyvars deriv_rhs `thenM` \ theta ->
- returnM (sortLt (<) theta) -- Canonicalise before returning the soluction
+ returnM (sortLe (<=) theta) -- Canonicalise before returning the soluction
mk_deriv_dfun (dfun_name, clas, tycon, tyvars, _) theta
= mkDictFunId dfun_name tyvars theta
genDerivBinds clas fix_env tycon
| className clas `elem` typeableClassNames
- = (gen_Typeable_binds tycon, emptyBag)
+ = (gen_Typeable_binds tycon, emptyLHsBinds)
| otherwise
= case assocMaybe gen_list (getUnique clas) of
-- no_aux_binds is used for generators that don't
-- need to produce any auxiliary bindings
- no_aux_binds f fix_env tc = (f fix_env tc, emptyBag)
+ no_aux_binds f fix_env tc = (f fix_env tc, emptyLHsBinds)
ignore_fix_env f fix_env tc = f tc
\end{code}
do_con2tag acc_Names tycon
| isDataTyCon tycon &&
((we_are_deriving eqClassKey tycon
- && any isNullaryDataCon (tyConDataCons tycon))
+ && any isNullarySrcDataCon (tyConDataCons tycon))
|| (we_are_deriving ordClassKey tycon
&& not (isProductTyCon tycon))
|| (we_are_deriving enumClassKey tycon)
where
pred = mkClassPred clas (tys ++ [mkTyConApp tycon (mkTyVarTys tyvars)])
-malformedPredErr tycon pred = ptext SLIT("Illegal deriving item") <+> ppr pred
-
derivCtxt :: Maybe Class -> TyCon -> SDoc
derivCtxt maybe_cls tycon
= ptext SLIT("When deriving") <+> cls <+> ptext SLIT("for type") <+> quotes (ppr tycon)