X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcModule.lhs;h=9a747c143ee79bb19d1d2d29246780f197684d2e;hb=4166dff80e8ec94022a040318ff2759913fbbe06;hp=3195197620b9af70c92a2f1ee164edd57ab6e947;hpb=438596897ebbe25a07e1c82085cfbc5bdb00f09e;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcModule.lhs b/ghc/compiler/typecheck/TcModule.lhs index 3195197..9a747c1 100644 --- a/ghc/compiler/typecheck/TcModule.lhs +++ b/ghc/compiler/typecheck/TcModule.lhs @@ -5,327 +5,386 @@ \begin{code} module TcModule ( - typecheckModule, - TcResults, - TcDDumpDeriv + typecheckModule, typecheckExpr, TcResults(..) ) where #include "HsVersions.h" -import CmdLineOpts ( opt_D_dump_tc, opt_D_dump_deriv ) -import HsSyn ( HsModule(..), HsBinds(..), MonoBinds(..), HsDecl(..) ) -import RnHsSyn ( RenamedHsModule ) -import TcHsSyn ( TcMonoBinds, TypecheckedMonoBinds, zonkTopBinds, - TypecheckedForeignDecl, zonkForeignExports +import CmdLineOpts ( DynFlag(..), DynFlags, opt_PprStyle_Debug ) +import HsSyn ( HsBinds(..), MonoBinds(..), HsDecl(..), + isIfaceRuleDecl, nullBinds, andMonoBindList ) +import HsTypes ( toHsType ) +import RnHsSyn ( RenamedHsBinds, RenamedHsDecl, RenamedHsExpr ) +import TcHsSyn ( TypecheckedMonoBinds, TypecheckedHsExpr, + TypecheckedForeignDecl, TypecheckedRuleDecl, + zonkTopBinds, zonkForeignExports, zonkRules, mkHsLet, + zonkExpr + ) + import TcMonad -import Inst ( Inst, emptyLIE, plusLIE ) -import TcBinds ( tcTopBindsAndThen ) +import TcType ( newTyVarTy, zonkTcType ) +import Inst ( plusLIE ) +import TcBinds ( tcTopBinds ) import TcClassDcl ( tcClassDecls2 ) -import TcDefaults ( tcDefaults ) -import TcEnv ( TcIdOcc(..), tcExtendGlobalValEnv, tcExtendTyConEnv, - getEnv_TyCons, getEnv_Classes, tcLookupLocalValue, - lookupGlobalByKey, tcSetGlobalValEnv, - tcLookupTyCon, initEnv, GlobalValueEnv +import TcDefaults ( tcDefaults, defaultDefaultTys ) +import TcExpr ( tcMonoExpr ) +import TcEnv ( TcEnv, InstInfo(iDFunId), tcExtendGlobalValEnv, + isLocalThing, tcSetEnv, tcSetInstEnv, initTcEnv, getTcGEnv ) -import TcExpr ( tcId ) +import TcRules ( tcIfaceRules, tcSourceRules ) import TcForeign ( tcForeignImports, tcForeignExports ) import TcIfaceSig ( tcInterfaceSigs ) import TcInstDcls ( tcInstDecls1, tcInstDecls2 ) -import TcInstUtil ( buildInstanceEnvs, classDataCon, InstInfo ) import TcSimplify ( tcSimplifyTop ) -import TcTyClsDecls ( tcTyAndClassDecls1 ) -import TcTyDecls ( mkDataBinds ) -import TcType ( TcType, typeToTcType, - TcKind, kindToTcKind - ) +import TcTyClsDecls ( tcTyAndClassDecls ) -import RnMonad ( RnNameSupply ) +import CoreUnfold ( unfoldingTemplate, hasUnfolding ) +import Type ( funResultTy, splitForAllTys, openTypeKind ) import Bag ( isEmptyBag ) -import ErrUtils ( ErrMsg, - pprBagOfErrors, dumpIfSet - ) -import Id ( Id, idType ) -import Name ( Name, nameUnique, isLocallyDefined, pprModule, NamedThing(..) ) -import TyCon ( TyCon, tyConKind ) -import DataCon ( dataConId ) -import Class ( Class, classSelIds, classTyCon ) -import Type ( mkTyConApp, Type ) -import TysWiredIn ( unitTy ) -import PrelMods ( mAIN ) -import PrelInfo ( main_NAME, ioTyCon_NAME, - thinAirIdNames, setThinAirIds - ) -import TcUnify ( unifyTauTy ) -import Unique ( Unique ) -import UniqSupply ( UniqSupply ) +import ErrUtils ( printErrorsAndWarnings, dumpIfSet_dyn, showPass ) +import Id ( idType, idUnfolding ) +import Module ( Module ) +import Name ( Name, toRdrName ) +import Name ( nameEnvElts, lookupNameEnv ) +import TyCon ( tyConGenInfo ) import Util -import Bag ( Bag, isEmptyBag ) +import BasicTypes ( EP(..), Fixity ) +import Bag ( isEmptyBag ) import Outputable - -import IOExts +import HscTypes ( PersistentCompilerState(..), HomeSymbolTable, + PackageTypeEnv, DFunId, ModIface(..), + TypeEnv, extendTypeEnvList, + TyThing(..), implicitTyThingIds, + mkTypeEnv + ) \end{code} Outside-world interface: \begin{code} -- Convenient type synonyms first: -type TcResults - = (TypecheckedMonoBinds, - [TyCon], [Class], - Bag InstInfo, -- Instance declaration information - [TypecheckedForeignDecl], -- foreign import & exports. - TcDDumpDeriv, - GlobalValueEnv, - [Id] -- The thin-air Ids - ) - -type TcDDumpDeriv = SDoc +data TcResults + = TcResults { + -- 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 + } --------------- typecheckModule - :: UniqSupply - -> RnNameSupply - -> RenamedHsModule - -> IO (Maybe TcResults) - -typecheckModule us rn_name_supply mod - = let - (maybe_result, warns, errs) = - initTc us initEnv (tcModule rn_name_supply mod) - in - print_errs warns >> - print_errs errs >> - - dumpIfSet opt_D_dump_tc "Typechecked" - (case maybe_result of - Just (binds, _, _, _, _, _, _, _) -> ppr binds - Nothing -> text "Typecheck failed") >> - - dumpIfSet opt_D_dump_deriv "Derived instances" - (case maybe_result of - Just (_, _, _, _, _, dump_deriv, _, _) -> dump_deriv - Nothing -> empty) >> - - -- write the thin-air Id map - (case maybe_result of - Just (_, _, _, _, _, _, _, thin_air_ids) -> setThinAirIds thin_air_ids - Nothing -> return () - ) >> - - return (if isEmptyBag errs then - maybe_result - else - Nothing) - -print_errs errs - | isEmptyBag errs = return () - | otherwise = printErrs (pprBagOfErrors errs) + :: DynFlags + -> PersistentCompilerState + -> HomeSymbolTable + -> ModIface -- Iface for this module + -> PrintUnqualified -- For error printing + -> [RenamedHsDecl] + -> IO (Maybe (PersistentCompilerState, TcResults)) + -- The new PCS is Augmented with imported information, + -- (but not stuff from this module) + + +typecheckModule dflags pcs hst mod_iface unqual decls + = do { maybe_tc_result <- typecheck dflags pcs hst unqual $ + tcModule pcs hst get_fixity this_mod decls + ; printTcDump dflags maybe_tc_result + ; return maybe_tc_result } + where + this_mod = mi_module mod_iface + fixity_env = mi_fixities mod_iface + + get_fixity :: Name -> Maybe Fixity + get_fixity nm = lookupNameEnv fixity_env nm + +--------------- +typecheckExpr :: DynFlags + -> PersistentCompilerState + -> HomeSymbolTable + -> PrintUnqualified -- For error printing + -> Module + -> (RenamedHsExpr, -- The expression itself + [RenamedHsDecl]) -- Plus extra decls it sucked in from interface files + -> IO (Maybe (PersistentCompilerState, TypecheckedHsExpr, TcType)) + +typecheckExpr dflags pcs hst unqual this_mod (expr, decls) + = typecheck dflags pcs hst unqual $ + + -- use the default default settings, i.e. [Integer, Double] + tcSetDefaultTys defaultDefaultTys $ + tcImports pcs hst get_fixity this_mod decls `thenTc` \ (env, new_pcs, local_inst_info, deriv_binds, local_rules) -> + ASSERT( null local_inst_info && nullBinds deriv_binds && null local_rules ) + + tcSetEnv env $ + newTyVarTy openTypeKind `thenTc` \ ty -> + tcMonoExpr expr ty `thenTc` \ (expr', lie) -> + tcSimplifyTop lie `thenTc` \ binds -> + let all_expr = mkHsLet binds expr' in + zonkExpr all_expr `thenNF_Tc` \ zonked_expr -> + zonkTcType ty `thenNF_Tc` \ zonked_ty -> + returnTc (new_pcs, zonked_expr, zonked_ty) + where + get_fixity :: Name -> Maybe Fixity + get_fixity n = pprPanic "typecheckExpr" (ppr n) + +--------------- +typecheck :: DynFlags + -> PersistentCompilerState + -> HomeSymbolTable + -> PrintUnqualified -- For error printing + -> TcM r + -> IO (Maybe r) + +typecheck dflags pcs hst unqual thing_inside + = do { showPass dflags "Typechecker"; + ; env <- initTcEnv hst (pcs_PTE pcs) + + ; (maybe_tc_result, (warns,errs)) <- initTc dflags env thing_inside + + ; printErrorsAndWarnings unqual (errs,warns) + + ; if isEmptyBag errs then + return maybe_tc_result + else + return Nothing + } \end{code} The internal monster: \begin{code} -tcModule :: RnNameSupply -- for renaming derivings - -> RenamedHsModule -- input - -> TcM s TcResults -- output - -tcModule rn_name_supply - (HsModule mod_name verion exports imports fixities 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 - - -- The knot for instance information. This isn't used at all - -- till we type-check value declarations - fixTc ( \ ~(rec_inst_mapper, _, _, _, _) -> +tcModule :: PersistentCompilerState + -> HomeSymbolTable + -> (Name -> Maybe Fixity) + -> Module + -> [RenamedHsDecl] + -> TcM (PersistentCompilerState, TcResults) + +tcModule pcs hst get_fixity this_mod decls + = -- Type-check the type and class decls, and all imported decls + tcImports pcs hst get_fixity this_mod decls `thenTc` \ (env, new_pcs, local_inst_info, deriv_binds, local_rules) -> + + tcSetEnv env $ + + -- Foreign import declarations next +-- traceTc (text "Tc4") `thenNF_Tc_` + tcForeignImports decls `thenTc` \ (fo_ids, foi_decls) -> + tcExtendGlobalValEnv fo_ids $ - -- Type-check the type and class decls - -- trace "tcTyAndClassDecls:" $ - tcTyAndClassDecls1 unf_env rec_inst_mapper decls `thenTc` \ env -> + -- Default declarations + tcDefaults decls `thenTc` \ defaulting_tys -> + tcSetDefaultTys defaulting_tys $ + + -- Value declarations next. + -- We also typecheck any extra binds that came out of the "deriving" process +-- traceTc (text "Tc5") `thenNF_Tc_` + tcTopBinds (val_binds `ThenBinds` deriv_binds) `thenTc` \ ((val_binds, env), lie_valdecls) -> + tcSetEnv env $ - -- trace "tc3" $ - -- Typecheck the instance decls, includes deriving - tcSetEnv env ( - -- trace "tcInstDecls:" $ - tcInstDecls1 unf_env decls mod_name rn_name_supply - ) `thenTc` \ (inst_info, deriv_binds, ddump_deriv) -> + -- Foreign export declarations next +-- traceTc (text "Tc6") `thenNF_Tc_` + tcForeignExports decls `thenTc` \ (lie_fodecls, foe_binds, foe_decls) -> - -- trace "tc4" $ - buildInstanceEnvs inst_info `thenNF_Tc` \ inst_mapper -> + -- 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 tycl_decls `thenNF_Tc` \ (lie_clasdecls, cls_dm_binds) -> + tcSourceRules source_rules `thenNF_Tc` \ (lie_rules, more_local_rules) -> - returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv) + -- 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 -> - -- End of inner fix loop - ) `thenTc` \ (_, env, inst_info, deriv_binds, ddump_deriv) -> + -- Backsubstitution. This must be done last. + -- Even tcSimplifyTop may do some unification. + let + all_binds = val_binds `AndMonoBinds` + inst_binds `AndMonoBinds` + cls_dm_binds `AndMonoBinds` + const_inst_binds `AndMonoBinds` + foe_binds + in +-- traceTc (text "Tc9") `thenNF_Tc_` + 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 more_local_rules `thenNF_Tc` \ more_local_rules' -> - -- trace "tc5" $ - tcSetEnv env $ - - -- Default declarations - tcDefaults decls `thenTc` \ defaulting_tys -> - tcSetDefaultTys defaulting_tys $ - - -- 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 - let - tycons = getEnv_TyCons env - classes = getEnv_Classes env - local_tycons = filter isLocallyDefined tycons - local_classes = filter isLocallyDefined classes - in - mkDataBinds tycons `thenTc` \ (data_ids, data_binds) -> - - -- Extend the global value environment with - -- (a) constructors - -- (b) record selectors - -- (c) class op selectors - -- (d) default-method ids - tcExtendGlobalValEnv data_ids $ - tcExtendGlobalValEnv (concat (map classSelIds classes)) $ - - -- Extend the TyCon envt with the tycons corresponding to - -- the classes, and the global value environment with the - -- corresponding data cons. - -- They are mentioned in types in interface files. - tcExtendGlobalValEnv (map (dataConId . classDataCon) classes) $ - tcExtendTyConEnv [ (getName tycon, (kindToTcKind (tyConKind tycon), Nothing, tycon)) - | clas <- classes, - let tycon = classTyCon clas - ] $ - - -- 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 - tcInterfaceSigs unf_env decls `thenTc` \ sig_ids -> - tcExtendGlobalValEnv sig_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 --- trace "tc6" $ - 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 -> --- pprTrace "tc7" (ppr 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. --- pprTrace "tc8" emtpy $ - tcInstDecls2 inst_info `thenNF_Tc` \ (lie_instdecls, inst_binds) -> - tcClassDecls2 decls `thenNF_Tc` \ (lie_clasdecls, cls_binds) -> - - -- Check that "main" has the right signature - tcCheckMainSig mod_name `thenTc_` - - -- 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 - in - tcSimplifyTop lie_alldecls `thenTc` \ const_inst_binds -> + + let local_things = filter (isLocalThing this_mod) (nameEnvElts (getTcGEnv final_env)) + + -- Create any necessary "implicit" bindings (data constructors etc) + -- Should we create bindings for dictionary constructors? + -- They are always fully applied, and the bindings are just there + -- to support partial applications. But it's easier to let them through. + implicit_binds = andMonoBindList [ CoreMonoBind id (unfoldingTemplate unf) + | id <- implicitTyThingIds local_things + , let unf = idUnfolding id + , hasUnfolding unf + ] + + local_type_env :: TypeEnv + local_type_env = mkTypeEnv local_things + + all_local_rules = local_rules ++ more_local_rules' + in +-- traceTc (text "Tc10") `thenNF_Tc_` + returnTc (new_pcs, + TcResults { tc_env = local_type_env, + tc_binds = implicit_binds `AndMonoBinds` all_binds', + tc_insts = map iDFunId local_inst_info, + tc_fords = foi_decls ++ foe_decls', + tc_rules = all_local_rules + } + ) + where + tycl_decls = [d | TyClD d <- decls] + val_binds = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls] + source_rules = [d | RuleD d <- decls, not (isIfaceRuleDecl d)] +\end{code} - -- Backsubstitution. This must be done last. - -- Even tcCheckMainSig and tcSimplifyTop may do some unification. - let - all_binds = data_binds `AndMonoBinds` - val_binds `AndMonoBinds` - inst_binds `AndMonoBinds` - cls_binds `AndMonoBinds` - const_inst_binds `AndMonoBinds` - foe_binds - in - zonkTopBinds all_binds `thenNF_Tc` \ (all_binds', really_final_env) -> - tcSetGlobalValEnv really_final_env $ - zonkForeignExports foe_decls `thenNF_Tc` \ foe_decls' -> +\begin{code} +tcImports :: PersistentCompilerState + -> HomeSymbolTable + -> (Name -> Maybe Fixity) + -> Module + -> [RenamedHsDecl] + -> TcM (TcEnv, PersistentCompilerState, + [InstInfo], RenamedHsBinds, [TypecheckedRuleDecl]) + +-- tcImports is a slight mis-nomer. +-- It deals with everythign that could be an import: +-- type and class decls +-- interface signatures +-- instance decls +-- rule decls +-- These can occur in source code too, of course + +tcImports pcs hst get_fixity this_mod decls + = fixTc (\ ~(unf_env, _, _, _, _) -> + -- (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 + +-- traceTc (text "Tc1") `thenNF_Tc_` + tcTyAndClassDecls unf_env tycl_decls `thenTc` \ env -> + tcSetEnv env $ + + -- Typecheck the instance decls, includes deriving +-- traceTc (text "Tc2") `thenNF_Tc_` + tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs) + hst unf_env get_fixity this_mod + decls `thenTc` \ (new_pcs_insts, inst_env, local_inst_info, deriv_binds) -> + tcSetInstEnv inst_env $ + + -- 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 +-- traceTc (text "Tc3") `thenNF_Tc_` + tcInterfaceSigs unf_env tycl_decls `thenTc` \ sig_ids -> + tcExtendGlobalValEnv sig_ids $ + + + tcIfaceRules (pcs_rules pcs) this_mod iface_rules `thenNF_Tc` \ (new_pcs_rules, local_rules) -> + tcGetEnv `thenTc` \ unf_env -> let - thin_air_ids = map (lookupGlobalByKey really_final_env . nameUnique) thinAirIdNames - -- When looking up the thin-air names we must use - -- a global env that includes the zonked locally-defined Ids too - -- Hence using really_final_env + imported_things = filter (not . isLocalThing this_mod) (nameEnvElts (getTcGEnv unf_env)) + + new_pte :: PackageTypeEnv + new_pte = extendTypeEnvList (pcs_PTE pcs) imported_things + + new_pcs :: PersistentCompilerState + new_pcs = pcs { pcs_PTE = new_pte, + pcs_insts = new_pcs_insts, + pcs_rules = new_pcs_rules + } in - returnTc (really_final_env, - (all_binds', local_tycons, local_classes, inst_info, - foi_decls ++ foe_decls', - ddump_deriv, really_final_env, thin_air_ids)) - - -- End of outer fix loop - ) `thenTc` \ (final_env, stuff) -> - returnTc stuff - -get_val_decls decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls] -\end{code} - + returnTc (unf_env, new_pcs, local_inst_info, deriv_binds, local_rules) + ) + where + tycl_decls = [d | TyClD d <- decls] + iface_rules = [d | RuleD d <- decls, isIfaceRuleDecl d] +\end{code} + +%************************************************************************ +%* * +\subsection{Dumping output} +%* * +%************************************************************************ \begin{code} -tcCheckMainSig mod_name - | mod_name /= mAIN - = returnTc () -- A non-main module - - | otherwise - = -- Check that main is defined - tcLookupTyCon ioTyCon_NAME `thenTc` \ (_,_,ioTyCon) -> - tcLookupLocalValue main_NAME `thenNF_Tc` \ maybe_main_id -> - case maybe_main_id of { - Nothing -> failWithTc noMainErr ; - Just main_id -> - - -- Check that it has the right type (or a more general one) - let - expected_tau = typeToTcType (mkTyConApp ioTyCon [unitTy]) - in - tcId main_NAME `thenNF_Tc` \ (_, lie, main_tau) -> - tcSetErrCtxt mainTyCheckCtxt $ - unifyTauTy expected_tau - main_tau `thenTc_` - checkTc (isEmptyBag lie) (mainTyMisMatch expected_tau (idType main_id)) - } - - -mainTyCheckCtxt - = hsep [ptext SLIT("When checking that"), ppr main_NAME, ptext SLIT("has the required type")] - -noMainErr - = hsep [ptext SLIT("Module"), quotes (pprModule mAIN), - ptext SLIT("must include a definition for"), quotes (ppr main_NAME)] - -mainTyMisMatch :: TcType s -> TcType s -> ErrMsg -mainTyMisMatch expected actual - = hang (hsep [ppr main_NAME, ptext SLIT("has the wrong type")]) - 4 (vcat [ - hsep [ptext SLIT("Expected:"), ppr expected], - hsep [ptext SLIT("Inferred:"), ppr actual] - ]) +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 + = 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)) + | 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 = True -- For now + +ppr_gen_tycons tcs = vcat [ptext SLIT("{-# Generic type constructor details"), + vcat (map ppr_gen_tycon tcs), + ptext SLIT("#-}") + ] + +-- 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) + + | 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) + +pp_rules [] = empty +pp_rules rs = vcat [ptext SLIT("{-# RULES"), + nest 4 (vcat (map ppr rs)), + ptext SLIT("#-}")] \end{code}