Dear Mika,
I think this is not a bug - rather SBCL is correct:
> ;; --- Simple case ---
>
> ;; Ok
> (defun test-1 (a)
> (declare (type symbol a))
> (if a 'is-true))
>
> (test-1 :test)
>
> ;; Gives 1 note of deleting unreachable code
> ;; although logic is similar to test-1
> (defun test-2 ()
> (let ((a nil))
> (declare (type symbol a))
> (if a 'is-true)))
>
> (test-2)
test-1 doesn't complain, since it's perfectly reasonable: a might be nil
or not. However, in test-2, sbcl _knows_ that a is nil, since you've
made it so in the let and the declare can't change this. Thus a must be
nil at the if and 'is-true can never be evaluated.
>
> ;; --- More complicated case ---
>
> ;; Ok
> (defun test-3 (element listing)
> (declare (type list listing)
> (type symbol element))
> (if element
> (member element listing :test 'equal)))
>
> (test-3 :test '(:a :b))
>
> ;; Gives 11 notes of deleting unreachable code
> ;; although logic is similar to test-3.
> ;; This example is synthetic and not real production code.
> (defun test-4 ()
> (let ((listing (list :a :b))
> (element nil))
> (declare (type list listing)
> (type symbol element))
> (if element
> (member element listing :test 'equal))))
>
> (test-4)
>
Similarly here, element must be nil.
> ;; --- Another case ---
>
> ;; Gives note of deleting unreachable code.
> ;; Results are ok.
> (defun test-5 (&key (element nil))
> (declare (type symbol element))
> (if element
> (assert (member element '(:a :b :c) :test 'equal)
> nil "Not allowed...")))
>
> (test-5)
> (test-5 :element nil)
> (test-5 :element :a)
> (test-5 :element :x)
>
Here I'm not so sure what's supposed to happen - maybe someone more
knowledgeable can weigh in. Clearly, when presented with (test-5), sbcl
knows that element is nil etc. but I don't know how far the inferences
are carried.
Rupert
|