X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcInstDcls.lhs;h=12e853d052963836f23ff113a20e86f84ace0977;hb=a76db2a07f99716c40e05d73210f80b4e4794b9a;hp=459160d60f9f60d39257bcfd39934969b05bad9b;hpb=a180ee15dfe2eb0da03cd92ca89475765cd080d9;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcInstDcls.lhs b/ghc/compiler/typecheck/TcInstDcls.lhs index 459160d..12e853d 100644 --- a/ghc/compiler/typecheck/TcInstDcls.lhs +++ b/ghc/compiler/typecheck/TcInstDcls.lhs @@ -9,52 +9,53 @@ module TcInstDcls ( tcInstDecls1, tcInstDecls2, tcAddDeclCtxt ) where #include "HsVersions.h" -import CmdLineOpts ( opt_GlasgowExts, opt_AllowUndecidableInstances, opt_D_dump_deriv ) +import CmdLineOpts ( DynFlag(..), dopt ) -import HsSyn ( HsDecl(..), InstDecl(..), TyClDecl(..), - MonoBinds(..), HsExpr(..), HsLit(..), Sig(..), +import HsSyn ( HsDecl(..), InstDecl(..), TyClDecl(..), + MonoBinds(..), HsExpr(..), HsLit(..), Sig(..), andMonoBindList, collectMonoBinders, isClassDecl ) -import HsTypes ( HsType (..), HsTyVarBndr(..), toHsTyVar ) -import HsPat ( InPat (..) ) -import HsMatches ( Match (..) ) -import RnHsSyn ( RenamedHsBinds, RenamedInstDecl, RenamedHsDecl, extractHsTyVars ) +import RnHsSyn ( RenamedHsBinds, RenamedInstDecl, RenamedHsDecl, RenamedMonoBinds, + RenamedTyClDecl, RenamedHsType, + extractHsTyVars, maybeGenericMatch + ) import TcHsSyn ( TcMonoBinds, mkHsConApp ) import TcBinds ( tcSpecSigs ) import TcClassDcl ( tcMethodBind, badMethodErr ) import TcMonad -import RnMonad ( RnNameSupply, FixityEnv ) import Inst ( InstOrigin(..), newDicts, newClassDicts, LIE, emptyLIE, plusLIE, plusLIEs ) import TcDeriv ( tcDeriving ) import TcEnv ( TcEnv, tcExtendGlobalValEnv, - tcExtendTyVarEnvForMeths, TyThing (..), + tcExtendTyVarEnvForMeths, tcAddImportedIdInfo, tcInstId, tcLookupClass, newDFunName, tcExtendTyVarEnv ) -import TcInstUtil ( InstInfo(..), pprInstInfo, classDataCon, simpleInstInfoTyCon, simpleInstInfoTy ) -import TcMonoType ( tcTyVars, tcHsSigType, tcHsType, kcHsSigType ) +import InstEnv ( InstInfo(..), InstEnv, pprInstInfo, classDataCon, + simpleInstInfoTyCon, simpleInstInfoTy, isLocalInst, + extendInstEnv ) +import TcMonoType ( tcTyVars, tcHsSigType, kcHsSigType ) import TcSimplify ( tcSimplifyAndCheck ) import TcType ( zonkTcSigTyVars ) +import HscTypes ( PersistentCompilerState(..), HomeSymbolTable, DFunId, + ModDetails(..) ) -import Bag ( emptyBag, unitBag, unionBags, unionManyBags, - foldBag, Bag, listToBag - ) +import Bag ( unionManyBags ) import Class ( Class, DefMeth(..), classBigSig ) import Var ( idName, idType ) -import Maybes ( maybeToBool, expectJust ) +import Maybes ( maybeToBool ) import MkId ( mkDictFunId ) import Generics ( validGenericInstanceType ) -import Module ( Module ) +import Module ( Module, foldModuleEnv ) import Name ( isLocallyDefined ) import NameSet ( emptyNameSet, nameSetToList ) import PrelInfo ( eRROR_ID ) import PprType ( pprConstraint, pprPred ) -import TyCon ( isSynTyCon, tyConDerivings ) -import Type ( mkTyVarTys, splitSigmaTy, isTyVarTy, - splitTyConApp_maybe, splitDictTy_maybe, - splitAlgTyConApp_maybe, classesToPreds, classesOfPreds, +import TyCon ( TyCon, isSynTyCon, tyConDerivings ) +import Type ( mkTyVarTys, splitDFunTy, isTyVarTy, + splitTyConApp_maybe, splitDictTy, + splitAlgTyConApp_maybe, unUsgTy, tyVarsOfTypes, mkClassPred, mkTyVarTy, getClassTys_maybe ) @@ -62,21 +63,17 @@ import Subst ( mkTopTyVarSubst, substClasses, substTheta ) import VarSet ( mkVarSet, varSetElems ) import TysWiredIn ( genericTyCons, isFFIArgumentTy, isFFIResultTy ) import PrelNames ( cCallableClassKey, cReturnableClassKey, hasKey ) -import Name ( Name, NameEnv, extendNameEnv_C, emptyNameEnv, - plusNameEnv_C, nameEnvElts ) -import FiniteMap ( mapFM ) +import Name ( Name ) import SrcLoc ( SrcLoc ) -import RnHsSyn -- ( RenamedMonoBinds ) import VarSet ( varSetElems ) -import UniqFM ( mapUFM ) import Unique ( Uniquable(..) ) -import BasicTypes ( NewOrData(..) ) -import ErrUtils ( dumpIfSet ) +import BasicTypes ( NewOrData(..), Fixity ) +import ErrUtils ( dumpIfSet_dyn ) import ListSetOps ( Assoc, emptyAssoc, plusAssoc_C, mapAssoc, assocElts, extendAssoc_C, equivClassesByUniq, minusList ) -import List ( intersect, (\\) ) +import List ( partition ) import Outputable \end{code} @@ -166,22 +163,24 @@ Gather up the instance declarations from their various sources tcInstDecls1 :: PersistentCompilerState -> HomeSymbolTable -- Contains instances -> TcEnv -- Contains IdInfo for dfun ids + -> (Name -> Maybe Fixity) -- for deriving Show and Read -> Module -- Module for deriving + -> [TyCon] -> [RenamedHsDecl] -> TcM (PersistentCompilerState, InstEnv, [InstInfo], RenamedHsBinds) -tcInstDecls1 pcs hst unf_env this_mod decls mod +tcInstDecls1 pcs hst unf_env get_fixity mod local_tycons decls = let inst_decls = [inst_decl | InstD inst_decl <- decls] - clas_decls = [clas_decl | TyClD clas_decl <- decls, isClassDecl cl_decl] + clas_decls = [clas_decl | TyClD clas_decl <- decls, isClassDecl clas_decl] in -- (1) Do the ordinary instance declarations - mapNF_Tc (tcInstDecl1 mod) inst_decls `thenNF_Tc` \ inst_infos -> + mapNF_Tc (tcInstDecl1 mod unf_env) inst_decls `thenNF_Tc` \ inst_infos -> -- (2) Instances from generic class declarations - getGenericInstances mod clas_decls `thenTc` \ generic_inst_info -> + getGenericInstances mod clas_decls `thenTc` \ generic_inst_info -> - -- Next, consruct the instance environment so far, consisting of + -- Next, construct the instance environment so far, consisting of -- a) cached non-home-package InstEnv (gotten from pcs) pcs_insts pcs -- b) imported instance decls (not in the home package) inst_env1 -- c) other modules in this package (gotten from hst) inst_env2 @@ -189,25 +188,27 @@ tcInstDecls1 pcs hst unf_env this_mod decls mod -- e) generic instances inst_env4 -- The result of (b) replaces the cached InstEnv in the PCS let - (local_inst_info, imported_inst_info) = partition isLocalInst (concat inst_infos) - generic_inst_info = concat generic_inst_infos -- All local + (local_inst_info, imported_inst_info) + = partition isLocalInst (concat inst_infos) - imported_dfuns = map (tcAddImportedIdInfo unf_env . instInfoDFun) imported_inst_info + imported_dfuns = map (tcAddImportedIdInfo unf_env . iDFunId) + imported_inst_info hst_dfuns = foldModuleEnv ((++) . md_insts) [] hst in addInstDFuns (pcs_insts pcs) imported_dfuns `thenNF_Tc` \ inst_env1 -> addInstDFuns inst_env1 hst_dfuns `thenNF_Tc` \ inst_env2 -> addInstInfos inst_env2 local_inst_info `thenNF_Tc` \ inst_env3 -> addInstInfos inst_env3 generic_inst_info `thenNF_Tc` \ inst_env4 -> - in -- (3) Compute instances from "deriving" clauses; -- note that we only do derivings for things in this module; -- we ignore deriving decls from interfaces! -- This stuff computes a context for the derived instance decl, so it -- needs to know about all the instances possible; hecne inst_env4 - tcDeriving (pcs_PRS pcs) this_mod inst_env4 local_tycons `thenTc` \ (deriv_inst_info, deriv_binds) -> - addInstInfos inst_env4 deriv_inst_info `thenNF_Tc` \ final_inst_env -> + tcDeriving (pcs_PRS pcs) mod inst_env4 get_fixity local_tycons + `thenTc` \ (deriv_inst_info, deriv_binds) -> + addInstInfos inst_env4 deriv_inst_info + `thenNF_Tc` \ final_inst_env -> returnTc (pcs { pcs_insts = inst_env1 }, final_inst_env, @@ -215,14 +216,17 @@ tcInstDecls1 pcs hst unf_env this_mod decls mod deriv_binds) addInstInfos :: InstEnv -> [InstInfo] -> NF_TcM InstEnv -addInstInfos inst_env infos = addInstDfuns inst_env (map iDFun infos) +addInstInfos inst_env infos = addInstDFuns inst_env (map iDFunId infos) addInstDFuns :: InstEnv -> [DFunId] -> NF_TcM InstEnv addInstDFuns dfuns infos - = addErrsTc errs `thenNF_Tc_` + = getDOptsTc `thenTc` \ dflags -> + extendInstEnv dflags dfuns infos `bind` \ (inst_env', errs) -> + addErrsTc errs `thenNF_Tc_` returnTc inst_env' where - (inst_env', errs) = extendInstEnv env dfuns + bind x f = f x + \end{code} \begin{code} @@ -236,10 +240,7 @@ tcInstDecl1 mod unf_env (InstDecl poly_ty binds uprags maybe_dfun_name src_loc) -- Type-check all the stuff before the "where" tcHsSigType poly_ty `thenTc` \ poly_ty' -> let - (tyvars, theta, dict_ty) = splitSigmaTy poly_ty' - (clas, inst_tys) = case splitDictTy_maybe dict_ty of - Just ct -> ct - Nothing -> pprPanic "tcInstDecl1" (ppr poly_ty) + (tyvars, theta, clas, inst_tys) = splitDFunTy poly_ty' in (case maybe_dfun_name of @@ -302,16 +303,18 @@ gives rise to the instance declarations \begin{code} getGenericInstances :: Module -> [RenamedTyClDecl] -> TcM [InstInfo] getGenericInstances mod class_decls - = mapTc (get_generics mod) class_decls `thenTc` \ gen_inst_infos -> + = mapTc (get_generics mod) class_decls `thenTc` \ gen_inst_infos -> let gen_inst_info = concat gen_inst_infos in - ioToTc (dumpIfSet opt_D_dump_deriv "Generic instances" - (vcat (map pprInstInfo gen_inst_info))) `thenNF_Tc_` + getDOptsTc `thenTc` \ dflags -> + ioToTc (dumpIfSet_dyn dflags Opt_D_dump_deriv "Generic instances" + (vcat (map pprInstInfo gen_inst_info))) + `thenNF_Tc_` returnTc gen_inst_info get_generics mod decl@(ClassDecl context class_name tyvar_names - fundeps class_sigs def_methods pragmas + fundeps class_sigs def_methods name_list loc) | null groups = returnTc [] -- The comon case: @@ -411,11 +414,13 @@ mkGenericInstance mod clas loc (hs_ty, binds) %************************************************************************ \begin{code} -tcInstDecls2 :: Bag InstInfo +tcInstDecls2 :: [InstInfo] -> NF_TcM (LIE, TcMonoBinds) tcInstDecls2 inst_decls - = foldBag combine tcInstDecl2 (returnNF_Tc (emptyLIE, EmptyMonoBinds)) inst_decls +-- = foldBag combine tcInstDecl2 (returnNF_Tc (emptyLIE, EmptyMonoBinds)) inst_decls + = foldr combine (returnNF_Tc (emptyLIE, EmptyMonoBinds)) + (map tcInstDecl2 inst_decls) where combine tc1 tc2 = tc1 `thenNF_Tc` \ (lie1, binds1) -> tc2 `thenNF_Tc` \ (lie2, binds2) -> @@ -506,7 +511,7 @@ tcInstDecl2 (InstInfo { iClass = clas, iTyVars = inst_tyvars, iTys = inst_tys, -- Instantiate the instance decl with tc-style type variables tcInstId dfun_id `thenNF_Tc` \ (inst_tyvars', dfun_theta', dict_ty') -> let - (clas, inst_tys') = expectJust "tcInstDecl2" (splitDictTy_maybe dict_ty') + (clas, inst_tys') = splitDictTy dict_ty' origin = InstanceDeclOrigin (class_tyvars, sc_theta, _, op_items) = classBigSig clas @@ -672,57 +677,64 @@ We can also have instances for functions: @instance Foo (a -> b) ...@. \begin{code} scrutiniseInstanceConstraint pred - | opt_AllowUndecidableInstances - = returnNF_Tc () + = getDOptsTc `thenTc` \ dflags -> case () of + () + | dopt Opt_AllowUndecidableInstances dflags + -> returnNF_Tc () - | Just (clas,tys) <- getClassTys_maybe pred, - all isTyVarTy tys - = returnNF_Tc () + | Just (clas,tys) <- getClassTys_maybe pred, + all isTyVarTy tys + -> returnNF_Tc () - | otherwise - = addErrTc (instConstraintErr pred) + | otherwise + -> addErrTc (instConstraintErr pred) scrutiniseInstanceHead clas inst_taus - | -- CCALL CHECK + = getDOptsTc `thenTc` \ dflags -> case () of + () + | -- CCALL CHECK -- A user declaration of a CCallable/CReturnable instance -- must be for a "boxed primitive" type. - (clas `hasKey` cCallableClassKey && not (ccallable_type first_inst_tau)) || - (clas `hasKey` cReturnableClassKey && not (creturnable_type first_inst_tau)) - = addErrTc (nonBoxedPrimCCallErr clas first_inst_tau) + (clas `hasKey` cCallableClassKey + && not (ccallable_type dflags first_inst_tau)) + || + (clas `hasKey` cReturnableClassKey + && not (creturnable_type first_inst_tau)) + -> addErrTc (nonBoxedPrimCCallErr clas first_inst_tau) -- DERIVING CHECK -- It is obviously illegal to have an explicit instance -- for something that we are also planning to `derive' - | maybeToBool alg_tycon_app_maybe && clas `elem` (tyConDerivings alg_tycon) - = addErrTc (derivingWhenInstanceExistsErr clas first_inst_tau) + | maybeToBool alg_tycon_app_maybe && clas `elem` (tyConDerivings alg_tycon) + -> addErrTc (derivingWhenInstanceExistsErr clas first_inst_tau) -- Kind check will have ensured inst_taus is of length 1 -- Allow anything for AllowUndecidableInstances - | opt_AllowUndecidableInstances - = returnNF_Tc () + | dopt Opt_AllowUndecidableInstances dflags + -> returnNF_Tc () -- If GlasgowExts then check at least one isn't a type variable - | opt_GlasgowExts - = if all isTyVarTy inst_taus then - addErrTc (instTypeErr clas inst_taus (text "There must be at least one non-type-variable in the instance head")) - else - returnNF_Tc () + | dopt Opt_GlasgowExts dflags + -> if all isTyVarTy inst_taus + then addErrTc (instTypeErr clas inst_taus + (text "There must be at least one non-type-variable in the instance head")) + else returnNF_Tc () -- WITH HASKELL 1.4, MUST HAVE C (T a b c) - | not (length inst_taus == 1 && - maybeToBool maybe_tycon_app && -- Yes, there's a type constuctor - not (isSynTyCon tycon) && -- ...but not a synonym - all isTyVarTy arg_tys && -- Applied to type variables - length (varSetElems (tyVarsOfTypes arg_tys)) == length arg_tys - -- This last condition checks that all the type variables are distinct - ) - = addErrTc (instTypeErr clas inst_taus - (text "the instance type must be of form (T a b c)" $$ - text "where T is not a synonym, and a,b,c are distinct type variables") - ) - - | otherwise - = returnNF_Tc () + | not (length inst_taus == 1 && + maybeToBool maybe_tycon_app && -- Yes, there's a type constuctor + not (isSynTyCon tycon) && -- ...but not a synonym + all isTyVarTy arg_tys && -- Applied to type variables + length (varSetElems (tyVarsOfTypes arg_tys)) == length arg_tys + -- This last condition checks that all the type variables are distinct + ) + -> addErrTc (instTypeErr clas inst_taus + (text "the instance type must be of form (T a b c)" $$ + text "where T is not a synonym, and a,b,c are distinct type variables") + ) + + | otherwise + -> returnNF_Tc () where (first_inst_tau : _) = inst_taus @@ -736,8 +748,8 @@ scrutiniseInstanceHead clas inst_taus -- The "Alg" part looks through synonyms Just (alg_tycon, _, _) = alg_tycon_app_maybe -ccallable_type ty = isFFIArgumentTy False {- Not safe call -} ty -creturnable_type ty = isFFIResultTy ty + ccallable_type dflags ty = isFFIArgumentTy dflags False {- Not safe call -} ty + creturnable_type ty = isFFIResultTy ty \end{code} @@ -755,10 +767,10 @@ tcAddDeclCtxt decl thing_inside where (name, loc, thing) = case decl of - (ClassDecl _ name _ _ _ _ _ _ loc) -> (name, loc, "class") - (TySynonym name _ _ loc) -> (name, loc, "type synonym") - (TyData NewType _ name _ _ _ _ _ loc _ _) -> (name, loc, "newtype") - (TyData DataType _ name _ _ _ _ _ loc _ _) -> (name, loc, "data type") + (ClassDecl _ name _ _ _ _ _ loc) -> (name, loc, "class") + (TySynonym name _ _ loc) -> (name, loc, "type synonym") + (TyData NewType _ name _ _ _ _ loc _ _) -> (name, loc, "newtype") + (TyData DataType _ name _ _ _ _ loc _ _) -> (name, loc, "data type") ctxt = hsep [ptext SLIT("In the"), text thing, ptext SLIT("declaration for"), quotes (ppr name)]