[project @ 2002-10-14 14:44:06 by sof]
[ghc-hetmet.git] / ghc / compiler / utils / Panic.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1992-2000
3 %
4 \section{Panic error messages}
5
6 Defines basic funtions for printing error messages.
7
8 It's hard to put these functions anywhere else without causing
9 some unnecessary loops in the module dependency graph.
10
11 \begin{code}
12 module Panic  
13    ( 
14      GhcException(..), ghcError, progName, 
15      panic, panic#, assertPanic, trace,
16      showException, showGhcException, Exception.throwDyn, tryMost,
17
18      Exception.Exception, 
19      Panic.try, -- try :: IO a -> IO (Either Exception a)
20                 -- This is Control.Exception.try in the new library story
21                 --         Exception.tryAllIO in GHC 4.08
22                 -- So it usefully hides the difference
23
24 #if __GLASGOW_HASKELL__ <= 408
25      catchJust, ioErrors, throwTo,
26 #endif
27    ) where
28
29 #include "HsVersions.h"
30
31 import Config
32 import FastTypes
33
34 import DYNAMIC
35 import qualified EXCEPTION as Exception
36 import TRACE            ( trace )
37 import UNSAFE_IO        ( unsafePerformIO )
38
39 import System
40 \end{code}
41
42 GHC's own exception type.
43
44 \begin{code}
45 ghcError :: GhcException -> a
46 ghcError e = Exception.throwDyn e
47
48 -- error messages all take the form
49 --
50 --      <location>: <error>
51 --
52 -- If the location is on the command line, or in GHC itself, then 
53 -- <location>="ghc".  All of the error types below correspond to 
54 -- a <location> of "ghc", except for ProgramError (where the string is
55 -- assumed to contain a location already, so we don't print one).
56
57 data GhcException
58   = PhaseFailed String          -- name of phase 
59                 ExitCode        -- an external phase (eg. cpp) failed
60   | Interrupted                 -- someone pressed ^C
61   | UsageError String           -- prints the short usage msg after the error
62   | CmdLineError String         -- cmdline prob, but doesn't print usage
63   | Panic String                -- the `impossible' happened
64   | InstallationError String    -- an installation problem
65   | ProgramError String         -- error in the user's code, probably
66   deriving Eq
67
68 progName = unsafePerformIO (getProgName)
69 {-# NOINLINE progName #-}
70
71 short_usage = "Usage: For basic information, try the `--help' option."
72    
73 showException :: Exception.Exception -> String
74 -- Show expected dynamic exceptions specially
75 showException (Exception.DynException d) | Just e <- fromDynamic d 
76                                          = show (e::GhcException)
77 showException other_exn                  = show other_exn
78
79 instance Show GhcException where
80   showsPrec _ e@(ProgramError _) = showGhcException e
81   showsPrec _ e = showString progName . showString ": " . showGhcException e
82
83 showGhcException (UsageError str)
84    = showString str . showChar '\n' . showString short_usage
85 showGhcException (PhaseFailed phase code)
86    = showString "phase `" . showString phase . 
87      showString "' failed (exitcode = " . shows int_code . 
88      showString ")"
89   where
90     int_code = 
91       case code of
92         ExitSuccess   -> (0::Int)
93         ExitFailure x -> x
94 showGhcException (CmdLineError str)
95    = showString str
96 showGhcException (ProgramError str)
97    = showString str
98 showGhcException (InstallationError str)
99    = showString str
100 showGhcException (Interrupted)
101    = showString "interrupted"
102 showGhcException (Panic s)
103    = showString ("panic! (the `impossible' happened, GHC version "
104                  ++ cProjectVersion ++ "):\n\t"
105                  ++ s ++ "\n\n"
106                  ++ "Please report it as a compiler bug "
107                  ++ "to glasgow-haskell-bugs@haskell.org,\n"
108                  ++ "or http://sourceforge.net/projects/ghc/.\n\n")
109
110 ghcExceptionTc = mkTyCon "GhcException"
111 {-# NOINLINE ghcExceptionTc #-}
112 instance Typeable GhcException where
113   typeOf _ = mkAppTy ghcExceptionTc []
114 \end{code}
115
116 Panics and asserts.
117
118 \begin{code}
119 panic :: String -> a
120 panic x = Exception.throwDyn (Panic x)
121
122 -- #-versions because panic can't return an unboxed int, and that's
123 -- what TAG_ is with GHC at the moment.  Ugh. (Simon)
124 -- No, man -- Too Beautiful! (Will)
125
126 panic# :: String -> FastInt
127 panic# s = case (panic s) of () -> _ILIT 0
128
129 assertPanic :: String -> Int -> a
130 assertPanic file line = 
131   Exception.throw (Exception.AssertionFailed 
132            ("ASSERT failed! file " ++ file ++ ", line " ++ show line))
133 \end{code}
134
135 \begin{code}
136 -- | tryMost is like try, but passes through Interrupted and Panic
137 -- exceptions.  Used when we want soft failures when reading interface
138 -- files, for example.
139
140 tryMost :: IO a -> IO (Either Exception.Exception a)
141 tryMost action = do r <- try action; filter r
142   where
143    filter (Left e@(Exception.DynException d))
144             | Just ghc_ex <- fromDynamic d
145                 = case ghc_ex of
146                     Interrupted -> Exception.throw e
147                     Panic _     -> Exception.throw e
148                     _other      -> return (Left e)
149    filter other 
150      = return other
151
152 #if __GLASGOW_HASKELL__ <= 408
153 try = Exception.tryAllIO
154 #else
155 try = Exception.try
156 #endif
157 \end{code}      
158
159 Compatibility stuff:
160
161 \begin{code}
162 #if __GLASGOW_HASKELL__ <= 408
163 catchJust = Exception.catchIO
164 ioErrors  = Exception.justIoErrors
165 throwTo   = Exception.raiseInThread
166 #endif
167 \end{code}