Subject: Re: bug#78989: 31.0.50; classes and methods inheritance (defclass) seq-contains-p

From: Stefan Monnier <[email-masked]>
Date: Mon, 14 Jul 2025 18:08:47 -0400

> It would be good to improve the patch I installed by adding
> a compile-time warning since it's a better moment to fix the problem
> than when running the code.

The patch below adds such a warning.
Comments?

        Stefan
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index e1051eb7d4e..56272a12260 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -128,6 +128,28 @@ defclass
         (warnings '())
         (accessors ()))
 
+    ;; Check that we can consistently linearize the parent graphs.
+    (when (length> superclasses 1)
+      (let* ((aps (delq
+                   nil (mapcar (lambda (cn)
+                                 (let ((class (cl--find-class cn)))
+                                   (when class
+                                     (cl--class-allparents class))))
+                               superclasses)))
+             (conflict
+              (cl-block conflict
+                ;; FIXME: This mimics the code is `cl--class-allparents'.
+                (merge-ordered-lists
+                 (nconc aps (list superclasses))
+                 (lambda (remaining-lists)
+                   (cl-return-from conflict remaining-lists)))
+                nil)))
+        (when conflict
+          (push (cons superclasses
+                      (format-message
+                       "Inconsistent hierarchy: %S" conflict))
+                warnings))))
+
     ;; Collect the accessors we need to define.
     (setq slots (mapcar (lambda (x) (if (consp x) x (list x))) slots))
     (pcase-dolist (`(,sname . ,soptions) slots)
@@ -272,9 +294,10 @@ defclass
        ;; while keeping our above predicate clean.
 
        (eval-and-compile
-         (define-symbol-prop ',name 'cl-deftype-satisfies #',testsym2))
+         (define-symbol-prop ',name 'cl-deftype-satisfies #',testsym2)
 
-       (eieio-defclass-internal ',name ',superclasses ',slots ',options-and-doc)
+         (eieio-defclass-internal ',name ',superclasses
+                                  ',slots ',options-and-doc))
 
        ,@accessors
 
@@ -690,7 +713,8 @@ eieio-default-superclass
 Its slots are automatically adopted by classes with no specified parents."
   :abstract t)
 
-(setq eieio-default-superclass (cl--find-class 'eieio-default-superclass))
+(with-suppressed-warnings ((obsolete eieio-default-superclass))
+  (setq eieio-default-superclass (cl--find-class 'eieio-default-superclass)))
 
 (define-obsolete-function-alias 'standard-class
   #'eieio-default-superclass "26.1")