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