summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Err.lhs
blob: c1aa78fa4f59dce9c7bf1dc4ebaca0ba52c55593 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
% -----------------------------------------------------------------------------
% $Id: Err.lhs,v 1.1 2001/06/28 14:15:03 simonmar Exp $
%
% (c) The University of Glasgow, 1994-2000
%

\section[GHC.Err]{Module @GHC.Err@}

The GHC.Err module defines the code for the wired-in error functions,
which have a special type in the compiler (with "open tyvars").

We cannot define these functions in a module where they might be used
(e.g., GHC.Base), because the magical wired-in type will get confused
with what the typechecker figures out.

\begin{code}
{-# OPTIONS -fno-implicit-prelude #-}
module GHC.Err 
       (
         irrefutPatError
       , noMethodBindingError
       , nonExhaustiveGuardsError
       , patError
       , recSelError
       , recConError
       , recUpdError               -- :: String -> a

       , absentErr, parError       -- :: a
       , seqError                  -- :: a

       , error		           -- :: String -> a
       , assertError		   -- :: String -> Bool -> a -> a
       
       , undefined		   -- :: a
       ) where

import GHC.Base
import GHC.List     ( span )
import GHC.Exception
\end{code}

%*********************************************************
%*							*
\subsection{Error-ish functions}
%*							*
%*********************************************************

\begin{code}
-- error stops execution and displays an error message
error :: String -> a
error s = throw (ErrorCall s)

-- It is expected that compilers will recognize this and insert error
-- messages which are more appropriate to the context in which undefined 
-- appears. 

undefined :: a
undefined =  error "Prelude.undefined"
\end{code}

%*********************************************************
%*							 *
\subsection{Compiler generated errors + local utils}
%*							 *
%*********************************************************

Used for compiler-generated error message;
encoding saves bytes of string junk.

\begin{code}
absentErr, parError, seqError :: a

absentErr = error "Oops! The program has entered an `absent' argument!\n"
parError  = error "Oops! Entered GHCerr.parError (a GHC bug -- please report it!)\n"
seqError = error "Oops! Entered seqError (a GHC bug -- please report it!)\n"

\end{code}

\begin{code}
irrefutPatError
   , noMethodBindingError
   , nonExhaustiveGuardsError
   , patError
   , recSelError
   , recConError
   , recUpdError :: String -> a

noMethodBindingError     s = throw (NoMethodError (untangle s "No instance nor default method for class operation"))
irrefutPatError		 s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern"))
nonExhaustiveGuardsError s = throw (PatternMatchFail (untangle s "Non-exhaustive guards in"))
patError 		 s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in"))
recSelError 		 s = throw (RecSelError (untangle s "Missing field in record selection"))
recConError 		 s = throw (RecConError (untangle s "Missing field in record construction"))
recUpdError 		 s = throw (RecUpdError (untangle s "Record doesn't contain field(s) to be updated"))


assertError :: String -> Bool -> a -> a
assertError str pred v 
  | pred      = v
  | otherwise = throw (AssertionFailed (untangle str "Assertion failed"))

\end{code}


(untangle coded message) expects "coded" to be of the form 

	"location|details"

It prints

	location message details

\begin{code}
untangle :: String -> String -> String
untangle coded message
  =  location
  ++ ": " 
  ++ message
  ++ details
  ++ "\n"
  where
    (location, details)
      = case (span not_bar coded) of { (loc, rest) ->
	case rest of
	  ('|':det) -> (loc, ' ' : det)
	  _	    -> (loc, "")
	}
    not_bar c = c /= '|'
\end{code}