-%************************************************************************
-%* *
-\subsection{Error checking code}
-%* *
-%************************************************************************
+\begin{code}
+tcCheckMainSig mod_name
+ | not is_main && not is_ghc_main
+ = returnTc () -- A non-main module
+
+ | otherwise
+ = -- Check that main is defined
+ tcLookupTyCon tycon_name `thenTc` \ (_,_,tycon) ->
+ tcLookupLocalValue main_name `thenNF_Tc` \ maybe_main_id ->
+ case maybe_main_id of {
+ Nothing -> failTc (noMainErr mod_name main_name);
+ Just main_id ->
+
+ -- Check that it has the right type (or a more general one)
+ let
+ expected_ty | isSynTyCon tycon = mkSynTy tycon [unitTy]
+ | otherwise = applyTyCon tycon [unitTy]
+ -- This is bizarre. There ought to be a suitable function in Type.lhs!
+ in
+ tcInstType [] expected_ty `thenNF_Tc` \ expected_tau ->
+ tcId main_name `thenNF_Tc` \ (_, lie, main_tau) ->
+ tcSetErrCtxt (mainTyCheckCtxt main_name) $
+ unifyTauTy expected_tau
+ main_tau `thenTc_`
+ checkTc (isEmptyBag lie) (mainTyMisMatch main_name expected_ty (idType main_id))
+ }
+ where
+ is_main = mod_name == mAIN
+ is_ghc_main = mod_name == gHC_MAIN
+
+ main_name | is_main = main_NAME
+ | otherwise = mainPrimIO_NAME