The following code declaims ftype of both (foo) and (setf foo). For some reason, the ftype of (foo) is used to check the arguments passed to (setf foo), causing errors.
(declaim (ftype (function (cons) t) foo)) (declaim (ftype (function (t cons) t) (setf foo))) (defun foo (cons) (first cons)) (defun (setf foo) (value cons) (setf (first cons) value)) (defvar *c* (cons 'x 'y)) (foo *c*) ;; correctly returns 'x (setf (foo *c*) 'z) ;; signals an error: ;; Z is not of type CONS. ;; [Condition of type TYPE-ERROR]
I'd say it's a bug, since a declaim on (foo) should not affect (setf foo).
The only workarounds I found are:
1) not declaim ftype of (foo)
2) declaim ftype of (foo) as:
(declaim (ftype (function (t) t) foo))
then recompile (setf foo).
Both solution are clearly sub-optimal.
P.S. tested on ecl-13.5.1 on Debian GNU/Linux 7 (x86_64). ecl was compiled with:
./configure --enable-threads --enable-boehm --enable-c99complex --with-__thread --with-clx --with-dffi --with-sse=yes