[project @ 2005-02-24 09:58:23 by simonmar]
[ghc-base.git] / GHC / Err.lhs
1 \begin{code}
2 {-# OPTIONS_GHC -fno-implicit-prelude #-}
3 -----------------------------------------------------------------------------
4 -- |
5 -- Module      :  GHC.Err
6 -- Copyright   :  (c) The University of Glasgow, 1994-2002
7 -- License     :  see libraries/base/LICENSE
8 -- 
9 -- Maintainer  :  cvs-ghc@haskell.org
10 -- Stability   :  internal
11 -- Portability :  non-portable (GHC extensions)
12 --
13 -- The "GHC.Err" module defines the code for the wired-in error functions,
14 -- which have a special type in the compiler (with \"open tyvars\").
15 -- 
16 -- We cannot define these functions in a module where they might be used
17 -- (e.g., "GHC.Base"), because the magical wired-in type will get confused
18 -- with what the typechecker figures out.
19 -- 
20 -----------------------------------------------------------------------------
21
22 -- #hide
23 module GHC.Err 
24        (
25          irrefutPatError
26        , noMethodBindingError
27        , nonExhaustiveGuardsError
28        , patError
29        , recSelError
30        , recConError
31        , runtimeError              -- :: Addr#  -> a    -- Addr# points to UTF8 encoded C string
32
33        , absentErr                 -- :: a
34        , divZeroError              -- :: a
35
36        , error                     -- :: String -> a
37        , assertError               -- :: String -> Bool -> a -> a
38        
39        , undefined                 -- :: a
40        ) where
41
42 #ifndef __HADDOCK__
43 import GHC.Base
44 import GHC.List     ( span )
45 import GHC.Exception
46 #endif
47 \end{code}
48
49 %*********************************************************
50 %*                                                      *
51 \subsection{Error-ish functions}
52 %*                                                      *
53 %*********************************************************
54
55 \begin{code}
56 -- | 'error' stops execution and displays an error message.
57 error :: String -> a
58 error s = throw (ErrorCall s)
59
60 -- | A special case of 'error'.
61 -- It is expected that compilers will recognize this and insert error
62 -- messages which are more appropriate to the context in which 'undefined'
63 -- appears. 
64
65 undefined :: a
66 undefined =  error "Prelude.undefined"
67 \end{code}
68
69 %*********************************************************
70 %*                                                       *
71 \subsection{Compiler generated errors + local utils}
72 %*                                                       *
73 %*********************************************************
74
75 Used for compiler-generated error message;
76 encoding saves bytes of string junk.
77
78 \begin{code}
79 absentErr :: a
80
81 absentErr = error "Oops! The program has entered an `absent' argument!\n"
82 \end{code}
83
84 \begin{code}
85 recSelError, recConError, irrefutPatError, runtimeError,
86              nonExhaustiveGuardsError, patError, noMethodBindingError
87         :: Addr# -> a   -- All take a UTF8-encoded C string
88
89 recSelError              s = throw (RecSelError (unpackCStringUtf8# s)) -- No location info unfortunately
90 runtimeError             s = error (unpackCStringUtf8# s)               -- No location info unfortunately
91
92 nonExhaustiveGuardsError s = throw (PatternMatchFail (untangle s "Non-exhaustive guards in"))
93 irrefutPatError          s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern"))
94 recConError              s = throw (RecConError      (untangle s "Missing field in record construction"))
95 noMethodBindingError     s = throw (NoMethodError    (untangle s "No instance nor default method for class operation"))
96 patError                 s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in"))
97
98 assertError :: Addr# -> Bool -> a -> a
99 assertError str pred v 
100   | pred      = v
101   | otherwise = throw (AssertionFailed (untangle str "Assertion failed"))
102 \end{code}
103
104
105 (untangle coded message) expects "coded" to be of the form 
106
107         "location|details"
108
109 It prints
110
111         location message details
112
113 \begin{code}
114 untangle :: Addr# -> String -> String
115 untangle coded message
116   =  location
117   ++ ": " 
118   ++ message
119   ++ details
120   ++ "\n"
121   where
122     coded_str = unpackCStringUtf8# coded
123
124     (location, details)
125       = case (span not_bar coded_str) of { (loc, rest) ->
126         case rest of
127           ('|':det) -> (loc, ' ' : det)
128           _         -> (loc, "")
129         }
130     not_bar c = c /= '|'
131 \end{code}
132
133 Divide by zero.  We put it here because it is needed relatively early
134 in the libraries before the Exception type has been defined yet.
135
136 \begin{code}
137 {-# NOINLINE divZeroError #-}
138 divZeroError :: a
139 divZeroError = throw (ArithException DivideByZero)
140 \end{code}
141