module TcModule (
typecheckModule,
SYN_IE(TcResults),
- SYN_IE(TcResultBinds),
SYN_IE(TcSpecialiseRequests),
SYN_IE(TcDDumpDeriv)
) where
IMP_Ubiq(){-uitous-}
-import HsSyn ( HsDecl(..), HsModule(..), HsBinds(..), HsExpr, MonoBinds,
+import HsSyn ( HsDecl(..), HsModule(..), HsBinds(..), HsExpr, MonoBinds(..),
TyDecl, SpecDataSig, ClassDecl, InstDecl, IfaceSig,
SpecInstSig, DefaultDecl, Sig, Fake, InPat,
- SYN_IE(RecFlag), nonRecursive,
+ SYN_IE(RecFlag), nonRecursive, GRHSsAndBinds, Match,
FixityDecl, IE, ImportDecl
)
import RnHsSyn ( SYN_IE(RenamedHsModule), RenamedFixityDecl(..) )
import TcHsSyn ( SYN_IE(TypecheckedHsBinds), SYN_IE(TypecheckedHsExpr),
- SYN_IE(TypecheckedDictBinds),
- TcIdOcc(..), zonkBinds )
+ SYN_IE(TypecheckedDictBinds), SYN_IE(TcMonoBinds),
+ SYN_IE(TypecheckedMonoBinds),
+ TcIdOcc(..), zonkTopBinds )
import TcMonad
-import Inst ( Inst, plusLIE )
+import Inst ( Inst, emptyLIE, plusLIE )
import TcBinds ( tcBindsAndThen )
import TcClassDcl ( tcClassDecls2 )
import TcDefaults ( tcDefaults )
import Name ( Name, isLocallyDefined, pprModule )
import Pretty
import TyCon ( TyCon, isSynTyCon )
-import Class ( GenClass, SYN_IE(Class), classGlobalIds )
+import Class ( GenClass, SYN_IE(Class), classSelIds )
import Type ( applyTyCon, mkSynTy, SYN_IE(Type) )
import PprType ( GenType, GenTyVar )
import TysWiredIn ( unitTy )
Outside-world interface:
\begin{code}
+--ToDo: put this in HsVersions
+#if __GLASGOW_HASKELL__ >= 200
+# define REAL_WORLD RealWorld
+#else
+# define REAL_WORLD _RealWorld
+#endif
+
+
-- Convenient type synonyms first:
type TcResults
- = (TcResultBinds,
+ = (TypecheckedMonoBinds,
[TyCon], [Class],
Bag InstInfo, -- Instance declaration information
TcSpecialiseRequests,
TcDDumpDeriv)
-type TcResultBinds
- = (TypecheckedHsBinds, -- record selector binds
- TypecheckedHsBinds, -- binds from class decls; does NOT
- -- include default-methods bindings
- TypecheckedHsBinds, -- binds from instance decls; INCLUDES
- -- class default-methods binds
- TypecheckedHsBinds, -- binds from value decls
-
- TypecheckedHsBinds) -- constant instance binds
-
type TcSpecialiseRequests
= FiniteMap TyCon [(Bool, [Maybe Type])]
-- source tycon specialisation requests
-> RnNameSupply
-> RenamedHsModule
-> MaybeErr
- (TcResults, -- if all goes well...
- Bag Warning) -- (we can still get warnings)
- (Bag Error, -- if we had errors...
+ (TcResults, -- if all goes well...
+ Bag Warning) -- (we can still get warnings)
+ (Bag Error, -- if we had errors...
Bag Warning)
typecheckModule us rn_name_supply mod
(HsModule mod_name verion exports imports fixities decls src_loc)
= tcAddSrcLoc src_loc $ -- record where we're starting
- -- Tie the knot for inteface-file value declaration signatures
- -- This info is only used inside the knot for type-checking the
- -- pragmas, which is done lazily [ie failure just drops the pragma
+ 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 dfuns.
+
+ -- The knot for instance information. This isn't used at all
+ -- till we type-check value declarations
+ fixTc ( \ ~(rec_inst_mapper, _, _, _, _) ->
+
+ -- Type-check the type and class decls
+ -- trace "tcTyAndClassDecls:" $
+ tcTyAndClassDecls1 unf_env rec_inst_mapper decls `thenTc` \ 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) ->
+
+ -- trace "tc4" $
+ buildInstanceEnvs inst_info `thenTc` \ inst_mapper ->
+
+ returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv)
+
+ -- End of inner fix loop
+ ) `thenTc` \ (_, env, inst_info, deriv_binds, ddump_deriv) ->
+
+ -- 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
+ let
+ tycons = getEnv_TyCons env
+ classes = getEnv_Classes env
+ 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)) $
- -- trace "tc1" $
-
- fixTc (\ ~(_, _, _, _, _, _, sig_ids) ->
-
- -- trace "tc2" $
- tcExtendGlobalValEnv sig_ids (
- -- The knot for instance information. This isn't used at all
- -- till we type-check value declarations
- fixTc ( \ ~(rec_inst_mapper, _, _, _, _) ->
+ -- 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 $
- -- Type-check the type and class decls
- -- trace "tcTyAndClassDecls:" $
- tcTyAndClassDecls1 rec_inst_mapper decls `thenTc` \ env ->
- -- trace "tc3" $
- -- Typecheck the instance decls, includes deriving
- tcSetEnv env (
- -- trace "tcInstDecls:" $
- tcInstDecls1 decls mod_name rn_name_supply
- ) `thenTc` \ (inst_info, deriv_binds, ddump_deriv) ->
+ -- Value declarations next.
+ -- We also typecheck any extra binds that came out of the "deriving" process
+ -- trace "tcBinds:" $
+ tcBindsAndThen
+ (\ is_rec binds1 (binds2, thing) -> (binds1 `AndMonoBinds` binds2, thing))
+ (get_val_decls decls `ThenBinds` deriv_binds)
+ ( tcGetEnv `thenNF_Tc` \ env ->
+ returnTc ((EmptyMonoBinds, env), emptyLIE)
+ ) `thenTc` \ ((val_binds, final_env), lie_valdecls) ->
+ tcSetEnv final_env $
- -- trace "tc4" $
- buildInstanceEnvs inst_info `thenTc` \ inst_mapper ->
- returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv)
+ -- Second pass over class and instance declarations,
+ -- to compile the bindings themselves.
+ -- trace "tc8" $
+ tcInstDecls2 inst_info `thenNF_Tc` \ (lie_instdecls, inst_binds) ->
+ tcClassDecls2 decls `thenNF_Tc` \ (lie_clasdecls, cls_binds) ->
- ) `thenTc` \ (_, env, inst_info, deriv_binds, ddump_deriv) ->
- -- trace "tc5" $
- tcSetEnv env (
- -- Default declarations
- tcDefaults decls `thenTc` \ defaulting_tys ->
- tcSetDefaultTys defaulting_tys ( -- for the iface sigs...
+ -- Check that "main" has the right signature
+ tcCheckMainSig mod_name `thenTc_`
- -- Create any necessary record selector Ids and their bindings
- -- "Necessary" includes data and newtype declarations
+ -- 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.)
+ -- trace "tc9" $
let
- tycons = getEnv_TyCons env
- classes = getEnv_Classes env
+ lie_alldecls = lie_valdecls `plusLIE` lie_instdecls `plusLIE` lie_clasdecls
in
- mkDataBinds tycons `thenTc` \ (data_ids, data_binds) ->
+ tcSimplifyTop lie_alldecls `thenTc` \ const_inst_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 classGlobalIds classes)) $
- -- 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 decls `thenTc` \ sig_ids ->
- tcGetEnv `thenNF_Tc` \ env ->
- -- trace "tc6" $
-
- returnTc (env, inst_info, data_binds, deriv_binds, ddump_deriv, defaulting_tys, sig_ids)
-
- )))) `thenTc` \ (env, inst_info, data_binds, deriv_binds, ddump_deriv, defaulting_tys, _) ->
+ -- 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
+ in
+ zonkTopBinds all_binds `thenNF_Tc` \ (all_binds', really_final_env) ->
- -- trace "tc7" $
- tcSetEnv env ( -- to the end...
- tcSetDefaultTys defaulting_tys ( -- ditto
+ returnTc (really_final_env, (all_binds', inst_info, ddump_deriv))
- -- Value declarations next.
- -- We also typecheck any extra binds that came out of the "deriving" process
- -- trace "tcBinds:" $
- tcBindsAndThen
- (\ binds1 (binds2, thing) -> (binds1 `ThenBinds` binds2, thing))
- (get_val_decls decls `ThenBinds` deriv_binds)
- ( -- Second pass over instance declarations,
- -- to compile the bindings themselves.
- -- trace "tc8" $
- tcInstDecls2 inst_info `thenNF_Tc` \ (lie_instdecls, inst_binds) ->
- tcClassDecls2 decls `thenNF_Tc` \ (lie_clasdecls, cls_binds) ->
- tcCheckMainSig mod_name `thenTc_`
- tcGetEnv `thenNF_Tc` \ env ->
- returnTc ( (EmptyBinds, (inst_binds, cls_binds, env)),
- lie_instdecls `plusLIE` lie_clasdecls
- )
- )
-
- `thenTc` \ ((val_binds, (inst_binds, cls_binds, final_env)), lie_alldecls) ->
-
- -- 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.)
- -- trace "tc9" $
- tcSimplifyTop lie_alldecls `thenTc` \ const_insts ->
-
-
- -- Backsubstitution. Monomorphic top-level decls may have
- -- been instantiated by subsequent decls, and the final
- -- simplification step may have instantiated some
- -- ambiguous types. So, sadly, we need to back-substitute
- -- over the whole bunch of bindings.
- --
- -- More horrible still, we have to do it in a careful order, so that
- -- all the TcIds are in scope when we come across them.
- --
- -- These bindings ought really to be bundled together in a huge
- -- recursive group, but HsSyn doesn't have recursion among Binds, only
- -- among MonoBinds. Sigh again.
- zonkBinds nullTyVarEnv nullIdEnv (MonoBind const_insts [] nonRecursive)
- `thenNF_Tc` \ (const_insts', ve1) ->
- zonkBinds nullTyVarEnv ve1 val_binds `thenNF_Tc` \ (val_binds', ve2) ->
+ -- End of outer fix loop
+ ) `thenTc` \ (final_env, (all_binds', inst_info, ddump_deriv)) ->
- zonkBinds nullTyVarEnv ve2 data_binds `thenNF_Tc` \ (data_binds', _) ->
- zonkBinds nullTyVarEnv ve2 inst_binds `thenNF_Tc` \ (inst_binds', _) ->
- zonkBinds nullTyVarEnv ve2 cls_binds `thenNF_Tc` \ (cls_binds', _) ->
let
- localids = getEnv_LocalIds final_env
tycons = getEnv_TyCons final_env
classes = getEnv_Classes final_env
in
-- FINISHED AT LAST
returnTc (
- (data_binds', cls_binds', inst_binds', val_binds', const_insts'),
+ all_binds',
local_tycons, local_classes, inst_info, tycon_specs,
ddump_deriv
- )))
+ )
get_val_decls decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls]
\end{code}