1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 14:30:50 -08:00

(cl--class-allparents): Fix bug#78989

Give more control over ordering when linearizing the
parent graph and avoid pathological misbehavior (such as
placing `t` in the middle of the linearization instead of the
end) when we can't "do it right".

* lisp/subr.el (merge-ordered-lists): Degrade more gracefully in case
of inconsistent hierarchies and don't do it silently.

* lisp/emacs-lisp/cl-preloaded.el (cl--class-allparents): Use the local
ordering to break ties, as in the C3 algorithm.
This commit is contained in:
Stefan Monnier 2025-07-14 12:37:11 -04:00
parent c8b6e90b4e
commit 7f1cae9637
2 changed files with 50 additions and 28 deletions

View file

@ -285,8 +285,14 @@
(defun cl--class-allparents (class)
(cons (cl--class-name class)
(merge-ordered-lists (mapcar #'cl--class-allparents
(cl--class-parents class)))))
(let* ((parents (cl--class-parents class))
(aps (mapcar #'cl--class-allparents parents)))
(if (null (cdr aps)) ;; Single-inheritance fast-path.
(car aps)
(merge-ordered-lists
;; Add the list of immediate parents, to control which
;; linearization is chosen. doi:10.1145/236337.236343
(nconc aps (list (mapcar #'cl--class-name parents))))))))
(cl-defstruct (built-in-class
(:include cl--class)