From: James Y Knight <foom@fu...> - 2007-01-09 23:11:54
The following behavior seems ungood:
> (declaim (optimize (safety 3)))
> (defun foo (x) x)
> (declaim (ftype (function (t) fixnum) foo))
> (defun bar (x) (+ (foo x) 5))
> (bar :haha)
This code produces no warnings or errors. It fails to signal a TYPE-
ERROR when run, and instead returns a number like 8594561790 (YVMV).
This is, of course, allowed by the standard, since I lied about the
types, but shouldn't be allowed by SBCL in safety 3 (or, really, in
safety 1 either, IMO). What happens here is that by putting the ftype
second, it never gets checked by foo, as it has already been compiled
assuming no type information. Yet, the ftype *does* get used for type
propagation at call sites.
I assert that at a minimum, either the type should be checked and
propagated, OR it should be not checked and not propagated. This
would require storing with the function what ftype the function was
actually compiled with, and deriving types from that, instead of
using whatever ftype was declared after-the-fact.
It would also be good for a style warning to be emitted in the case
where you do a ftype declaration after a defun which has assumed
different types. (similar to STYLE-WARNING: new FTYPE proclamation
for FOO does not match old FTYPE proclamation).
What I'm not asking for is to have any new after-the-fact ftype
declarations for a function get type checked, because as I understand
it, that could have too much overhead, and really, you should have
put the ftype before the defun, anyways. With the combination of the
above two change, I don't think it's really necessary to do; the
style warning should be suitable warning that you're doing the wrong