Too aggressive at avoiding make-instances-obsolete since 20.4.24
In ECL 20.4.24, you have introduced an optimization that avoids calling make-instances-obsolete in case the sets of old slots and new slots is compatible under class redefinition. The criteria are the allocation, the names, and the locations of the involved slots. However, this is potentially too restrictive outside of standard-class. In the general case, subclasses of standard-class may add other ways how slots may differ from each other that are not captured here.
This occurs in a test case for ContextL (see below), where slots can be 'special', which means that slot-values may be stored as symbol-values of symbols which are stored in the slot location in place of the direct values. (This allows for rebinding them with dynamic scope.) Whether a slot is special or not is indicated by a flag in the class definition. A slot can be non-special in a class, and then be turned into a special slot by redefining the same class. Previously, this worked in ECL, but now doesn't anymore because of the optimization above. I can imagine other circumstances where this may fail as well (for example in ORMs).
(asdf:load-system :contextl) (use-package :contextl) (defclass person () ((name :initarg :name :accessor person-name) (address :initarg :address :accessor person-address)) (:metaclass special-class)) (defvar *pascal* (make-instance 'person :name "Pascal" :address "Belgium")) (defun test () (print (person-name *pascal*)) (print (person-address *pascal*)) (eval '(defclass person () ((name :initarg :name :accessor person-name :special t) (address :initarg :address :accessor person-address :special t)) (:metaclass special-class))) (print (person-name *pascal*)) (print (person-address *pascal*)))
In previous ECL versions, this would print "Pascal" and "Belgium" twice, but now it signals an error the second time around, indicating that it tries to access the slot-value of a string (because the necessary update in shared-initialize by way of update-instance-for-redefined-class and make-instances-obsolete hasn't happened).
(lisp-implementation-version) "20.4.24" (ext:lisp-implementation-vcs-id) "UNKNOWN" (software-type) "Darwin" (software-version) "19.4.0" (machine-type) "x86_64" *features* (:QUICKLISP :ASDF-PACKAGE-SYSTEM :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-MACOSX :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :WALKER :CDR-1 :CDR-5 :DARWIN :FORMATTER :CDR-7 :ECL-WEAK-HASH :LITTLE-ENDIAN :LONG-LONG :UINT64-T :UINT32-T :UINT16-T :COMPLEX-FLOAT :LONG-FLOAT :UNICODE :DFFI :CLOS-STREAMS :CMU-FORMAT :UNIX :ECL-PDE :DLOPEN :CLOS :THREADS :BOEHM-GC :ANSI-CL :COMMON-LISP :FLOATING-POINT-EXCEPTIONS :IEEE-FLOATING-POINT :PACKAGE-LOCAL-NICKNAMES :CDR-14 :PREFIXED-API :FFI :X86_64 :COMMON :ECL)
ContextL is available through Quicklisp.