\begin{code} {-# OPTIONS_GHC -fno-implicit-prelude #-} ----------------------------------------------------------------------------- -- | -- Module : GHC.Err -- Copyright : (c) The University of Glasgow, 1994-2002 -- License : see libraries/base/LICENSE -- -- Maintainer : cvs-ghc@haskell.org -- Stability : internal -- Portability : non-portable (GHC extensions) -- -- 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. -- ----------------------------------------------------------------------------- module GHC.Err ( irrefutPatError , noMethodBindingError , nonExhaustiveGuardsError , patError , recSelError , recConError , runtimeError -- :: Addr# -> a -- Addr# points to UTF8 encoded C string , absentErr -- :: a , divZeroError -- :: a , error -- :: String -> a , assertError -- :: String -> Bool -> a -> a , undefined -- :: a ) where #ifndef __HADDOCK__ import GHC.Base import GHC.List ( span ) import GHC.Exception #endif \end{code} %********************************************************* %* * \subsection{Error-ish functions} %* * %********************************************************* \begin{code} -- | 'error' stops execution and displays an error message. error :: String -> a error s = throw (ErrorCall s) -- | A special case of 'error'. -- 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 :: a absentErr = error "Oops! The program has entered an `absent' argument!\n" \end{code} \begin{code} recSelError, recConError, irrefutPatError, runtimeError, nonExhaustiveGuardsError, patError, noMethodBindingError :: Addr# -> a -- All take a UTF8-encoded C string recSelError s = throw (RecSelError (unpackCStringUtf8# s)) -- No location info unfortunately runtimeError s = error (unpackCStringUtf8# s) -- No location info unfortunately nonExhaustiveGuardsError s = throw (PatternMatchFail (untangle s "Non-exhaustive guards in")) irrefutPatError s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern")) recConError s = throw (RecConError (untangle s "Missing field in record construction")) noMethodBindingError s = throw (NoMethodError (untangle s "No instance nor default method for class operation")) patError s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in")) assertError :: Addr# -> 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 :: Addr# -> String -> String untangle coded message = location ++ ": " ++ message ++ details ++ "\n" where coded_str = unpackCStringUtf8# coded (location, details) = case (span not_bar coded_str) of { (loc, rest) -> case rest of ('|':det) -> (loc, ' ' : det) _ -> (loc, "") } not_bar c = c /= '|' \end{code} Divide by zero. We put it here because it is needed relatively early in the libraries before the Exception type has been defined yet. \begin{code} {-# NOINLINE divZeroError #-} divZeroError :: a divZeroError = throw (ArithException DivideByZero) \end{code}