Parse issues in DEFINE-FUNCTION when generating CHECK-TYPEs
There are a few small bugs when parsing the function body if generating check-types instead of the default, declare-based, behavior. These normally wouldn't require their own issue, but the description of the problems are too complicated to fit into a commit message.
The bugs are represented by the following cases, which will be added as tests (including the one that currently works).
Empty body
An empty body if :check-type t is an error.
(define-function (foo :check-type t) ())
The expected behavior is a function with an empty body, implicitly returning NIL, which is the case in the default behavior:
(define-function foo ())
This bug is because split-docstring in typed-bindings.lisp uses a destructuring-bind on a body that is allowed to be empty.
declare in body
Only docstrings are parsed in the body when :check-type t. This is also a bug in the helper function split-docstring in typed-bindings.lisp. This means that a declare can be placed after one or more calls to check-type, which will be an error. This can be reproduced with just (declare), but the examples below will try to provide a somewhat useful example of a declare by using optimize.
(define-function (foo :check-type t) ((x fixnum))
"Hello"
(declare (optimize (speed 3)))
x)
(define-function (foo :check-type t) ((x fixnum))
(declare (optimize (speed 3)))
"Hello"
x)
Note that the error does not happen if there is no typed variable in the lambda list because if that's the case then no check-type is placed before the declare form.
The solution here is to replace split-docstring with split-body and split the body in three (docstring, declare, and body) instead of in two (docstring and body).