+@node Compiler Errors
+@comment node-name, next, previous, up
+@section Compiler Errors
+
+@menu
+* Type Errors at Compile Time::
+* Errors During Macroexpansion::
+* Read Errors::
+@end menu
+
+@node Type Errors at Compile Time
+@comment node-name, next, previous, up
+@subsection Type Errors at Compile Time
+@cindex Compile time type errors
+@cindex Type checking, at compile time
+
+If the compiler can prove at compile time that some portion of the
+program cannot be executed without a type error, then it will give a
+warning at compile time.
+
+It is possible that the offending code would never actually be
+executed at run-time due to some higher level consistency constraint
+unknown to the compiler, so a type warning doesn't always indicate an
+incorrect program.
+
+For example, consider this code fragment:
+
+@lisp
+(defun raz (foo)
+ (let ((x (case foo
+ (:this 13)
+ (:that 9)
+ (:the-other 42))))
+ (declare (fixnum x))
+ (foo x)))
+@end lisp
+
+Compilation produces this warning:
+
+@example
+; in: DEFUN RAZ
+; (CASE FOO (:THIS 13) (:THAT 9) (:THE-OTHER 42))
+; --> LET COND IF COND IF COND IF
+; ==>
+; (COND)
+;
+; caught WARNING:
+; This is not a FIXNUM:
+; NIL
+@end example
+
+In this case, the warning means that if @code{foo} isn't any of
+@code{:this}, @code{:that} or @code{:the-other}, then @code{x} will be
+initialized to @code{nil}, which the @code{fixnum} declaration makes
+illegal. The warning will go away if @code{ecase} is used instead of
+@code{case}, or if @code{:the-other} is changed to @code{t}.
+
+This sort of spurious type warning happens moderately often in the
+expansion of complex macros and in inline functions. In such cases,
+there may be dead code that is impossible to correctly execute. The
+compiler can't always prove this code is dead (could never be
+executed), so it compiles the erroneous code (which will always signal
+an error if it is executed) and gives a warning.
+
+@node Errors During Macroexpansion
+@comment node-name, next, previous, up
+@subsection Errors During Macroexpansion
+@cindex Macroexpansion, errors during
+
+The compiler handles errors that happen during macroexpansion, turning
+them into compiler errors. If you want to debug the error (to debug a
+macro), you can set @code{*break-on-signals*} to @code{error}. For
+example, this definition:
+
+@lisp
+(defun foo (e l)
+ (do ((current l (cdr current))
+ ((atom current) nil))
+ (when (eq (car current) e) (return current))))
+@end lisp
+
+gives this error:
+
+@example
+; in: DEFUN FOO
+; (DO ((CURRENT L (CDR CURRENT))
+; ((ATOM CURRENT) NIL))
+; (WHEN (EQ (CAR CURRENT) E) (RETURN CURRENT)))
+;
+; caught ERROR:
+; (in macroexpansion of (DO # #))
+; (hint: For more precise location, try *BREAK-ON-SIGNALS*.)
+; DO step variable is not a symbol: (ATOM CURRENT)
+@end example
+
+
+@node Read Errors
+@comment node-name, next, previous, up
+@subsection Read Errors
+@cindex Read errors, compiler
+
+SBCL's compiler does not attempt to recover from read errors when
+reading a source file, but instead just reports the offending
+character position and gives up on the entire source file.