Skip to content

defstruct :type vector restricts the vector length at high safety #1699

@slburson

Description

@slburson

Describe the bug

(defstruct (frob (:type vector))
  x y)

(defun access-frob (f)
  (declare (optimize (safety 3)))
  (frob-x f))

(access-frob (make-array 3))
  => error "#(NIL NIL NIL) is not of type (SIMPLE-ARRAY T (2))."

This is a misinterpretation of what :type vector means. (Admittedly, the spec doesn't say so explicitly.) The whole point of :type vector is that you want to have a variable-length object with some fixed slots at the beginning. There's no other reason to use it; it doesn't save either time or space compared to a structure class.

Expected behavior
The above example should return nil without signalling an error.

Context

Noticed in 2.5.0. I haven't tried HEAD, but this fix works and is not in HEAD:

diff --git a/src/lisp/kernel/lsp/defstruct.lisp b/src/lisp/kernel/lsp/defstruct.lisp
index f4cd5de8b..2bd487105 100644
--- a/src/lisp/kernel/lsp/defstruct.lisp
+++ b/src/lisp/kernel/lsp/defstruct.lisp
@@ -620,9 +620,7 @@
                  (vector (values #'defstruct-vector-reader-body
                                  #'defstruct-vector-writer-body
                                  nil
-                                 `(simple-array
-                                   ,element-type
-                                   (,(length slot-descriptions)))))
+                                 `(simple-array ,element-type (*))))
                  (list (values #'defstruct-list-reader-body
                                #'defstruct-list-writer-body
                                nil

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions