+;;; As noted by Paul Dietz for CMUCL, :CONC-NAME handling was a little
+;;; too fragile:
+(defstruct (conc-name-syntax :conc-name) a-conc-name-slot)
+(assert (eq (a-conc-name-slot (make-conc-name-syntax :a-conc-name-slot 'y))
+ 'y))
+;;; and further :CONC-NAME NIL was being wrongly treated:
+(defpackage "DEFSTRUCT-TEST-SCRATCH")
+(defstruct (conc-name-nil :conc-name)
+ defstruct-test-scratch::conc-name-nil-slot)
+(assert (= (defstruct-test-scratch::conc-name-nil-slot
+ (make-conc-name-nil :conc-name-nil-slot 1)) 1))
+(assert (raises-error? (conc-name-nil-slot (make-conc-name-nil))
+ undefined-function))
+\f
+;;; The named/typed predicates were a little fragile, in that they
+;;; could throw errors on innocuous input:
+(defstruct (list-struct (:type list) :named) a-slot)
+(assert (list-struct-p (make-list-struct)))
+(assert (not (list-struct-p nil)))
+(assert (not (list-struct-p 1)))
+(defstruct (offset-list-struct (:type list) :named (:initial-offset 1)) a-slot)
+(assert (offset-list-struct-p (make-offset-list-struct)))
+(assert (not (offset-list-struct-p nil)))
+(assert (not (offset-list-struct-p 1)))
+(assert (not (offset-list-struct-p '(offset-list-struct))))
+(assert (not (offset-list-struct-p '(offset-list-struct . 3))))
+(defstruct (vector-struct (:type vector) :named) a-slot)
+(assert (vector-struct-p (make-vector-struct)))
+(assert (not (vector-struct-p nil)))
+(assert (not (vector-struct-p #())))
+\f
+;;; bug 3d: type safety with redefined type constraints on slots
+(macrolet
+ ((test (type)
+ (let* ((base-name (intern (format nil "bug3d-~A" type)))
+ (up-name (intern (format nil "~A-up" base-name)))
+ (accessor (intern (format nil "~A-X" base-name)))
+ (up-accessor (intern (format nil "~A-X" up-name)))
+ (type-options (when type `((:type ,type)))))
+ `(progn
+ (defstruct (,base-name ,@type-options)
+ x y)
+ (defstruct (,up-name (:include ,base-name
+ (x "x" :type simple-string)
+ (y "y" :type simple-string))
+ ,@type-options))
+ (let ((ob (,(intern (format nil "MAKE-~A" up-name)))))
+ (setf (,accessor ob) 0)
+ (loop for decl in '(inline notinline)
+ for fun = `(lambda (s)
+ (declare (optimize (safety 3))
+ (,decl ,',up-accessor))
+ (,',up-accessor s))
+ do (assert (raises-error? (funcall (compile nil fun) ob)
+ type-error))))))))
+ (test nil)
+ (test list)
+ (test vector))
+
+(let* ((name (gensym))
+ (form `(defstruct ,name
+ (x nil :type (or null (function (integer)
+ (values number &optional foo)))))))
+ (eval (copy-tree form))
+ (eval (copy-tree form)))
+
+;;; 322: "DEFSTRUCT :TYPE LIST predicate and improper lists"
+;;; reported by Bruno Haible sbcl-devel "various SBCL bugs" from CLISP
+;;; test suite.
+(defstruct (bug-332a (:type list) (:initial-offset 5) :named))
+(defstruct (bug-332b (:type list) (:initial-offset 2) :named (:include bug-332a)))
+(assert (not (bug-332b-p (list* nil nil nil nil nil 'foo73 nil 'tail))))
+(assert (not (bug-332b-p 873257)))
+(assert (not (bug-332b-p '(1 2 3 4 5 x 1 2 bug-332a))))
+(assert (bug-332b-p '(1 2 3 4 5 x 1 2 bug-332b)))
+
+;;; Similar test for vectors, just for good measure.
+(defstruct (bug-332a-aux (:type vector)
+ (:initial-offset 5) :named))
+(defstruct (bug-332b-aux (:type vector)
+ (:initial-offset 2) :named
+ (:include bug-332a-aux)))
+(assert (not (bug-332b-aux-p #(1 2 3 4 5 x 1 premature-end))))
+(assert (not (bug-332b-aux-p 873257)))
+(assert (not (bug-332b-aux-p #(1 2 3 4 5 x 1 2 bug-332a-aux))))
+(assert (bug-332b-aux-p #(1 2 3 4 5 x 1 2 bug-332b-aux)))
+
+;;; In sbcl-0.8.11.8 FBOUNDPness potential collisions of structure
+;;; slot accessors signalled a condition at macroexpansion time, not
+;;; when the code was actually compiled or loaded.
+(let ((defstruct-form '(defstruct bug-in-0-8-11-8 x)))
+ (defun bug-in-0-8-11-8-x (z) (print "some unrelated thing"))
+ (handler-case (macroexpand defstruct-form)
+ (warning (c)
+ (error "shouldn't warn just from macroexpansion here"))))
+