import IfaceSyn
import TcSimplify
import TcTyClsDecls
+import TcUnify ( withBox )
import LoadIface
import RnNames
import RnEnv
import Id
import Var
import Module
-import UniqFM
+import LazyUniqFM
import Name
import NameEnv
import NameSet
import TyCon
+import TysWiredIn
import SrcLoc
import HscTypes
import ListSetOps
import TcHsType
import TcMType
import TcMatches
-import TcGadt
import RnTypes
import RnExpr
import IfaceEnv
import MkId
-import TysWiredIn
import IdInfo
import {- Kind parts of -} Type
import BasicTypes
import Util
import Bag
-import Control.Monad ( unless )
+import Control.Monad
import Data.Maybe ( isJust )
\end{code}
-- (b) tcExtCoreBindings doesn't need anything
-- (in fact, it might not even need to be in the scope of
-- this tcg_env at all)
- tcg_env <- importsFromLocalDecls False (mkFakeGroup ldecls)
- emptyUFM {- no fixity decls -} ;
+ avails <- getLocalNonValBinders (mkFakeGroup ldecls) ;
+ tc_envs <- extendGlobalRdrEnvRn False avails
+ emptyFsEnv {- no fixity decls -} ;
- setGblEnv tcg_env $ do {
+ setEnvs tc_envs $ do {
rn_decls <- checkNoErrs $ rnTyClDecls ldecls ;
mod_guts = ModGuts { mg_module = this_mod,
mg_boot = False,
- mg_usages = [], -- ToDo: compute usage
- mg_dir_imps = [], -- ??
+ mg_used_names = emptyNameSet, -- ToDo: compute usage
+ mg_dir_imps = emptyModuleEnv, -- ??
mg_deps = noDependencies, -- ??
mg_exports = my_exports,
mg_types = final_type_env,
Just main_name -> do
{ traceTc (text "checkMain found" <+> ppr main_mod <+> ppr main_fn)
- ; let { rhs = nlHsApp (nlHsVar runMainIOName) (nlHsVar main_name) }
- -- :Main.main :: IO () = runMainIO main
-
- ; (main_expr, ty) <- addErrCtxt mainCtxt $
- setSrcSpan (srcLocSpan (getSrcLoc main_name)) $
- tcInferRho rhs
+ ; let loc = srcLocSpan (getSrcLoc main_name)
+ ; ioTyCon <- tcLookupTyCon ioTyConName
+ ; (main_expr, res_ty)
+ <- addErrCtxt mainCtxt $
+ withBox liftedTypeKind $ \res_ty ->
+ tcMonoExpr (L loc (HsVar main_name)) (mkTyConApp ioTyCon [res_ty])
-- See Note [Root-main Id]
+ -- Construct the binding
+ -- :Main.main :: IO res_ty = runMainIO res_ty main
+ ; run_main_id <- tcLookupId runMainIOName
; let { root_main_name = mkExternalName rootMainKey rOOT_MAIN
(mkVarOccFS FSLIT("main"))
(getSrcSpan main_name)
- ; root_main_id = Id.mkExportedLocalId root_main_name ty
- ; main_bind = noLoc (VarBind root_main_id main_expr) }
+ ; root_main_id = Id.mkExportedLocalId root_main_name
+ (mkTyConApp ioTyCon [res_ty])
+ ; co = mkWpTyApps [res_ty]
+ ; rhs = nlHsApp (mkLHsWrap co (nlHsVar run_main_id)) main_expr
+ ; main_bind = noLoc (VarBind root_main_id rhs) }
; return (tcg_env { tcg_binds = tcg_binds tcg_env
`snocBag` main_bind,
-- None of the Ids should be of unboxed type, because we
-- cast them all to HValues in the end!
- mappM bad_unboxed (filter (isUnLiftedType . idType) zonked_ids) ;
+ mapM bad_unboxed (filter (isUnLiftedType . idType) zonked_ids) ;
traceTc (text "tcs 1") ;
- let { -- (a) Make all the bound ids "global" ids, now that
- -- they're notionally top-level bindings. This is
- -- important: otherwise when we come to compile an expression
- -- using these ids later, the byte code generator will consider
- -- the occurrences to be free rather than global.
- --
- -- (b) Tidy their types; this is important, because :info may
- -- ask to look at them, and :info expects the things it looks
- -- up to have tidy types
- global_ids = map globaliseAndTidy zonked_ids ;
+ let { global_ids = map globaliseAndTidy zonked_ids } ;
{- ---------------------------------------------
At one stage I removed any shadowed bindings from the type_env;
Hence this code is commented out
-------------------------------------------------- -}
- } ;
dumpOptTcRn Opt_D_dump_tc
(vcat [text "Bound Ids" <+> pprWithCommas ppr global_ids,
text "Typechecked expr" <+> ppr zonked_expr]) ;
- returnM (global_ids, zonked_expr)
+ return (global_ids, zonked_expr)
}
where
bad_unboxed id = addErr (sep [ptext SLIT("GHCi can't bind a variable of unlifted type:"),
nest 2 (ppr id <+> dcolon <+> ppr (idType id))])
globaliseAndTidy :: Id -> Id
-globaliseAndTidy id
--- Give the Id a Global Name, and tidy its type
+globaliseAndTidy id -- Note [Interactively-bound Ids in GHCi]
= Id.setIdType (globaliseId VanillaGlobal id) tidy_type
where
tidy_type = tidyTopType (idType id)
\end{code}
+Note [Interactively-bound Ids in GHCi]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The Ids bound by previous Stmts in Template Haskell are currently
+ a) GlobalIds
+ b) with an Internal Name (not External)
+ c) and a tidied type
+
+ (a) They must be GlobalIds (not LocalIds) otherwise when we come to
+ compile an expression using these ids later, the byte code
+ generator will consider the occurrences to be free rather than
+ global.
+
+ (b) They retain their Internal names becuase we don't have a suitable
+ Module to name them with. We could revisit this choice.
+
+ (c) Their types are tidied. This is important, because :info may ask
+ to look at them, and :info expects the things it looks up to have
+ tidy types
+
+
+--------------------------------------------------------------------------
+ Typechecking Stmts in GHCi
+
Here is the grand plan, implemented in tcUserStmt
What you type The IO [HValue] that hscStmt returns
; runPlans [ -- Plan A
do { stuff@([it_id], _) <- tcGhciStmts [bind_stmt, print_it]
; it_ty <- zonkTcType (idType it_id)
- ; ifM (isUnitTy it_ty) failM
+ ; when (isUnitTy it_ty) failM
; return stuff },
-- Plan B; a naked bind statment
; let print_plan = do
{ stuff@([v_id], _) <- tcGhciStmts [stmt, print_v]
; v_ty <- zonkTcType (idType v_id)
- ; ifM (isUnitTy v_ty || not (isTauTy v_ty)) failM
+ ; when (isUnitTy v_ty || not (isTauTy v_ty)) failM
; return stuff }
-- The plans are:
= do { ioTyCon <- tcLookupTyCon ioTyConName ;
ret_id <- tcLookupId returnIOName ; -- return @ IO
let {
- io_ty = mkTyConApp ioTyCon [] ;
ret_ty = mkListTy unitTy ;
io_ret_ty = mkTyConApp ioTyCon [ret_ty] ;
- tc_io_stmts stmts = tcStmts DoExpr (tcDoStmt io_ty) stmts
- (emptyRefinement, io_ret_ty) ;
+ tc_io_stmts stmts = tcStmts DoExpr tcDoStmt stmts io_ret_ty ;
names = map unLoc (collectLStmtsBinders stmts) ;
-- OK, we're ready to typecheck the stmts
traceTc (text "TcRnDriver.tcGhciStmts: tc stmts") ;
((tc_stmts, ids), lie) <- getLIE $ tc_io_stmts stmts $ \ _ ->
- mappM tcLookupId names ;
+ mapM tcLookupId names ;
-- Look up the names right in the middle,
-- where they will all be in scope
= do { dflags <- getDOpts ;
-- Dump short output if -ddump-types or -ddump-tc
- ifM (dopt Opt_D_dump_types dflags || dopt Opt_D_dump_tc dflags)
- (dumpTcRn short_dump) ;
+ when (dopt Opt_D_dump_types dflags || dopt Opt_D_dump_tc dflags)
+ (dumpTcRn short_dump) ;
-- Dump bindings if -ddump-tc
dumpOptTcRn Opt_D_dump_tc (mkDumpDoc "Typechecker" full_dump)
tcCoreDump mod_guts
= do { dflags <- getDOpts ;
- ifM (dopt Opt_D_dump_types dflags || dopt Opt_D_dump_tc dflags)
- (dumpTcRn (pprModGuts mod_guts)) ;
+ when (dopt Opt_D_dump_types dflags || dopt Opt_D_dump_tc dflags)
+ (dumpTcRn (pprModGuts mod_guts)) ;
-- Dump bindings if -ddump-tc
dumpOptTcRn Opt_D_dump_tc (mkDumpDoc "Typechecker" full_dump) }