diff --git a/src/clos/change.lsp b/src/clos/change.lsp index 5fbd4cd09..a7f033749 100644 --- a/src/clos/change.lsp +++ b/src/clos/change.lsp @@ -215,6 +215,25 @@ class) +(defun slot-definitions-compatible-p (old-slotds new-slotds) + (loop for o = (pop old-slotds) + for n = (pop new-slotds) + while (and o n) + do (let ((old-alloc (slot-definition-allocation o)) + (new-alloc (slot-definition-allocation n))) + (unless (and (eq old-alloc new-alloc) + (eq (slot-definition-name o) + (slot-definition-name n)) + (or (not (eq old-alloc :instance)) + (= (slot-definition-location o) + (slot-definition-location n)))) + (return-from slot-definitions-compatible-p nil))) + finally + (return (and (null o) + (null n) + (null old-slotds) + (null new-slotds))))) + (defmethod make-instances-obsolete ((class class)) (setf (class-slots class) (copy-list (class-slots class))) class) diff --git a/src/clos/standard.lsp b/src/clos/standard.lsp index f8ee2031c..8c42aeb85 100644 --- a/src/clos/standard.lsp +++ b/src/clos/standard.lsp @@ -303,8 +303,14 @@ because it contains a reference to the undefined class~% ~A" (setf (class-precedence-list class) cpl) (let ((slots (compute-slots class))) - (setf (class-slots class) slots - (class-size class) (compute-instance-size slots) + ;; We don't change identity of class-slots when slot definitions + ;; are compatible to avoid making instances obsolete. This is + ;; allowed by the standard (see MAKE-INSTANCES-OBSOLETE). + (if (and (slot-boundp class 'slots) + (slot-definitions-compatible-p (class-slots class) slots)) + (map-into (class-slots class) #'identity slots) + (setf (class-slots class) slots)) + (setf (class-size class) (compute-instance-size slots) (class-default-initargs class) (compute-default-initargs class) (class-finalized-p class) t)) ;;