Commit a361055a authored by Daniel Kochmański's avatar Daniel Kochmański Committed by Marius Gerbershagen

defstruct: disallow defining structures of incompatible layouts

We signal an error if the structure is incompatible with an already defined
one. We concern ourself about slot names, their types, offset and number of
slots. Fixes #457.
parent 38f5dea0
Pipeline #46757970 (#211) passed with stage
@node Structures
@section Structures
@subsection Redefining a defstruct structure
@ansi{} says that consequences of redefining a @code{defstruct} are
undefined. @ecl{} defines this behavior to siganal an error if the new
structure is not compatible. Structures are incompatible when:
@table @asis
@item They have a different number of slots
This is particularily important for other structures which could have
included the current one and for already defined instances.
@item Slot name, type or offset is different
Binary compatibility between old and new instances.
@end table
@subsection C Reference
@subsubsection ANSI Dictionary
This diff is collapsed.
......@@ -46,6 +46,57 @@
(is-true (typep 3 '(nest (2) 3)))))
;;; 8. Structures
(my-struct make-my-struct my-struct-2 make-my-struct-2 my-struct-compatible-type)
(test ansi.8.redefine-compatible
(let (foo-1 foo-2 foo-3 foo-4)
(defstruct (my-struct (:constructor make-my-struct)) slot-1 slot-2)
(setq foo-1 (make-my-struct :slot-1 3 :slot-2 4))
(finishes (defstruct (my-struct (:constructor make-my-struct))
(slot-1 nil)
(slot-2 t)))
(setq foo-2 (make-my-struct :slot-1 3 :slot-2 4))
(finishes (defstruct (my-struct (:constructor make-my-struct))
(slot-1 3)
(slot-2 4)))
(setq foo-3 (make-my-struct))
(finishes (defstruct (my-struct (:constructor make-my-struct))
(slot-1 8 :type t :read-only nil)
(slot-2 8 :type t :read-only nil)))
(setq foo-4 (make-my-struct :slot-1 3 :slot-2 4))
(is (equalp foo-1 foo-2))
(is (equalp foo-2 foo-3))
(is (equalp foo-3 foo-4)))
(deftype my-struct-compatible-type () `(integer 0 10))
(defstruct (my-struct-2 (:constructor make-my-struct-2))
(slot-1 nil :type my-struct-compatible-type :read-only t))
(defstruct my-struct-2
(slot-1 nil :type (integer 0 10) :read-only t)))
(defstruct my-struct-2
(slot-1 4 :type (integer 0 10) :read-only t)))
(defstruct my-struct-2
(slot-1 4 :type (integer 0 10) :read-only nil)))))
(ext:with-clean-symbols (my-struct make-my-struct)
(test ansi.8.redefine-incompatible
(defstruct (my-struct (:constructor make-my-struct)) slot-1 slot-2)
;; different slot type
(signals error (defstruct (my-struct (:constructor make-my-struct))
(slot-1 nil :type integer)
(slot-2 t)))
;; too many slots
(signals error (defstruct (my-struct (:constructor make-my-struct)) slot-1 slot-2 slot-3))
;; too few slots
(signals error (defstruct (my-struct (:constructor make-my-struct)) slot-1))
;; incompatible names
(signals error (defstruct (my-struct (:constructor make-my-struct)) slot-1x slot-2x))
(finishes (make-my-struct))))
;; 12.2.* Numbers tests ;;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment