\section[TcClassDcl]{Typechecking class declarations}
\begin{code}
-module TcClassDcl ( tcClassDecl1, tcClassDecls2, mkImplicitClassBinds,
+module TcClassDcl ( tcClassDecl1, tcClassDecls2,
tcMethodBind, badMethodErr
) where
#include "HsVersions.h"
-import HsSyn ( HsDecl(..), TyClDecl(..), Sig(..), MonoBinds(..),
- HsExpr(..), HsLit(..), HsType(..), HsPred(..),
+import HsSyn ( TyClDecl(..), Sig(..), MonoBinds(..),
+ HsExpr(..), HsLit(..), HsType(..), HsPred(..),
mkSimpleMatch, andMonoBinds, andMonoBindList,
isClassDecl, isClassOpSig, isPragSig,
getClassDeclSysNames, tyClDeclName
import BasicTypes ( TopLevelFlag(..), RecFlag(..) )
import RnHsSyn ( RenamedTyClDecl,
RenamedClassOpSig, RenamedMonoBinds,
- RenamedContext, RenamedHsDecl, RenamedSig,
+ RenamedContext, RenamedSig,
maybeGenericMatch
)
-import TcHsSyn ( TcMonoBinds, idsToMonoBinds )
+import TcHsSyn ( TcMonoBinds )
import Inst ( InstOrigin(..), LIE, emptyLIE, plusLIE, plusLIEs,
newDicts, newMethod )
-import TcEnv ( TcId, TcEnv, TyThingDetails(..), tcAddImportedIdInfo,
+import TcEnv ( TcId, TcEnv, RecTcEnv, TyThingDetails(..), tcAddImportedIdInfo,
tcLookupClass, tcExtendTyVarEnvForMeths, tcExtendGlobalTyVars,
tcExtendLocalValEnv, tcExtendTyVarEnv, newDefaultMethodName
)
import TcBinds ( tcBindWithSigs, tcSpecSigs )
-import TcMonoType ( tcHsSigType, tcClassContext, checkSigTyVars, checkAmbiguity, sigCtxt, mkTcSig )
+import TcMonoType ( tcHsRecType, tcRecClassContext, checkSigTyVars, checkAmbiguity, sigCtxt, mkTcSig )
import TcSimplify ( tcSimplifyAndCheck, bindInstsOfLocalFuns )
import TcType ( TcType, TcTyVar, tcInstTyVars, zonkTcSigTyVars )
import TcMonad
import Generics ( mkGenericRhs, validGenericMethodType )
import PrelInfo ( nO_METHOD_BINDING_ERROR_ID )
-import Class ( classTyVars, classBigSig, classSelIds, classTyCon,
+import Class ( classTyVars, classBigSig, classTyCon,
Class, ClassOpItem, DefMeth (..) )
import MkId ( mkDictSelId, mkDataConId, mkDataConWrapId, mkDefaultMethodId )
import DataCon ( mkDataCon, notMarkedStrict )
import Id ( Id, idType, idName )
-import Name ( Name, isLocallyDefined, NamedThing(..),
- NameEnv, lookupNameEnv, emptyNameEnv, unitNameEnv,
- plusNameEnv, nameEnvElts )
+import Module ( Module )
+import Name ( Name, NamedThing(..), isFrom )
+import Name ( NameEnv, lookupNameEnv, emptyNameEnv, unitNameEnv, plusNameEnv, nameEnvElts )
import NameSet ( emptyNameSet )
import Outputable
-import Type ( Type, ClassContext, mkTyVarTys, mkDictTys, mkSigmaTy, mkClassPred,
+import Type ( Type, ClassContext, mkTyVarTys, mkDictTys, mkClassPred,
splitTyConApp_maybe, isTyVarTy
)
import Var ( TyVar )
%************************************************************************
\begin{code}
-tcClassDecl1 :: TcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
-tcClassDecl1 rec_env
+
+tcClassDecl1 :: RecFlag -> RecTcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
+tcClassDecl1 is_rec rec_env
(ClassDecl context class_name
tyvar_names fundeps class_sigs def_methods
sys_names src_loc)
-- LOOK THINGS UP IN THE ENVIRONMENT
tcLookupClass class_name `thenTc` \ clas ->
let
- (tyvars, fds) = classTvsFds clas
+ tyvars = classTyVars clas
op_sigs = filter isClassOpSig class_sigs
op_names = [n | ClassOpSig n _ _ _ <- op_sigs]
(_, datacon_name, datacon_wkr_name, sc_sel_names) = getClassDeclSysNames sys_names
checkGenericClassIsUnary clas dm_info `thenTc_`
-- CHECK THE CONTEXT
- tcSuperClasses clas context sc_sel_names `thenTc` \ (sc_theta, sc_sel_ids) ->
+ tcSuperClasses is_rec clas context sc_sel_names `thenTc` \ (sc_theta, sc_sel_ids) ->
-- CHECK THE CLASS SIGNATURES,
- mapTc (tcClassSig rec_env tyvar_names clas tyvars fds dm_info)
- op_sigs `thenTc` \ sig_stuff ->
+ mapTc (tcClassSig is_rec rec_env clas tyvars dm_info) op_sigs `thenTc` \ sig_stuff ->
-- MAKE THE CLASS DETAILS
let
\begin{code}
-tcSuperClasses :: Class
+tcSuperClasses :: RecFlag -> Class
-> RenamedContext -- class context
-> [Name] -- Names for superclass selectors
-> TcM (ClassContext, -- the superclass context
[Id]) -- superclass selector Ids
-tcSuperClasses clas context sc_sel_names
+tcSuperClasses is_rec clas context sc_sel_names
= -- Check the context.
-- The renamer has already checked that the context mentions
-- only the type variable of the class decl.
) `thenTc_`
-- Context is already kind-checked
- tcClassContext context `thenTc` \ sc_theta ->
+ tcRecClassContext is_rec context `thenTc` \ sc_theta ->
let
sc_sel_ids = [mkDictSelId sc_name clas | sc_name <- sc_sel_names]
in
is_tyvar other = False
-tcClassSig :: TcEnv -- Knot tying only!
- -> [HsTyVarBndr Name] -- From the declaration, for error messages
+tcClassSig :: RecFlag -> RecTcEnv -- Knot tying only!
-> Class -- ...ditto...
-> [TyVar] -- The class type variable, used for error check only
- -> [FunDep TyVar]
-> NameEnv (DefMeth Name) -- Info about default methods
-> RenamedClassOpSig
-> TcM (Type, -- Type of the method
-- so we distinguish them in checkDefaultBinds, and pass this knowledge in the
-- Class.DefMeth data structure.
-tcClassSig rec_env tyvar_names clas clas_tyvars fds dm_info
+tcClassSig is_rec unf_env clas clas_tyvars dm_info
(ClassOpSig op_name maybe_dm op_ty src_loc)
= tcAddSrcLoc src_loc $
-- Check the type signature. NB that the envt *already has*
-- bindings for the type variables; see comments in TcTyAndClassDcls.
- tcHsSigType op_ty `thenTc` \ local_ty ->
+ tcHsRecType is_rec op_ty `thenTc` \ local_ty ->
+
+ -- Check for ambiguous class op types
let
- theta = [mkClassPred clas (mkTyVarTys clas_tyvars)]
- global_ty = mkSigmaTy clas_tyvars theta local_ty
+ theta = [mkClassPred clas (mkTyVarTys clas_tyvars)]
+ in
+ checkAmbiguity is_rec True clas_tyvars theta local_ty `thenTc` \ global_ty ->
+ -- The default method's type should really come from the
+ -- iface file, since it could be usage-generalised, but this
+ -- requires altering the mess of knots in TcModule and I'm
+ -- too scared to do that. Instead, I have disabled generalisation
+ -- of types of default methods (and dict funs) by annotating them
+ -- TyGenNever (in MkId). Ugh! KSW 1999-09.
+ let
-- Build the selector id and default method id
sel_id = mkDictSelId op_name clas
dm_info_id = case dm_info_name of
NoDefMeth -> NoDefMeth
GenDefMeth -> GenDefMeth
- DefMeth dm_name -> DefMeth (tcAddImportedIdInfo rec_env dm_id)
+ DefMeth dm_name -> DefMeth (tcAddImportedIdInfo unf_env dm_id)
where
dm_id = mkDefaultMethodId dm_name clas global_ty
-
- full_hs_ty = HsForAllTy (Just tyvar_names) op_ty
in
- -- Check for ambiguous class op types
- checkAmbiguity full_ty clas_tyvars theta local_ty `thenRn_`
-
-- Check that for a generic method, the type of
-- the method is sufficiently simple
checkTc (dm_info_name /= GenDefMeth || validGenericMethodType local_ty)
%************************************************************************
%* *
-\subsection[ClassDcl-pass2]{Class decls pass 2: default methods}
-%* *
-%************************************************************************
-
-@mkImplicitClassBinds@ produces a binding for the selector function for each method
-and superclass dictionary.
-
-\begin{code}
-mkImplicitClassBinds :: [Class] -> NF_TcM ([Id], TcMonoBinds)
-mkImplicitClassBinds classes
- = returnNF_Tc (concat cls_ids_s, andMonoBindList binds_s)
- -- The selector binds are already in the selector Id's unfoldings
- -- We don't return the data constructor etc from the class,
- -- because that's done via the class's TyCon
- where
- (cls_ids_s, binds_s) = unzip (map mk_implicit classes)
-
- mk_implicit clas = (sel_ids, binds)
- where
- sel_ids = classSelIds clas
- binds | isLocallyDefined clas = idsToMonoBinds sel_ids
- | otherwise = EmptyMonoBinds
-\end{code}
-
-
-
-%************************************************************************
-%* *
\subsection[Default methods]{Default methods}
%* *
%************************************************************************
each local class decl.
\begin{code}
-tcClassDecls2 :: [RenamedHsDecl] -> NF_TcM (LIE, TcMonoBinds)
+tcClassDecls2 :: Module -> [RenamedTyClDecl] -> NF_TcM (LIE, TcMonoBinds)
-tcClassDecls2 decls
+tcClassDecls2 this_mod decls
= foldr combine
(returnNF_Tc (emptyLIE, EmptyMonoBinds))
- [tcClassDecl2 cls_decl | TyClD cls_decl <- decls,
+ [tcClassDecl2 cls_decl | cls_decl <- decls,
isClassDecl cls_decl,
- isLocallyDefined (tyClDeclName cls_decl)]
+ isFrom this_mod (tyClDeclName cls_decl)]
where
combine tc1 tc2 = tc1 `thenNF_Tc` \ (lie1, binds1) ->
tc2 `thenNF_Tc` \ (lie2, binds2) ->