%
+% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-\section[TcInstDecls]{Typechecking instance declarations}
+
+TcInstDecls: Typechecking instance declarations
\begin{code}
module TcInstDcls ( tcInstDecls1, tcInstDecls2 ) where
#include "HsVersions.h"
import HsSyn
-import TcBinds ( mkPragFun, tcPrags, badBootDeclErr )
-import TcTyClsDecls ( tcIdxTyInstDecl )
-import TcClassDcl ( tcMethodBind, mkMethodBind, badMethodErr, badATErr,
- omittedATWarn, tcClassDecl2, getGenericInstances )
+import TcBinds
+import TcTyClsDecls
+import TcClassDcl
import TcRnMonad
-import TcMType ( tcSkolSigType, checkValidInstance,
- checkValidInstHead )
-import TcType ( TcType, mkClassPred, tcSplitSigmaTy,
- tcSplitDFunHead, SkolemInfo(InstSkol),
- tcSplitTyConApp,
- tcSplitDFunTy, mkFunTy )
-import Inst ( newDictBndr, newDictBndrs, instToId, showLIE,
- getOverlapFlag, tcExtendLocalInstEnv )
-import InstEnv ( mkLocalInstance, instanceDFunId )
-import FamInst ( tcExtendLocalFamInstEnv )
-import FamInstEnv ( extractFamInsts )
-import TcDeriv ( tcDeriving )
-import TcEnv ( InstInfo(..), InstBindings(..),
- newDFunName, tcExtendIdEnv, tcExtendGlobalEnv
- )
-import TcHsType ( kcHsSigType, tcHsKindedType )
-import TcUnify ( checkSigTyVars )
-import TcSimplify ( tcSimplifySuperClasses )
-import Type ( zipOpenTvSubst, substTheta, mkTyConApp, mkTyVarTy,
- TyThing(ATyCon), isTyVarTy, tcEqType,
- substTys, emptyTvSubst, extendTvSubst )
-import Coercion ( mkSymCoercion )
-import TyCon ( TyCon, tyConName, newTyConCo_maybe, tyConTyVars,
- isTyConAssoc, tyConFamInst_maybe, tyConDataCons,
- assocTyConArgPoss_maybe )
-import DataCon ( classDataCon, dataConInstArgTys )
-import Class ( Class, classTyCon, classBigSig, classATs )
-import Var ( TyVar, Id, idName, idType, tyVarName )
-import MkId ( mkDictFunId )
-import Name ( Name, getSrcLoc, nameOccName )
-import NameSet ( addListToNameSet, emptyNameSet, minusNameSet,
- nameSetToList )
-import Maybe ( fromJust, catMaybes )
-import Monad ( when )
-import List ( find )
-import DynFlags ( DynFlag(Opt_WarnMissingMethods) )
-import SrcLoc ( srcLocSpan, unLoc, noLoc, Located(..), srcSpanStart,
- getLoc)
-import ListSetOps ( minusList )
-import Util ( snocView, dropList )
+import TcMType
+import TcType
+import Inst
+import InstEnv
+import FamInst
+import FamInstEnv
+import TcDeriv
+import TcEnv
+import TcHsType
+import TcUnify
+import TcSimplify
+import Type
+import Coercion
+import TyCon
+import DataCon
+import Class
+import Var
+import MkId
+import Name
+import NameSet
+import DynFlags
+import SrcLoc
+import ListSetOps
+import Util
import Outputable
import Bag
-import BasicTypes ( Activation( AlwaysActive ), InlineSpec(..) )
-import HscTypes ( implicitTyThings )
+import BasicTypes
+import HscTypes
import FastString
+
+import Data.Maybe
+import Control.Monad hiding (zipWithM_, mapAndUnzipM)
+import Data.List
\end{code}
Typechecking instance declarations is done in two passes. The first
tcInstDecls1 -- Deal with both source-code and imported instance decls
:: [LTyClDecl Name] -- For deriving stuff
-> [LInstDecl Name] -- Source code instance decls
+ -> [LDerivDecl Name] -- Source code stand-alone deriving decls
-> TcM (TcGblEnv, -- The full inst env
[InstInfo], -- Source-code instance decls to process;
-- contains all dfuns for this module
HsValBinds Name) -- Supporting bindings for derived instances
-tcInstDecls1 tycl_decls inst_decls
+tcInstDecls1 tycl_decls inst_decls deriv_decls
= checkNoErrs $
do { -- Stop if addInstInfos etc discovers any errors
-- (they recover, so that we get more than one error each
-- round)
- -- (1) Do class instance declarations and instances of indexed
- -- types
- ; let { idxty_decls = filter (isIdxTyDecl . unLoc) tycl_decls }
+ -- (1) Do class and family instance declarations
+ ; let { idxty_decls = filter (isFamInstDecl . unLoc) tycl_decls }
; local_info_tycons <- mappM tcLocalInstDecl1 inst_decls
; idx_tycons <- mappM tcIdxTyInstDeclTL idxty_decls
-- (4) Compute instances from "deriving" clauses;
-- This stuff computes a context for the derived instance
-- decl, so it needs to know about all the instances possible
- ; (deriv_inst_info, deriv_binds) <- tcDeriving tycl_decls
+ ; (deriv_inst_info, deriv_binds) <- tcDeriving tycl_decls deriv_decls
; addInsts deriv_inst_info $ do {
; gbl_env <- getGblEnv
-- !!!TODO: Need to perform this check for the TyThing of type functions,
-- too.
tcIdxTyInstDeclTL ldecl@(L loc decl) =
- do { tything <- tcIdxTyInstDecl ldecl
+ do { tything <- tcFamInstDecl ldecl
; setSrcSpan loc $
when (isAssocFamily tything) $
addErr $ assocInClassErr (tcdName decl)
addFamInsts :: [TyThing] -> TcM a -> TcM a
addFamInsts tycons thing_inside
- = tcExtendLocalFamInstEnv (extractFamInsts tycons) thing_inside
-\end{code}
+ = tcExtendLocalFamInstEnv (map mkLocalFamInstTyThing tycons) thing_inside
+ where
+ mkLocalFamInstTyThing (ATyCon tycon) = mkLocalFamInst tycon
+ mkLocalFamInstTyThing tything = pprPanic "TcInstDcls.addFamInsts"
+ (ppr tything)
+\end{code}
\begin{code}
tcLocalInstDecl1 :: LInstDecl Name
; checkTc (not is_boot || (isEmptyLHsBinds binds && null uprags))
badBootDeclErr
- -- Typecheck the instance type itself. We can't use
- -- tcHsSigType, because it's not a valid user type.
- ; kinded_ty <- kcHsSigType poly_ty
- ; poly_ty' <- tcHsKindedType kinded_ty
- ; let (tyvars, theta, tau) = tcSplitSigmaTy poly_ty'
+ ; (tyvars, theta, tau) <- tcHsInstHead poly_ty
-- Next, process any associated types.
- ; idx_tycons <- mappM tcIdxTyInstDecl ats
+ ; idx_tycons <- mappM tcFamInstDecl ats
-- Now, check the validity of the instance.
; (clas, inst_tys) <- checkValidInstHead tau
checkValidAndMissingATs clas inst_tys ats
= do { -- Issue a warning for each class AT that is not defined in this
-- instance.
- ; let classDefATs = listToNameSet . map tyConName . classATs $ clas
- definedATs = listToNameSet . map (tcdName.unLoc.fst) $ ats
- omitted = classDefATs `minusNameSet` definedATs
+ ; let class_ats = map tyConName (classATs clas)
+ defined_ats = listToNameSet . map (tcdName.unLoc.fst) $ ats
+ omitted = filterOut (`elemNameSet` defined_ats) class_ats
; warn <- doptM Opt_WarnMissingMethods
- ; mapM_ (warnTc warn . omittedATWarn) (nameSetToList omitted)
+ ; mapM_ (warnTc warn . omittedATWarn) omitted
-- Ensure that all AT indexes that correspond to class parameters
-- coincide with the types in the instance head. All remaining
tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = NewTypeDerived mb_preds })
= do { let dfun_id = instanceDFunId ispec
- rigid_info = InstSkol dfun_id
+ rigid_info = InstSkol
origin = SigOrigin rigid_info
inst_ty = idType dfun_id
; (tvs, theta, inst_head_ty) <- tcSkolSigType rigid_info inst_ty
; let (cls, cls_inst_tys) = tcSplitDFunHead inst_head_ty
cls_tycon = classTyCon cls
the_coercion = make_coercion cls_tycon cls_inst_tys
- coerced_rep_dict = mkHsCoerce the_coercion (HsVar rep_dict_id)
+ coerced_rep_dict = mkHsWrap the_coercion (HsVar rep_dict_id)
; body <- make_body cls_tycon cls_inst_tys sc_dict_ids coerced_rep_dict
- ; return (sc_binds `snocBag` (noLoc $ VarBind dfun_id $ noLoc $ mkHsCoerce wrap_fn body)) }
+ ; return (sc_binds `snocBag` (noLoc $ VarBind dfun_id $ noLoc $ mkHsWrap wrap_fn body)) }
where
-----------------------
make_wrapper inst_loc tvs theta (Just preds) -- Case (a)
= ASSERT( null tvs && null theta )
do { dicts <- newDictBndrs inst_loc preds
- ; sc_binds <- addErrCtxt superClassCtxt (tcSimplifySuperClasses [] [] dicts)
+ ; sc_binds <- addErrCtxt superClassCtxt $
+ tcSimplifySuperClasses inst_loc [] dicts
-- Use tcSimplifySuperClasses to avoid creating loops, for the
-- same reason as Note [SUPERCLASS-LOOP 1] in TcSimplify
- ; return (map instToId dicts, idCoercion, sc_binds) }
+ ; return (map instToId dicts, idHsWrapper, sc_binds) }
make_wrapper inst_loc tvs theta Nothing -- Case (b)
= do { dicts <- newDictBndrs inst_loc theta
; let dict_ids = map instToId dicts
- ; return (dict_ids, mkCoTyLams tvs <.> mkCoLams dict_ids, emptyBag) }
+ ; return (dict_ids, mkWpTyLams tvs <.> mkWpLams dict_ids, emptyBag) }
-----------------------
-- make_coercion
, (tycon, tc_args) <- tcSplitTyConApp last_ty -- Should not fail
, Just co_con <- newTyConCo_maybe tycon
, let co = mkSymCoercion (mkTyConApp co_con tc_args)
- = ExprCoFn (mkTyConApp cls_tycon (all_tys_but_last ++ [co]))
+ = WpCo (mkTyConApp cls_tycon (all_tys_but_last ++ [co]))
| otherwise -- The newtype is transparent; no need for a cast
- = idCoercion
+ = idHsWrapper
-----------------------
-- make_body
tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = VanillaInst monobinds uprags })
= let
dfun_id = instanceDFunId ispec
- rigid_info = InstSkol dfun_id
+ rigid_info = InstSkol
inst_ty = idType dfun_id
in
-- Prime error recovery
newDictBndrs sc_loc sc_theta' `thenM` \ sc_dicts ->
getInstLoc origin `thenM` \ inst_loc ->
newDictBndrs inst_loc dfun_theta' `thenM` \ dfun_arg_dicts ->
- newDictBndr inst_loc (mkClassPred clas inst_tys') `thenM` \ this_dict ->
+ newDictBndr inst_loc (mkClassPred clas inst_tys') `thenM` \ this_dict ->
-- Default-method Ids may be mentioned in synthesised RHSs,
-- but they'll already be in the environment.
-- Don't include this_dict in the 'givens', else
-- sc_dicts get bound by just selecting from this_dict!!
addErrCtxt superClassCtxt
- (tcSimplifySuperClasses inst_tyvars'
- dfun_arg_dicts
- sc_dicts) `thenM` \ sc_binds ->
+ (tcSimplifySuperClasses inst_loc
+ dfun_arg_dicts sc_dicts) `thenM` \ sc_binds ->
-- It's possible that the superclass stuff might unified one
-- of the inst_tyavars' with something in the envt