+ :: DynFlags
+ -> PersistentCompilerState
+ -> HomeSymbolTable
+ -> ModIface -- Iface for this module (just module & fixities)
+ -> PrintUnqualified -- For error printing
+ -> (SyntaxMap, [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 (syn_map, decls)
+ = do { maybe_tc_result <- typecheck dflags syn_map 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
+
+---------------
+typecheckIface
+ :: DynFlags
+ -> PersistentCompilerState
+ -> HomeSymbolTable
+ -> ModIface -- Iface for this module (just module & fixities)
+ -> (SyntaxMap, [RenamedHsDecl])
+ -> IO (Maybe (PersistentCompilerState, TypeEnv, [TypecheckedRuleDecl]))
+ -- The new PCS is Augmented with imported information,
+ -- (but not stuff from this module).
+ -- The TcResults returned contains only the environment
+ -- and rules.
+
+
+typecheckIface dflags pcs hst mod_iface (syn_map, decls)
+ = do { maybe_tc_stuff <- typecheck dflags syn_map pcs hst alwaysQualify $
+ tcIfaceImports pcs hst get_fixity this_mod decls
+ ; printIfaceDump dflags maybe_tc_stuff
+ ; return maybe_tc_stuff }
+ 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
+
+ tcIfaceImports pcs hst get_fixity this_mod decls
+ = fixTc (\ ~(unf_env, _, _, _, _) ->
+ tcImports unf_env pcs hst get_fixity this_mod decls
+ ) `thenTc` \ (env, new_pcs, local_inst_info,
+ deriv_binds, local_rules) ->
+ ASSERT(nullBinds deriv_binds)
+ let
+ local_things = filter (isLocalThing this_mod)
+ (nameEnvElts (getTcGEnv env))
+ local_type_env :: TypeEnv
+ local_type_env = mkTypeEnv local_things
+ in
+
+ -- throw away local_inst_info
+ returnTc (new_pcs, local_type_env, local_rules)
+
+---------------
+typecheckExpr :: DynFlags
+ -> Bool -- True <=> wrap in 'print' to get a result of IO type
+ -> PersistentCompilerState
+ -> HomeSymbolTable
+ -> PrintUnqualified -- For error printing
+ -> Module
+ -> (SyntaxMap,
+ RenamedHsExpr, -- The expression itself
+ [RenamedHsDecl]) -- Plus extra decls it sucked in from interface files
+ -> IO (Maybe (PersistentCompilerState, TypecheckedHsExpr, TcType))
+
+typecheckExpr dflags wrap_io pcs hst unqual this_mod (syn_map, expr, decls)
+ = typecheck dflags syn_map pcs hst unqual $
+
+ -- use the default default settings, i.e. [Integer, Double]
+ tcSetDefaultTys defaultDefaultTys $
+
+ -- Typecheck the extra declarations
+ fixTc (\ ~(unf_env, _, _, _, _) ->
+ tcImports unf_env 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 )
+
+ -- Now typecheck the expression
+ tcSetEnv env $
+ tc_expr expr `thenTc` \ (expr', expr_ty) ->
+ zonkExpr expr' `thenNF_Tc` \ zonked_expr ->
+ zonkTcType expr_ty `thenNF_Tc` \ zonked_ty ->
+ ioToTc (dumpIfSet_dyn dflags
+ Opt_D_dump_tc "Typechecked" (ppr zonked_expr)) `thenNF_Tc_`
+ returnTc (new_pcs, zonked_expr, zonked_ty)
+
+ where
+ get_fixity :: Name -> Maybe Fixity
+ get_fixity n = pprPanic "typecheckExpr" (ppr n)
+
+ smpl_doc = ptext SLIT("main expression")
+
+ -- Typecheck it, wrapping in 'print' if necessary to
+ -- get a result of type IO t. Returns the result type
+ -- that is free in the result type
+ tc_expr e
+ | wrap_io = tryTc_ (tc_io_expr (HsApp (HsVar printName) e)) -- Recovery case
+ (tc_io_expr e) -- Main case
+ | otherwise = newTyVarTy openTypeKind `thenTc` \ ty ->
+ tcMonoExpr e ty `thenTc` \ (e', lie) ->
+ tcSimplifyInfer smpl_doc (varSetElems (tyVarsOfType ty)) lie
+ `thenTc` \ (qtvs, lie_free, dict_binds, dict_ids) ->
+ tcSimplifyTop lie_free `thenTc` \ const_binds ->
+ let all_expr = mkHsLet const_binds $
+ TyLam qtvs $
+ DictLam dict_ids $
+ mkHsLet dict_binds $
+ e'
+ all_expr_ty = mkForAllTys qtvs $
+ mkFunTys (map idType dict_ids) $
+ ty
+ in
+ returnTc (all_expr, all_expr_ty)
+ where
+ tc_io_expr e = newTyVarTy openTypeKind `thenTc` \ ty ->
+ tcLookupTyCon ioTyConName `thenNF_Tc` \ ioTyCon ->
+ let
+ res_ty = mkTyConApp ioTyCon [ty]
+ in
+ tcMonoExpr e res_ty `thenTc` \ (e', lie) ->
+ tcSimplifyTop lie `thenTc` \ const_binds ->
+ let all_expr = mkHsLet const_binds e' in
+ returnTc (all_expr, res_ty)
+
+---------------
+typecheck :: DynFlags
+ -> SyntaxMap
+ -> PersistentCompilerState
+ -> HomeSymbolTable
+ -> PrintUnqualified -- For error printing
+ -> TcM r
+ -> IO (Maybe r)
+
+typecheck dflags syn_map pcs hst unqual thing_inside
+ = do { showPass dflags "Typechecker";
+ ; env <- initTcEnv syn_map hst (pcs_PTE pcs)
+
+ ; (maybe_tc_result, errs) <- initTc dflags env thing_inside
+
+ ; printErrorsAndWarnings unqual errs
+
+ ; if errorsFound errs then
+ return Nothing
+ else
+ return maybe_tc_result
+ }