X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcModule.lhs;h=bc1a87d09a699b870b0d16336817ef73c4ce82a1;hb=5f67848a9c686f64bd4960a40a0e109f286df74b;hp=382984fc8d02218452357949441b90397c7ad8c5;hpb=1bba522f5ec82c43abd2ba4e84127b9c915dd020;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcModule.lhs b/ghc/compiler/typecheck/TcModule.lhs index 382984f..bc1a87d 100644 --- a/ghc/compiler/typecheck/TcModule.lhs +++ b/ghc/compiler/typecheck/TcModule.lhs @@ -11,52 +11,51 @@ module TcModule ( #include "HsVersions.h" -import CmdLineOpts ( opt_D_dump_tc, opt_D_dump_types, opt_PprStyle_Debug ) -import HsSyn ( HsModule(..), HsBinds(..), MonoBinds(..), HsDecl(..) ) +import CmdLineOpts ( DynFlag(..), DynFlags, opt_PprStyle_Debug ) +import HsSyn ( HsBinds(..), MonoBinds(..), HsDecl(..) ) import HsTypes ( toHsType ) -import RnHsSyn ( RenamedHsModule ) +import RnHsSyn ( RenamedHsDecl ) import TcHsSyn ( TypecheckedMonoBinds, TypecheckedForeignDecl, TypecheckedRuleDecl, zonkTopBinds, zonkForeignExports, zonkRules ) import TcMonad -import Inst ( emptyLIE, plusLIE ) -import TcBinds ( tcTopBindsAndThen ) +import Inst ( plusLIE ) +import TcBinds ( tcTopBinds ) import TcClassDcl ( tcClassDecls2, mkImplicitClassBinds ) import TcDefaults ( tcDefaults ) -import TcEnv ( tcExtendGlobalValEnv, - getEnvTyCons, getEnvClasses, tcLookupValueByKeyMaybe, - tcSetValueEnv, tcSetInstEnv, initEnv, - ValueEnv, +import TcEnv ( TcEnv, InstInfo(iDFunId), tcExtendGlobalValEnv, + tcEnvTyCons, tcEnvClasses, isLocalThing, + RecTcEnv, tcSetEnv, tcSetInstEnv, initTcEnv, getTcGEnv ) import TcRules ( tcRules ) import TcForeign ( tcForeignImports, tcForeignExports ) import TcIfaceSig ( tcInterfaceSigs ) import TcInstDcls ( tcInstDecls1, tcInstDecls2 ) -import TcInstUtil ( buildInstanceEnv, InstInfo ) import TcSimplify ( tcSimplifyTop ) import TcTyClsDecls ( tcTyAndClassDecls ) import TcTyDecls ( mkImplicitDataBinds ) -import RnMonad ( RnNameSupply, FixityEnv ) +import CoreUnfold ( unfoldingTemplate ) +import Type ( funResultTy, splitForAllTys ) import Bag ( isEmptyBag ) -import ErrUtils ( printErrorsAndWarnings, dumpIfSet ) -import Id ( idType, idName ) -import Module ( pprModuleName, mkThisModule ) -import Name ( nameOccName, isLocallyDefined, isGlobalName, - toRdrName, nameEnvElts, - ) -import OccName ( isSysOcc ) -import TyCon ( TyCon, tyConClass_maybe ) -import Class ( Class ) -import PrelInfo ( mAIN_Name ) -import Unique ( mainKey ) -import UniqSupply ( UniqSupply ) -import Maybes ( maybeToBool ) +import ErrUtils ( printErrorsAndWarnings, dumpIfSet_dyn ) +import Id ( idType, idUnfolding ) +import Module ( Module ) +import Name ( Name, isLocallyDefined, toRdrName ) +import Name ( nameEnvElts, lookupNameEnv ) +import TyCon ( tyConGenInfo ) +import Maybes ( thenMaybe ) import Util -import Bag ( Bag, isEmptyBag ) +import BasicTypes ( EP(..), Fixity ) +import Bag ( isEmptyBag ) import Outputable +import HscTypes ( PersistentCompilerState(..), HomeSymbolTable, HomeIfaceTable, + PackageTypeEnv, DFunId, ModIface(..), + TypeEnv, extendTypeEnvList, lookupIface, + TyThing(..), mkTypeEnv ) +import List ( partition ) \end{code} Outside-world interface: @@ -65,229 +64,258 @@ Outside-world interface: -- Convenient type synonyms first: data TcResults = TcResults { - tc_binds :: TypecheckedMonoBinds, - tc_tycons :: [TyCon], - tc_classes :: [Class], - tc_insts :: Bag InstInfo, -- Instance declaration information + tc_pcs :: PersistentCompilerState, -- Augmented with imported information, + -- (but not stuff from this module) + + -- All these fields have info *just for this module* + tc_env :: TypeEnv, -- The top level TypeEnv + tc_insts :: [DFunId], -- Instances + tc_binds :: TypecheckedMonoBinds, -- Bindings tc_fords :: [TypecheckedForeignDecl], -- Foreign import & exports. - tc_rules :: [TypecheckedRuleDecl], -- Transformation rules - tc_env :: ValueEnv + tc_rules :: [TypecheckedRuleDecl] -- Transformation rules } --------------- typecheckModule - :: UniqSupply - -> RnNameSupply - -> FixityEnv - -> RenamedHsModule + :: DynFlags + -> Module + -> PersistentCompilerState + -> HomeSymbolTable -> HomeIfaceTable + -> [RenamedHsDecl] -> IO (Maybe TcResults) -typecheckModule us rn_name_supply fixity_env mod - = initTc us initEnv (tcModule rn_name_supply fixity_env mod) >>= \ (maybe_result, warns, errs) -> - - printErrorsAndWarnings errs warns >> - - (case maybe_result of - Nothing -> return () - Just results -> dumpIfSet opt_D_dump_types "Type signatures" (dump_sigs results) >> - dumpIfSet opt_D_dump_tc "Typechecked" (dump_tc results) - ) >> - - return (if isEmptyBag errs then - maybe_result - else - Nothing) +typecheckModule dflags this_mod pcs hst hit decls + = do env <- initTcEnv hst (pcs_PTE pcs) + + (maybe_result, (warns,errs)) <- initTc dflags env tc_module + + let { maybe_tc_result :: Maybe TcResults ; + maybe_tc_result = case maybe_result of + Nothing -> Nothing + Just (_,r) -> Just r } + + printErrorsAndWarnings (errs,warns) + printTcDump dflags maybe_tc_result + + if isEmptyBag errs then + return maybe_tc_result + else + return Nothing + where + tc_module :: TcM (RecTcEnv, TcResults) + tc_module = fixTc (\ ~(unf_env ,_) -> tcModule pcs hst get_fixity this_mod decls unf_env) + + pit = pcs_PIT pcs + + get_fixity :: Name -> Maybe Fixity + get_fixity nm = lookupIface hit pit this_mod nm `thenMaybe` \ iface -> + lookupNameEnv (mi_fixities iface) nm +\end{code} + +The internal monster: +\begin{code} +tcModule :: PersistentCompilerState + -> HomeSymbolTable + -> (Name -> Maybe Fixity) + -> Module + -> [RenamedHsDecl] + -> RecTcEnv -- The knot-tied environment + -> TcM (TcEnv, TcResults) + + -- (unf_env :: RecTcEnv) is used for type-checking interface pragmas + -- which is done lazily [ie failure just drops the pragma + -- without having any global-failure effect]. + -- + -- unf_env is also used to get the pragama info + -- for imported dfuns and default methods + +tcModule pcs hst get_fixity this_mod decls unf_env + = -- Type-check the type and class decls + tcTyAndClassDecls unf_env decls `thenTc` \ env -> + tcSetEnv env $ + let + classes = tcEnvClasses env + tycons = tcEnvTyCons env -- INCLUDES tycons derived from classes + in + + -- Typecheck the instance decls, includes deriving + tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs) + hst unf_env get_fixity this_mod + tycons decls `thenTc` \ (new_pcs_insts, inst_env, local_inst_info, deriv_binds) -> + tcSetInstEnv inst_env $ + + -- Default declarations + tcDefaults decls `thenTc` \ defaulting_tys -> + tcSetDefaultTys defaulting_tys $ + + -- Interface type signatures + -- We tie a knot so that the Ids read out of interfaces are in scope + -- when we read their pragmas. + -- What we rely on is that pragmas are typechecked lazily; if + -- any type errors are found (ie there's an inconsistency) + -- we silently discard the pragma + -- We must do this before mkImplicitDataBinds (which comes next), since + -- the latter looks up unpackCStringId, for example, which is usually + -- imported + tcInterfaceSigs unf_env decls `thenTc` \ sig_ids -> + tcExtendGlobalValEnv sig_ids $ + tcGetEnv `thenTc` \ unf_env -> + + -- Create any necessary record selector Ids and their bindings + -- "Necessary" includes data and newtype declarations + -- We don't create bindings for dictionary constructors; + -- they are always fully applied, and the bindings are just there + -- to support partial applications + mkImplicitDataBinds this_mod tycons `thenTc` \ (data_ids, imp_data_binds) -> + mkImplicitClassBinds this_mod classes `thenNF_Tc` \ (cls_ids, imp_cls_binds) -> + + -- Extend the global value environment with + -- (a) constructors + -- (b) record selectors + -- (c) class op selectors + -- (d) default-method ids... where? I can't see where these are + -- put into the envt, and I'm worried that the zonking phase + -- will find they aren't there and complain. + tcExtendGlobalValEnv data_ids $ + tcExtendGlobalValEnv cls_ids $ + + -- Foreign import declarations next + tcForeignImports decls `thenTc` \ (fo_ids, foi_decls) -> + tcExtendGlobalValEnv fo_ids $ + + -- Value declarations next. + -- We also typecheck any extra binds that came out of the "deriving" process + tcTopBinds (get_binds decls `ThenBinds` deriv_binds) `thenTc` \ ((val_binds, env), lie_valdecls) -> + tcSetEnv env $ + + -- Foreign export declarations next + tcForeignExports decls `thenTc` \ (lie_fodecls, foe_binds, foe_decls) -> + + -- Second pass over class and instance declarations, + -- to compile the bindings themselves. + tcInstDecls2 local_inst_info `thenNF_Tc` \ (lie_instdecls, inst_binds) -> + tcClassDecls2 this_mod decls `thenNF_Tc` \ (lie_clasdecls, cls_dm_binds) -> + tcRules (pcs_rules pcs) this_mod decls `thenNF_Tc` \ (new_pcs_rules, lie_rules, local_rules) -> + + -- Deal with constant or ambiguous InstIds. How could + -- there be ambiguous ones? They can only arise if a + -- top-level decl falls under the monomorphism + -- restriction, and no subsequent decl instantiates its + -- type. (Usually, ambiguous type variables are resolved + -- during the generalisation step.) + let + lie_alldecls = lie_valdecls `plusLIE` + lie_instdecls `plusLIE` + lie_clasdecls `plusLIE` + lie_fodecls `plusLIE` + lie_rules + in + tcSimplifyTop lie_alldecls `thenTc` \ const_inst_binds -> + + -- Backsubstitution. This must be done last. + -- Even tcSimplifyTop may do some unification. + let + all_binds = imp_data_binds `AndMonoBinds` + imp_cls_binds `AndMonoBinds` + val_binds `AndMonoBinds` + inst_binds `AndMonoBinds` + cls_dm_binds `AndMonoBinds` + const_inst_binds `AndMonoBinds` + foe_binds + in + zonkTopBinds all_binds `thenNF_Tc` \ (all_binds', final_env) -> + tcSetEnv final_env $ + -- zonkTopBinds puts all the top-level Ids into the tcGEnv + zonkForeignExports foe_decls `thenNF_Tc` \ foe_decls' -> + zonkRules local_rules `thenNF_Tc` \ local_rules' -> + + + let (local_things, imported_things) = partition (isLocalThing this_mod) + (nameEnvElts (getTcGEnv final_env)) + + local_type_env :: TypeEnv + local_type_env = mkTypeEnv local_things + + new_pte :: PackageTypeEnv + new_pte = extendTypeEnvList (pcs_PTE pcs) imported_things + + final_pcs :: PersistentCompilerState + final_pcs = pcs { pcs_PTE = new_pte, + pcs_insts = new_pcs_insts, + pcs_rules = new_pcs_rules + } + in + returnTc (unf_env, + TcResults { tc_pcs = final_pcs, + tc_env = local_type_env, + tc_binds = all_binds', + tc_insts = map iDFunId local_inst_info, + tc_fords = foi_decls ++ foe_decls', + tc_rules = local_rules' + }) + +get_binds decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls] +\end{code} + + + +%************************************************************************ +%* * +\subsection{Dumping output} +%* * +%************************************************************************ + +\begin{code} +printTcDump dflags Nothing = return () +printTcDump dflags (Just results) + = do dumpIfSet_dyn dflags Opt_D_dump_types + "Type signatures" (dump_sigs results) + dumpIfSet_dyn dflags Opt_D_dump_tc + "Typechecked" (dump_tc results) dump_tc results - = ppr (tc_binds results) $$ pp_rules (tc_rules results) + = vcat [ppr (tc_binds results), + pp_rules (tc_rules results), + ppr_gen_tycons [tc | ATyCon tc <- nameEnvElts (tc_env results)] + ] dump_sigs results -- Print type signatures = -- Convert to HsType so that we get source-language style printing -- And sort by RdrName vcat $ map ppr_sig $ sortLt lt_sig $ - [(toRdrName id, toHsType (idType id)) | id <- nameEnvElts (tc_env results), - want_sig id + [(toRdrName id, toHsType (idType id)) + | AnId id <- nameEnvElts (tc_env results), + want_sig id ] where lt_sig (n1,_) (n2,_) = n1 < n2 ppr_sig (n,t) = ppr n <+> dcolon <+> ppr t want_sig id | opt_PprStyle_Debug = True - | otherwise = isLocallyDefined n && - isGlobalName n && - not (isSysOcc (nameOccName n)) - where - n = idName id + | otherwise = isLocallyDefined id -pp_rules [] = empty -pp_rules rs = vcat [ptext SLIT("{-# RULES"), - nest 4 (vcat (map ppr rs)), - ptext SLIT("#-}")] -\end{code} +ppr_gen_tycons tcs = vcat [ptext SLIT("{-# Generic type constructor details"), + vcat (map ppr_gen_tycon (filter isLocallyDefined tcs)), + ptext SLIT("#-}") + ] -The internal monster: -\begin{code} -tcModule :: RnNameSupply -- for renaming derivings - -> FixityEnv -- needed for Show/Read derivings. - -> RenamedHsModule -- input - -> TcM s TcResults -- output - -tcModule rn_name_supply fixities - (HsModule mod_name _ _ _ decls _ src_loc) - = tcAddSrcLoc src_loc $ -- record where we're starting - - fixTc (\ ~(unf_env ,_) -> - -- unf_env is used for type-checking interface pragmas - -- which is done lazily [ie failure just drops the pragma - -- without having any global-failure effect]. - -- - -- unf_env is also used to get the pragam info - -- for imported dfuns and default methods - - -- Type-check the type and class decls - tcTyAndClassDecls unf_env decls `thenTc` \ env -> - - -- Typecheck the instance decls, includes deriving - tcSetEnv env $ +-- x&y are now Id's, not CoreExpr's +ppr_gen_tycon tycon + | Just ep <- tyConGenInfo tycon + = (ppr tycon <> colon) $$ nest 4 (ppr_ep ep) - tcInstDecls1 unf_env decls - (mkThisModule mod_name) - fixities rn_name_supply `thenTc` \ (inst_info, deriv_binds) -> - - buildInstanceEnv inst_info `thenNF_Tc` \ inst_env -> - - tcSetInstEnv inst_env $ - let - classes = getEnvClasses env - tycons = getEnvTyCons env -- INCLUDES tycons derived from classes - local_classes = filter isLocallyDefined classes - local_tycons = [ tc | tc <- tycons, - isLocallyDefined tc, - Nothing <- [tyConClass_maybe tc] - ] - -- For local_tycons, filter out the ones derived from classes - -- Otherwise the latter show up in interface files - in - - -- Default declarations - tcDefaults decls `thenTc` \ defaulting_tys -> - tcSetDefaultTys defaulting_tys $ - - -- Interface type signatures - -- We tie a knot so that the Ids read out of interfaces are in scope - -- when we read their pragmas. - -- What we rely on is that pragmas are typechecked lazily; if - -- any type errors are found (ie there's an inconsistency) - -- we silently discard the pragma - -- We must do this before mkImplicitDataBinds (which comes next), since - -- the latter looks up unpackCStringId, for example, which is usually - -- imported - tcInterfaceSigs unf_env decls `thenTc` \ sig_ids -> - tcExtendGlobalValEnv sig_ids $ - - -- Create any necessary record selector Ids and their bindings - -- "Necessary" includes data and newtype declarations - -- We don't create bindings for dictionary constructors; - -- they are always fully applied, and the bindings are just there - -- to support partial applications - mkImplicitDataBinds tycons `thenTc` \ (data_ids, imp_data_binds) -> - mkImplicitClassBinds classes `thenNF_Tc` \ (cls_ids, imp_cls_binds) -> - - -- Extend the global value environment with - -- (a) constructors - -- (b) record selectors - -- (c) class op selectors - -- (d) default-method ids... where? I can't see where these are - -- put into the envt, and I'm worried that the zonking phase - -- will find they aren't there and complain. - tcExtendGlobalValEnv data_ids $ - tcExtendGlobalValEnv cls_ids $ - - -- foreign import declarations next. - tcForeignImports decls `thenTc` \ (fo_ids, foi_decls) -> - tcExtendGlobalValEnv fo_ids $ - - -- Value declarations next. - -- We also typecheck any extra binds that came out of the "deriving" process - tcTopBindsAndThen - (\ is_rec binds1 (binds2, thing) -> (binds1 `AndMonoBinds` binds2, thing)) - (get_val_decls decls `ThenBinds` deriv_binds) - ( tcGetEnv `thenNF_Tc` \ env -> - tcGetUnique `thenNF_Tc` \ uniq -> - returnTc ((EmptyMonoBinds, env), emptyLIE) - ) `thenTc` \ ((val_binds, final_env), lie_valdecls) -> - tcSetEnv final_env $ - - -- foreign export declarations next. - tcForeignExports decls `thenTc` \ (lie_fodecls, foe_binds, foe_decls) -> - - -- Second pass over class and instance declarations, - -- to compile the bindings themselves. - tcInstDecls2 inst_info `thenNF_Tc` \ (lie_instdecls, inst_binds) -> - tcClassDecls2 decls `thenNF_Tc` \ (lie_clasdecls, cls_dm_binds) -> - tcRules decls `thenNF_Tc` \ (lie_rules, rules) -> - - - -- Deal with constant or ambiguous InstIds. How could - -- there be ambiguous ones? They can only arise if a - -- top-level decl falls under the monomorphism - -- restriction, and no subsequent decl instantiates its - -- type. (Usually, ambiguous type variables are resolved - -- during the generalisation step.) - let - lie_alldecls = lie_valdecls `plusLIE` - lie_instdecls `plusLIE` - lie_clasdecls `plusLIE` - lie_fodecls `plusLIE` - lie_rules - in - tcSimplifyTop lie_alldecls `thenTc` \ const_inst_binds -> - - -- Check that Main defines main - (if mod_name == mAIN_Name then - tcLookupValueByKeyMaybe mainKey `thenNF_Tc` \ maybe_main -> - checkTc (maybeToBool maybe_main) noMainErr - else - returnTc () - ) `thenTc_` - - -- Backsubstitution. This must be done last. - -- Even tcSimplifyTop may do some unification. - let - all_binds = imp_data_binds `AndMonoBinds` - imp_cls_binds `AndMonoBinds` - val_binds `AndMonoBinds` - inst_binds `AndMonoBinds` - cls_dm_binds `AndMonoBinds` - const_inst_binds `AndMonoBinds` - foe_binds - in - zonkTopBinds all_binds `thenNF_Tc` \ (all_binds', really_final_env) -> - tcSetValueEnv really_final_env $ - zonkForeignExports foe_decls `thenNF_Tc` \ foe_decls' -> - zonkRules rules `thenNF_Tc` \ rules' -> - - returnTc (really_final_env, - (TcResults { tc_binds = all_binds', - tc_tycons = local_tycons, - tc_classes = local_classes, - tc_insts = inst_info, - tc_fords = foi_decls ++ foe_decls', - tc_rules = rules', - tc_env = really_final_env - })) - - -- End of outer fix loop - ) `thenTc` \ (final_env, stuff) -> - returnTc stuff - -get_val_decls decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls] -\end{code} + | otherwise = ppr tycon <> colon <+> ptext SLIT("Not derivable") +ppr_ep (EP from to) + = vcat [ ptext SLIT("Rep type:") <+> ppr (funResultTy from_tau), + ptext SLIT("From:") <+> ppr (unfoldingTemplate (idUnfolding from)), + ptext SLIT("To:") <+> ppr (unfoldingTemplate (idUnfolding to)) + ] + where + (_,from_tau) = splitForAllTys (idType from) -\begin{code} -noMainErr - = hsep [ptext SLIT("Module"), quotes (pprModuleName mAIN_Name), - ptext SLIT("must include a definition for"), quotes (ptext SLIT("main"))] +pp_rules [] = empty +pp_rules rs = vcat [ptext SLIT("{-# RULES"), + nest 4 (vcat (map ppr rs)), + ptext SLIT("#-}")] \end{code} -