GNU bug report logs - #79672
30.2.50; infinite loop with circular face inheritance

Previous Next

Package: emacs;

Reported by: "J.D. Smith" <jdtsmith <at> gmail.com>

Date: Wed, 22 Oct 2025 01:17:02 UTC

Severity: normal

Found in version 30.2.50

Done: Eli Zaretskii <eliz <at> gnu.org>

To reply to this bug, email your comments to 79672 AT debbugs.gnu.org.
There is no need to reopen the bug first.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 22 Oct 2025 01:17:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to "J.D. Smith" <jdtsmith <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 22 Oct 2025 01:17:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: "J.D. Smith" <jdtsmith <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.2.50; infinite loop with circular face inheritance
Date: Tue, 21 Oct 2025 21:16:21 -0400
[Message part 1 (text/plain, inline)]
TLDR: link -> button -> link -> button -> ... traps
      face_inherited_attr(xfaces.c) in an infinite loop.

I have a default theme that inherits `link' from the `button' face.
Other themes like `modus' inherit `button' from the `link' face.  If I
load one after the other, I end up with a circular inheritance pattern
between these two face.

I understand xfaces has mechanisms in place to deal with this.
`named_merge_points' is designed to detect and circumvent face
inheritance cycles, but this protection is not active for the specific
case outlined below.  The relevant backtrace is attached.

The call pattern in face_inherited_attr, where the story begins, is as
follow:

0. Prequel 

   a. named_merge_points = (org-link) (note that `org-link' just
      inherits from `link').

   b. The attribute being looked up in face_inherited_attr is at
      LFACE_EXTEND_INDEX, but I don't think that matters.
      
   c. Importantly, though, this attribute is `unspecified' for both of
      the faces `link' and `button'.

1. In the while loop, starting with the `link' face, we have an
   UNSPECIFIEDP (attr_val), as mentioned.

2. `link' indeed inherits from `button', so the loop is entered, setting
   parent_face=button.

3. parent_face is not CONSP (it's just `button'), so we proceed to

    ok = get_lface_attributes (w, f, parent_face, inherited_attrs,
          		     false, named_merge_points);

4. There is no face remapping in place, so inside the call to
   get_lface_attributes we fall quickly through to:

    return get_lface_attributes_no_remap (f, face_name, attrs, signal_p);

   Notice there is no named_merge_points argument here, and that, unlike
   the other branch, this no-remap branch does /not/ push a named merge
   point.  We are on our way to trouble.

5. get_lface_attributes_no_remap copies the attrs into the face, and
   naturally returns ok=true, since the parent face `button' is indeed a
   valid face.

6. We come again to the top of the while(UNSPECIFIEDP (attr_val)) loop
   in face_inherited_attr.  Again the :extend attribute (this time, of
   `button') is unspecified, and again the face has a parent: `link'.

7. And so we enter an infinite loop, endlessly checking
   link->button->link->button->... to try to in vain to find a
   !UNSPECIFIEDP (attr_val).  Emacs hangs.


[xfaces_bt.txt (text/plain, inline)]
* thread #2, name = 'org.gnu.Emacs.lisp-main', stop reason = step over
  * frame #0: 0x00000001005ad48c Emacs`face_inherited_attr(w=0x0000000145b96830, f=0x0000000145b95830, attrs=(struct Lisp_Symbol *) $4520 = 0x00000002710789c0, attr_idx=LFACE_EXTEND_INDEX, named_merge_points=0x00000001702b0d30) at xfaces.c:2481:8 [opt]
    frame #1: 0x00000001005ac23c Emacs`merge_named_face(w=0x0000000145b96830, f=0x0000000145b95830, face_name=<unavailable>, to=(struct Lisp_Symbol *) $4529 = 0x0000000271079008, named_merge_points=0x00000001702b0d30, attr_filter=LFACE_EXTEND_INDEX) at xfaces.c:2525:18 [opt]
    frame #2: 0x00000001005a8a20 Emacs`merge_face_ref(w=<unavailable>, f=0x0000000145b95830, face_ref=(struct Lisp_Symbol *) $4547 = 0x000000014608e610, to=(struct Lisp_Symbol *) $4556 = 0x0000000271079008, err_msgs=true, named_merge_points=0x0000000000000000, attr_filter=LFACE_EXTEND_INDEX) at xfaces.c:3011:12 [opt]
    frame #3: 0x00000001005a8d4c Emacs`merge_face_ref(w=<unavailable>, f=0x0000000145b95830, face_ref=<unavailable>, to=(struct Lisp_Symbol *) $4562 = 0x0000000271079008, err_msgs=true, named_merge_points=0x0000000000000000, attr_filter=LFACE_EXTEND_INDEX) at xfaces.c:3003:10 [opt]
    frame #4: 0x00000001005a8d14 Emacs`merge_face_ref(w=<unavailable>, f=0x0000000145b95830, face_ref=(struct Lisp_Cons *) $4568 = 0x00000001284f6e50, to=(struct Lisp_Symbol *) $4574 = 0x0000000271079008, err_msgs=true, named_merge_points=0x0000000000000000, attr_filter=LFACE_EXTEND_INDEX) at xfaces.c:3000:11 [opt]
    frame #5: 0x00000001005ab564 Emacs`face_at_buffer_position(w=0x0000000145b96830, pos=<unavailable>, endptr=0x00000001702b14a8, limit=<unavailable>, mouse=false, base_face_id=0, attr_filter=LFACE_EXTEND_INDEX) at xfaces.c:6961:5 [opt]
    frame #6: 0x000000010052ce64 Emacs`face_at_pos(it=0x00000001702b3d98, attr_filter=LFACE_EXTEND_INDEX) at xdisp.c:4673:14 [opt]
    frame #7: 0x00000001005327d0 Emacs`extend_face_to_end_of_line(it=0x00000001702b3d98) at xdisp.c:23873:10 [opt]
    frame #8: 0x0000000100511b38 Emacs`display_line(it=0x00000001702b3d98, cursor_vpos=<unavailable>) at xdisp.c:25729:9 [opt]
    frame #9: 0x00000001005107a8 Emacs`try_window(window=(struct window *) $4580 = 0x0000000145b96830, pos=(charpos = 281955, bytepos = 282008), flags=1) at xdisp.c:21203:11 [opt]
    frame #10: 0x00000001005392a8 Emacs`redisplay_window(window=(struct window *) $4586 = 0x0000000145b96830, just_this_one_p=false) at xdisp.c:20572:8 [opt]
    frame #11: 0x0000000100536b20 Emacs`redisplay_window_0(window=<unavailable>) at xdisp.c:18052:5 [opt]
    frame #12: 0x0000000100643494 Emacs`internal_condition_case_1(bfun=(Emacs`redisplay_window_0 at xdisp.c:18051:7), arg=(struct window *) $4592 = 0x0000000145b96830, handlers=<unavailable>, hfun=(Emacs`redisplay_window_error at xdisp.c:18032)) at eval.c:1637:25 [opt]
    frame #13: 0x000000010053619c Emacs`redisplay_windows(window=(struct window *) $4598 = 0x0000000145b96830) at xdisp.c:18021:4 [opt]
    frame #14: 0x00000001005361d4 Emacs`redisplay_windows(window=(struct window *) $4604 = 0x0000000145b1ffc8) at xdisp.c:18015:2 [opt]
    frame #15: 0x00000001005361d4 Emacs`redisplay_windows(window=(struct window *) $4610 = 0x0000000121b6b030) at xdisp.c:18015:2 [opt]
    frame #16: 0x000000010050a258 Emacs`redisplay_internal at xdisp.c:17419:5 [opt]
    frame #17: 0x000000010050f7c0 Emacs`redisplay at xdisp.c:16594:3 [opt] [artificial]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 22 Oct 2025 12:51:02 GMT) Full text and rfc822 format available.

Message #8 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: "J.D. Smith" <jdtsmith <at> gmail.com>
Cc: 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 22 Oct 2025 15:50:08 +0300
> From: "J.D. Smith" <jdtsmith <at> gmail.com>
> Date: Tue, 21 Oct 2025 21:16:21 -0400
> 
> TLDR: link -> button -> link -> button -> ... traps
>       face_inherited_attr(xfaces.c) in an infinite loop.
> 
> I have a default theme that inherits `link' from the `button' face.
> Other themes like `modus' inherit `button' from the `link' face.  If I
> load one after the other, I end up with a circular inheritance pattern
> between these two face.

Thanks.  I don't know when and even whether I will have time to work
on this case of using the rope Emacs gives us to hang ourselves, but
in the interests of making this issue easier to work on, would you
mind producing the smallest Lisp snippet that reproduces the problem,
starting from "emacs -Q"?

TIA




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 22 Oct 2025 15:57:02 GMT) Full text and rfc822 format available.

Message #11 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: "J.D. Smith" <jdtsmith <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 22 Oct 2025 11:56:35 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>> Date: Tue, 21 Oct 2025 21:16:21 -0400
>> 
>> TLDR: link -> button -> link -> button -> ... traps
>>       face_inherited_attr(xfaces.c) in an infinite loop.
>> 
>> I have a default theme that inherits `link' from the `button' face.
>> Other themes like `modus' inherit `button' from the `link' face.  If I
>> load one after the other, I end up with a circular inheritance pattern
>> between these two face.
>
> Thanks.  I don't know when and even whether I will have time to work
> on this case of using the rope Emacs gives us to hang ourselves, but

I don't think it's fair to say that Emacs /gives/ us this particular
rope, since it appears xfaces includes specific logic and data
structures explicitly designed to prevent circular face inheritance from
hanging the process (named_merge_point).

> in the interests of making this issue easier to work on, would you
> mind producing the smallest Lisp snippet that reproduces the problem,
> starting from "emacs -Q"?

Sure, evaluate this in *scratch*:

  (progn
    (font-lock-mode -1)
    (set-face-attribute 'button nil :inherit 'link)
    (set-face-attribute 'link nil :inherit 'button)
    (dolist (x '(link button))
      (set-face-attribute x nil :extend 'unspecified))
    (insert "\n\n" (propertize "TEST LINK\n" 'face '(link :extend t)))
    (redisplay t))

To be clear, no one would ever do this on purpose, but combinations of
themes in circulation effectively do.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 23 Oct 2025 07:38:02 GMT) Full text and rfc822 format available.

Message #14 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: "J.D. Smith" <jdtsmith <at> gmail.com>
Cc: 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 23 Oct 2025 10:35:54 +0300
> From: "J.D. Smith" <jdtsmith <at> gmail.com>
> Cc: 79672 <at> debbugs.gnu.org
> Date: Wed, 22 Oct 2025 11:56:35 -0400
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> From: "J.D. Smith" <jdtsmith <at> gmail.com>
> >> Date: Tue, 21 Oct 2025 21:16:21 -0400
> >> 
> >> TLDR: link -> button -> link -> button -> ... traps
> >>       face_inherited_attr(xfaces.c) in an infinite loop.
> >> 
> >> I have a default theme that inherits `link' from the `button' face.
> >> Other themes like `modus' inherit `button' from the `link' face.  If I
> >> load one after the other, I end up with a circular inheritance pattern
> >> between these two face.
> >
> > Thanks.  I don't know when and even whether I will have time to work
> > on this case of using the rope Emacs gives us to hang ourselves, but
> 
> I don't think it's fair to say that Emacs /gives/ us this particular
> rope

By "rope" I meant the face inheritance, and by "hang ourselves" I
meant defining face inheritance which leads to inheritance cycles.

> since it appears xfaces includes specific logic and data
> structures explicitly designed to prevent circular face inheritance from
> hanging the process (named_merge_point).

Lisp programs aren't supposed to rely on internal implementation
details when they do stuff, they should follow healthy instincts and
common sense, and thus avoid defining circular inheritance.  It isn't
hard to see what a face inherits from, certainly not when basic faces
such as link and button are involved.

Also, the current logic in xfaces.c is the last resort during face
merging at display time, which is sub-optimal for the issue at hand,
because doing this at display time is too late, and doesn't allow
robust and safe error reporting.  It is better to reject this circular
inheritance when a Lisp program or the user attempt to introduce it in
the first place.

> > in the interests of making this issue easier to work on, would you
> > mind producing the smallest Lisp snippet that reproduces the problem,
> > starting from "emacs -Q"?
> 
> Sure, evaluate this in *scratch*:
> 
>   (progn
>     (font-lock-mode -1)
>     (set-face-attribute 'button nil :inherit 'link)
>     (set-face-attribute 'link nil :inherit 'button)
>     (dolist (x '(link button))
>       (set-face-attribute x nil :extend 'unspecified))
>     (insert "\n\n" (propertize "TEST LINK\n" 'face '(link :extend t)))
>     (redisplay t))

Thanks.  Please see if the patch below fixes this, without introducing
any regressions.  (The patch is against the current master branch, so I
don't know if it will be appropriate for the emacs-30 branch.)

diff --git a/src/xfaces.c b/src/xfaces.c
index 7626dfe..ca1bee1 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -2426,6 +2426,60 @@ face_inherited_attr (struct window *w, struct frame *f,
   return attr_val;
 }
 
+/* Chase the chain of inheritance for FACE on frame F, and return
+   non-zero if FACE inherits from its CHILD face, directly or
+   indirectly.  FACE is either a symbol or a list of face symbols, which
+   are two forms of values for the :inherit attribute of a face.  CHILD
+   must be a face symbol.  */
+static bool
+face_inheritance_cycle (struct frame *f, Lisp_Object face, Lisp_Object child)
+{
+  Lisp_Object face_attrs[LFACE_VECTOR_SIZE];
+  Lisp_Object parent_face;
+  bool ok, cycle_found = false;
+
+  eassert (SYMBOLP (child));
+  if (CONSP (face))
+    {
+      Lisp_Object tail;
+      for (tail = face; !NILP (tail); tail = XCDR (tail))
+	{
+	  ok = get_lface_attributes (NULL, f, XCAR (tail), face_attrs,
+				     false, NULL);
+	  if (!ok)
+	    break;
+	  parent_face = face_attrs[LFACE_INHERIT_INDEX];
+	  if (EQ (parent_face, child))
+	    cycle_found = true;
+	  else if (!NILP (parent_face)
+		   && !UNSPECIFIEDP (parent_face)
+		   && !IGNORE_DEFFACE_P (parent_face)
+		   && !RESET_P (parent_face))
+	    cycle_found = face_inheritance_cycle (f, parent_face, child);
+	  if (cycle_found)
+	    break;
+	}
+    }
+  else
+    {
+      eassert (SYMBOLP (face));
+      ok = get_lface_attributes (NULL, f, face, face_attrs, false, NULL);
+      if (ok)
+	{
+	  parent_face = face_attrs[LFACE_INHERIT_INDEX];
+	  if (EQ (parent_face, child))
+	    cycle_found = true;
+	  else if (!NILP (parent_face)
+		   && !UNSPECIFIEDP (parent_face)
+		   && !IGNORE_DEFFACE_P (parent_face)
+		   && !RESET_P (parent_face))
+	    cycle_found = face_inheritance_cycle (f, parent_face, child);
+	}
+    }
+
+  return cycle_found;
+}
+
 /* Merge the named face FACE_NAME on frame F, into the vector of face
    attributes TO.  Use NAMED_MERGE_POINTS to detect loops in face
    inheritance.  Return true if FACE_NAME is a valid face name and
@@ -3654,7 +3708,9 @@ DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
 	for (tail = value; CONSP (tail); tail = XCDR (tail))
 	  if (!SYMBOLP (XCAR (tail)))
 	    break;
-      if (NILP (tail))
+      if (face_inheritance_cycle (f, value, face))
+	signal_error ("Face inheritance results in inheritance cycle", value);
+      else if (NILP (tail))
 	ASET (lface, LFACE_INHERIT_INDEX, value);
       else
 	signal_error ("Invalid face inheritance", value);




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 23 Oct 2025 13:06:03 GMT) Full text and rfc822 format available.

Message #17 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: JD Smith <jdtsmith <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: prot <at> protesilaos.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 23 Oct 2025 09:04:32 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> since it appears xfaces includes specific logic and data
>> structures explicitly designed to prevent circular face inheritance from
>> hanging the process (named_merge_point).
>
> Lisp programs aren't supposed to rely on internal implementation
> details when they do stuff, they should follow healthy instincts and
> common sense, and thus avoid defining circular inheritance.  It isn't
> hard to see what a face inherits from, certainly not when basic faces
> such as link and button are involved.

This took some serious timing analysis and lldb debugging to dig out the
culprit.  Most users I think would just ascribe this to general emacs
bugginess.

I did find this note from modus-themes:

https://www.gnu.org/software/emacs/manual/html_node/modus-themes/Disable-other-themes.html

so it seems some theme authors are aware of the problems subsequent
calls to `load-theme' can lead to.  That said, this
`modus-themes-disable-other-themes' option (on by default) unfortunately
does not prevent the :inherit cycle from forming.

In fact, I now find that loading /any/ modus-theme (v20251013.512)
leads to this same button<->link inheritance cycle, even from a clean
emacs -Q session:

(progn
   (package-initialize)
   (require 'modus-themes)
   (modus-themes-load-random))

Traceback below.  Copying in Prot.  So this may be more widespread than
I had assumed.

>> Sure, evaluate this in *scratch*:
>> 
>>   (progn
>>     (font-lock-mode -1)
>>     (set-face-attribute 'button nil :inherit 'link)
>>     (set-face-attribute 'link nil :inherit 'button)
>>     (dolist (x '(link button))
>>       (set-face-attribute x nil :extend 'unspecified))
>>     (insert "\n\n" (propertize "TEST LINK\n" 'face '(link :extend t)))
>>     (redisplay t))
>
> Thanks.  Please see if the patch below fixes this, without introducing
> any regressions.  (The patch is against the current master branch, so I
> don't know if it will be appropriate for the emacs-30 branch.)

Thanks!  This applies and works just fine on v30.2 as well; using my
test, I get the error:

  Face inheritance results in inheritance cycle: button

and the `link' face has its :inherit attribute cleared.  Perfect.

The same error is also now thrown when I load any modus-theme
(e.g. with M-x modus-themes-load-random).  No hang occurs.

I will run with this for a while and report any problems.  I gather
this only runs during defface or similar, so we should expect no
performance regression.

Thanks very much for working on this and coming up with a clean
solution.  I suspect this is responsible for a not insubstantial
fraction of the (rare) hangs I experience with Emacs.

modus backtrace:

Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
  internal-set-lisp-face-attribute(link :inherit button #<frame *scratch* - GNU Emacs at .local 0x1260aa5e0>)
  set-face-attribute(link #<frame *scratch* - GNU Emacs at .local 0x1260aa5e0> :inherit button)
  apply(set-face-attribute link #<frame *scratch* - GNU Emacs at .local 0x1260aa5e0> (:inherit button))
  face-spec-set-2(link #<frame *scratch* - GNU Emacs at .local 0x1260aa5e0> (:inherit button))
  face-spec-recalc(link #<frame *scratch* - GNU Emacs at .local 0x1260aa5e0>)
  custom-theme-recalc-face(link)
  enable-theme(modus-operandi-tritanopia)
  load-theme(modus-operandi-tritanopia :no-confirm)
  modus-themes-load-theme(modus-operandi-tritanopia)
  modus-themes-load-random()
  (progn (package-initialize) (require 'modus-themes) (modus-themes-load-random))
  (progn (progn (package-initialize) (require 'modus-themes) (modus-themes-load-random)))
  eval((progn (progn (package-initialize) (require 'modus-themes) (modus-themes-load-random))) t)
  elisp--eval-last-sexp(nil)
  #f(compiled-function () #<bytecode 0x1866e67a4c6a>)()
  handler-bind-1(#f(compiled-function () #<bytecode 0x1866e67a4c6a>) (error) eval-expression--debug)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 23 Oct 2025 13:25:04 GMT) Full text and rfc822 format available.

Message #20 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: JD Smith <jdtsmith <at> gmail.com>
Cc: prot <at> protesilaos.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 23 Oct 2025 16:23:49 +0300
> From: JD Smith <jdtsmith <at> gmail.com>
> Date: Thu, 23 Oct 2025 09:04:32 -0400
> Cc: 79672 <at> debbugs.gnu.org,
>  prot <at> protesilaos.com
> 
> >>   (progn
> >>     (font-lock-mode -1)
> >>     (set-face-attribute 'button nil :inherit 'link)
> >>     (set-face-attribute 'link nil :inherit 'button)
> >>     (dolist (x '(link button))
> >>       (set-face-attribute x nil :extend 'unspecified))
> >>     (insert "\n\n" (propertize "TEST LINK\n" 'face '(link :extend t)))
> >>     (redisplay t))
> >
> > Thanks.  Please see if the patch below fixes this, without introducing
> > any regressions.  (The patch is against the current master branch, so I
> > don't know if it will be appropriate for the emacs-30 branch.)
> 
> Thanks!  This applies and works just fine on v30.2 as well; using my
> test, I get the error:
> 
>   Face inheritance results in inheritance cycle: button
> 
> and the `link' face has its :inherit attribute cleared.  Perfect.

That was the intent, yes: catch the problem where it is created.

> The same error is also now thrown when I load any modus-theme
> (e.g. with M-x modus-themes-load-random).  No hang occurs.
> 
> I will run with this for a while and report any problems.  I gather
> this only runs during defface or similar, so we should expect no
> performance regression.

Thanks, I will wait for your feedback before installing this.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Fri, 24 Oct 2025 05:33:01 GMT) Full text and rfc822 format available.

Message #23 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Protesilaos Stavrou <prot <at> protesilaos.com>
To: JD Smith <jdtsmith <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Fri, 24 Oct 2025 08:32:34 +0300
> From: JD Smith <jdtsmith <at> gmail.com>
> Date: Thu, 23 Oct 2025 09:04:32 -0400

> [... 26 lines elided]

> In fact, I now find that loading /any/ modus-theme (v20251013.512)
> leads to this same button<->link inheritance cycle, even from a clean
> emacs -Q session:
> 
> (progn
>    (package-initialize)
>    (require 'modus-themes)
>    (modus-themes-load-random))
> 
> Traceback below.  Copying in Prot.  So this may be more widespread than
> I had assumed.

Thank you for bringing this to my attention! Notwithstanding any changes
to emacs.git, what should we do in the theme side of things to avoid
such a problem? I can make it so that we only inherit from faces that
Modus itself defines. It is not guaranteed to work 100% with multiple
enabled themes, but it makes it less likely that we run into trouble.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Fri, 24 Oct 2025 07:00:02 GMT) Full text and rfc822 format available.

Message #26 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Protesilaos Stavrou <prot <at> protesilaos.com>
Cc: 79672 <at> debbugs.gnu.org, jdtsmith <at> gmail.com
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Fri, 24 Oct 2025 09:59:44 +0300
> Date: Fri, 24 Oct 2025 08:32:34 +0300
> From: Protesilaos Stavrou <prot <at> protesilaos.com>
> Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org
> 
> > From: JD Smith <jdtsmith <at> gmail.com>
> > Date: Thu, 23 Oct 2025 09:04:32 -0400
> 
> > [... 26 lines elided]
> 
> > In fact, I now find that loading /any/ modus-theme (v20251013.512)
> > leads to this same button<->link inheritance cycle, even from a clean
> > emacs -Q session:
> > 
> > (progn
> >    (package-initialize)
> >    (require 'modus-themes)
> >    (modus-themes-load-random))
> > 
> > Traceback below.  Copying in Prot.  So this may be more widespread than
> > I had assumed.
> 
> Thank you for bringing this to my attention! Notwithstanding any changes
> to emacs.git, what should we do in the theme side of things to avoid
> such a problem? I can make it so that we only inherit from faces that
> Modus itself defines. It is not guaranteed to work 100% with multiple
> enabled themes, but it makes it less likely that we run into trouble.

One thing to avoid is not to define face inheritance that contradicts
the inheritance of those faces in core.  In this case, 'button' is
defined to inherit from 'link', so defining the opposite inheritance
is a recipe for trouble.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Fri, 24 Oct 2025 16:14:02 GMT) Full text and rfc822 format available.

Message #29 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: "J.D. Smith" <jdtsmith <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>, Protesilaos Stavrou <prot <at> protesilaos.com>
Cc: 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Fri, 24 Oct 2025 12:13:13 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> Date: Fri, 24 Oct 2025 08:32:34 +0300
>> From: Protesilaos Stavrou <prot <at> protesilaos.com>
>> Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org
>> 
>> > From: JD Smith <jdtsmith <at> gmail.com>
>> > Date: Thu, 23 Oct 2025 09:04:32 -0400
>> 
>> > [... 26 lines elided]
>> 
>> > In fact, I now find that loading /any/ modus-theme (v20251013.512)
>> > leads to this same button<->link inheritance cycle, even from a clean
>> > emacs -Q session:
>> > 
>> > (progn
>> >    (package-initialize)
>> >    (require 'modus-themes)
>> >    (modus-themes-load-random))
>> > 
>> > Traceback below.  Copying in Prot.  So this may be more widespread than
>> > I had assumed.
>> 
>> Thank you for bringing this to my attention! Notwithstanding any changes
>> to emacs.git, what should we do in the theme side of things to avoid
>> such a problem? I can make it so that we only inherit from faces that
>> Modus itself defines. It is not guaranteed to work 100% with multiple
>> enabled themes, but it makes it less likely that we run into trouble.
>
> One thing to avoid is not to define face inheritance that contradicts
> the inheritance of those faces in core.  In this case, 'button' is
> defined to inherit from 'link', so defining the opposite inheritance
> is a recipe for trouble.

Right.  Builtin:

 (defface button '((t :inherit link))
   "Default face used for buttons."
   :group 'basic-faces)

Modus:

 `(button ((,c :background ,bg-link :foreground ,fg-link :underline ,underline-link)))
 `(link ((,c :inherit button)))

With Eli's patch, this will raise an error, so it will be much easier to
avoid accidentally creating such inheritance loops once it's installed.
I guess the other thing which could be done is to set to 'unspecified
all pre-existing attributes in a builtin face that are /not/ being
modified by the theme.  I.e. here, `button :inherit' should be set
by modus to 'unspecified instead of being left alone.  In reality,
`:inherit' is probably the only "dangerous" attribute.

BTW, in case you are wondering, a face inheritance loop does not cause
an immediate freeze.  Only for certain corner cases where re-display is
chasing down an attribute unspecified by both faces does it occur.
That's why my reproducer added the `:extend t`.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Sat, 25 Oct 2025 06:40:02 GMT) Full text and rfc822 format available.

Message #32 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: "J.D. Smith" <jdtsmith <at> gmail.com>
Cc: prot <at> protesilaos.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Sat, 25 Oct 2025 09:39:15 +0300
> From: "J.D. Smith" <jdtsmith <at> gmail.com>
> Cc:  79672 <at> debbugs.gnu.org
> Date: Fri, 24 Oct 2025 12:13:13 -0400
> 
> I guess the other thing which could be done is to set to 'unspecified
> all pre-existing attributes in a builtin face that are /not/ being
> modified by the theme.  I.e. here, `button :inherit' should be set
> by modus to 'unspecified instead of being left alone.

Hmm... not sure why this should matter.  The value 'unspecified' is
the default, so leaving the attribute's value alone should be
equivalent to setting it to 'unspecified'.  Maybe I'm missing
something, so please show a case where this matters.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Sat, 25 Oct 2025 11:43:02 GMT) Full text and rfc822 format available.

Message #35 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: "J.D. Smith" <jdtsmith <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: prot <at> protesilaos.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Sat, 25 Oct 2025 07:41:51 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>> Cc:  79672 <at> debbugs.gnu.org
>> Date: Fri, 24 Oct 2025 12:13:13 -0400
>> 
>> I guess the other thing which could be done is to set to 'unspecified
>> all pre-existing attributes in a builtin face that are /not/ being
>> modified by the theme.  I.e. here, `button :inherit' should be set
>> by modus to 'unspecified instead of being left alone.
>
> Hmm... not sure why this should matter.  The value 'unspecified' is
> the default, so leaving the attribute's value alone should be
> equivalent to setting it to 'unspecified'.  Maybe I'm missing
> something, so please show a case where this matters.

I meant only that if you do choose to override the direction of
inheritance for some builtin face (from link->button to button->link),
you should explicitly remove its preexisting :inherit attribute.  But
leaving such inheritance intact does seem safer.  Luckily, with your
fix, theme authors and users will get instant feedback should this kind
of trouble arise.  No issues so far.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Mon, 27 Oct 2025 00:10:01 GMT) Full text and rfc822 format available.

Message #38 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: "J.D. Smith" <jdtsmith <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: prot <at> protesilaos.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Sun, 26 Oct 2025 20:09:15 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: JD Smith <jdtsmith <at> gmail.com>
>> I will run with this for a while and report any problems.  I gather
>> this only runs during defface or similar, so we should expect no
>> performance regression.
>
> Thanks, I will wait for your feedback before installing this.

I've run with this patch without issue for several days.  Prot has
recently updated modus-themes to be more careful with :inherit, so those
themes no longer trigger the new error (as of v20251026.810).  So I
think it can be installed.

Thanks for your efforts.  A small thing, but given the popularity of
modus, I suspect a number of people have been bitten by this.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Mon, 27 Oct 2025 08:16:02 GMT) Full text and rfc822 format available.

Message #41 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Protesilaos Stavrou <prot <at> protesilaos.com>
To: "J.D. Smith" <jdtsmith <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Mon, 27 Oct 2025 10:15:10 +0200
On 2025-10-27 02:09, J.D. Smith wrote:
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
>>> From: JD Smith <jdtsmith <at> gmail.com>
>>> I will run with this for a while and report any problems.  I gather
>>> this only runs during defface or similar, so we should expect no
>>> performance regression.
>> 
>> Thanks, I will wait for your feedback before installing this.
> 
> I've run with this patch without issue for several days.  Prot has
> recently updated modus-themes to be more careful with :inherit, so 
> those
> themes no longer trigger the new error (as of v20251026.810).  So I
> think it can be installed.
> 
> Thanks for your efforts.  A small thing, but given the popularity of
> modus, I suspect a number of people have been bitten by this.

Thank you!




Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Mon, 27 Oct 2025 13:58:01 GMT) Full text and rfc822 format available.

Notification sent to "J.D. Smith" <jdtsmith <at> gmail.com>:
bug acknowledged by developer. (Mon, 27 Oct 2025 13:58:02 GMT) Full text and rfc822 format available.

Message #46 received at 79672-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: "J.D. Smith" <jdtsmith <at> gmail.com>
Cc: prot <at> protesilaos.com, 79672-done <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Mon, 27 Oct 2025 15:57:03 +0200
> From: "J.D. Smith" <jdtsmith <at> gmail.com>
> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
> Date: Sun, 26 Oct 2025 20:09:15 -0400
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> From: JD Smith <jdtsmith <at> gmail.com>
> >> I will run with this for a while and report any problems.  I gather
> >> this only runs during defface or similar, so we should expect no
> >> performance regression.
> >
> > Thanks, I will wait for your feedback before installing this.
> 
> I've run with this patch without issue for several days.  Prot has
> recently updated modus-themes to be more careful with :inherit, so those
> themes no longer trigger the new error (as of v20251026.810).  So I
> think it can be installed.
> 
> Thanks for your efforts.  A small thing, but given the popularity of
> modus, I suspect a number of people have been bitten by this.

Thanks for testing the patch.  Now installed on the master branch, and
closing the bug.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Tue, 28 Oct 2025 19:28:02 GMT) Full text and rfc822 format available.

Message #49 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: 79672 <at> debbugs.gnu.org
Cc: eliz <at> gnu.org, jdtsmith <at> gmail.com
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Tue, 28 Oct 2025 20:26:50 +0100
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
>> Date: Sun, 26 Oct 2025 20:09:15 -0400
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>> >> From: JD Smith <jdtsmith <at> gmail.com>
>> >> I will run with this for a while and report any problems.  I gather
>> >> this only runs during defface or similar, so we should expect no
>> >> performance regression.
>> >
>> > Thanks, I will wait for your feedback before installing this.
>> 
>> I've run with this patch without issue for several days.  Prot has
>> recently updated modus-themes to be more careful with :inherit, so those
>> themes no longer trigger the new error (as of v20251026.810).  So I
>> think it can be installed.
>> 
>> Thanks for your efforts.  A small thing, but given the popularity of
>> modus, I suspect a number of people have been bitten by this.
>
> Thanks for testing the patch.  Now installed on the master branch, and
> closing the bug.

Hi,

FWIW, I still see this bug with the following recipe:

      - emacs -Q
      - insert (load-theme 'modus-operandi)
      - M-C-x
      
Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
  internal-set-lisp-face-attribute(link :inherit button #<frame *scratch* - GNU Emacs at computer 0x7748adbf660>)
  set-face-attribute(link #<frame *scratch* - GNU Emacs at computer 0x7748adbf660> :inherit button)
  apply(set-face-attribute link #<frame *scratch* - GNU Emacs at computer 0x7748adbf660> (:inherit button))
  face-spec-set-2(link #<frame *scratch* - GNU Emacs at computer 0x7748adbf660> (:inherit button))
  face-spec-recalc(link #<frame *scratch* - GNU Emacs at computer 0x7748adbf660>)
  custom-theme-recalc-face(link)
  enable-theme(modus-operandi)
  load-theme(modus-operandi)
  (progn (load-theme 'modus-operandi))
  (let ((print-level nil) (print-length nil)) (progn (load-theme 'modus-operandi)))
  (setq elisp--eval-defun-result (let ((print-level nil) (print-length nil)) (progn (load-theme 'modus-operandi))))
  eval-region(148 176 t #f(compiled-function (ignore) #<bytecode -0x837c5b5049a8956>))  ; Reading at buffer position 176
  elisp--eval-defun()
  #f(compiled-function () #<bytecode 0x18c82c4309f9>)()
  handler-bind-1(#f(compiled-function () #<bytecode 0x18c82c4309f9>) (error) eval-expression--debug)
  eval-defun(nil)
  funcall-interactively(eval-defun nil)
  call-interactively(eval-defun nil nil)
  command-execute(eval-defun)
-- 
Manuel Giraud




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Tue, 28 Oct 2025 20:13:02 GMT) Full text and rfc822 format available.

Message #52 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: JD Smith <jdtsmith <at> gmail.com>
To: Manuel Giraud <manuel <at> ledu-giraud.fr>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Tue, 28 Oct 2025 16:12:25 -0400
> On Oct 28, 2025, at 3:26 PM, Manuel Giraud <manuel <at> ledu-giraud.fr> wrote:
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
>>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>>> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
>>> Date: Sun, 26 Oct 2025 20:09:15 -0400
>>> 
>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>> 
>>>>> From: JD Smith <jdtsmith <at> gmail.com>
>>>>> I will run with this for a while and report any problems.  I gather
>>>>> this only runs during defface or similar, so we should expect no
>>>>> performance regression.
>>>> 
>>>> Thanks, I will wait for your feedback before installing this.
>>> 
>>> I've run with this patch without issue for several days.  Prot has
>>> recently updated modus-themes to be more careful with :inherit, so those
>>> themes no longer trigger the new error (as of v20251026.810).  So I
>>> think it can be installed.
>>> 
>>> Thanks for your efforts.  A small thing, but given the popularity of
>>> modus, I suspect a number of people have been bitten by this.
>> 
>> Thanks for testing the patch.  Now installed on the master branch, and
>> closing the bug.
> 
> Hi,
> 
> FWIW, I still see this bug with the following recipe:
> 
>      - emacs -Q
>      - insert (load-theme 'modus-operandi)
>      - M-C-x
> 
> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)

Do you have a recent development version of modus-themes installed?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Tue, 28 Oct 2025 20:44:02 GMT) Full text and rfc822 format available.

Message #55 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: JD Smith <jdtsmith <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Tue, 28 Oct 2025 21:43:07 +0100
JD Smith <jdtsmith <at> gmail.com> writes:

>> On Oct 28, 2025, at 3:26 PM, Manuel Giraud <manuel <at> ledu-giraud.fr> wrote:
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>>>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>>>> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
>>>> Date: Sun, 26 Oct 2025 20:09:15 -0400
>>>> 
>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>> 
>>>>>> From: JD Smith <jdtsmith <at> gmail.com>
>>>>>> I will run with this for a while and report any problems.  I gather
>>>>>> this only runs during defface or similar, so we should expect no
>>>>>> performance regression.
>>>>> 
>>>>> Thanks, I will wait for your feedback before installing this.
>>>> 
>>>> I've run with this patch without issue for several days.  Prot has
>>>> recently updated modus-themes to be more careful with :inherit, so those
>>>> themes no longer trigger the new error (as of v20251026.810).  So I
>>>> think it can be installed.
>>>> 
>>>> Thanks for your efforts.  A small thing, but given the popularity of
>>>> modus, I suspect a number of people have been bitten by this.
>>> 
>>> Thanks for testing the patch.  Now installed on the master branch, and
>>> closing the bug.
>> 
>> Hi,
>> 
>> FWIW, I still see this bug with the following recipe:
>> 
>>      - emacs -Q
>>      - insert (load-theme 'modus-operandi)
>>      - M-C-x
>> 
>> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
>
> Do you have a recent development version of modus-themes installed?

No I don't.  I'm using the one bundled with current Emacs.
-- 
Manuel Giraud




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Tue, 28 Oct 2025 20:50:03 GMT) Full text and rfc822 format available.

Message #58 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: JD Smith <jdtsmith <at> gmail.com>
To: Manuel Giraud <manuel <at> ledu-giraud.fr>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Protesilaos Stavrou <prot <at> protesilaos.com>,
 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Tue, 28 Oct 2025 16:49:21 -0400

> On Oct 28, 2025, at 4:43 PM, Manuel Giraud <manuel <at> ledu-giraud.fr> wrote:
> 
> JD Smith <jdtsmith <at> gmail.com> writes:
> 
>>>> On Oct 28, 2025, at 3:26 PM, Manuel Giraud <manuel <at> ledu-giraud.fr> wrote:
>>> 
>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>> 
>>>>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>>>>> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
>>>>> Date: Sun, 26 Oct 2025 20:09:15 -0400
>>>>> 
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>>> 
>>>>>>> From: JD Smith <jdtsmith <at> gmail.com>
>>>>>>> I will run with this for a while and report any problems.  I gather
>>>>>>> this only runs during defface or similar, so we should expect no
>>>>>>> performance regression.
>>>>>> 
>>>>>> Thanks, I will wait for your feedback before installing this.
>>>>> 
>>>>> I've run with this patch without issue for several days.  Prot has
>>>>> recently updated modus-themes to be more careful with :inherit, so those
>>>>> themes no longer trigger the new error (as of v20251026.810).  So I
>>>>> think it can be installed.
>>>>> 
>>>>> Thanks for your efforts.  A small thing, but given the popularity of
>>>>> modus, I suspect a number of people have been bitten by this.
>>>> 
>>>> Thanks for testing the patch.  Now installed on the master branch, and
>>>> closing the bug.
>>> 
>>> Hi,
>>> 
>>> FWIW, I still see this bug with the following recipe:
>>> 
>>>     - emacs -Q
>>>     - insert (load-theme 'modus-operandi)
>>>     - M-C-x
>>> 
>>> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
>> 
>> Do you have a recent development version of modus-themes installed?
> 
> No I don't.  I'm using the one bundled with current Emacs.

This patch serves to _reveal_ an underlying issue with face inheritance present in older versions of modus.   So you’ll need to update, and the version in master will need to be updated as well. 





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 29 Oct 2025 03:29:01 GMT) Full text and rfc822 format available.

Message #61 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: JD Smith <jdtsmith <at> gmail.com>
Cc: 79672 <at> debbugs.gnu.org, manuel <at> ledu-giraud.fr, prot <at> protesilaos.com
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 29 Oct 2025 05:27:50 +0200
> From: JD Smith <jdtsmith <at> gmail.com>
> Date: Tue, 28 Oct 2025 16:49:21 -0400
> Cc: 79672 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
>  Protesilaos Stavrou <prot <at> protesilaos.com>
> 
> 
> 
> > On Oct 28, 2025, at 4:43 PM, Manuel Giraud <manuel <at> ledu-giraud.fr> wrote:
> > 
> > JD Smith <jdtsmith <at> gmail.com> writes:
> > 
> >>>> On Oct 28, 2025, at 3:26 PM, Manuel Giraud <manuel <at> ledu-giraud.fr> wrote:
> >>> 
> >>> Eli Zaretskii <eliz <at> gnu.org> writes:
> >>> 
> >>>>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
> >>>>> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
> >>>>> Date: Sun, 26 Oct 2025 20:09:15 -0400
> >>>>> 
> >>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
> >>>>> 
> >>>>>>> From: JD Smith <jdtsmith <at> gmail.com>
> >>>>>>> I will run with this for a while and report any problems.  I gather
> >>>>>>> this only runs during defface or similar, so we should expect no
> >>>>>>> performance regression.
> >>>>>> 
> >>>>>> Thanks, I will wait for your feedback before installing this.
> >>>>> 
> >>>>> I've run with this patch without issue for several days.  Prot has
> >>>>> recently updated modus-themes to be more careful with :inherit, so those
> >>>>> themes no longer trigger the new error (as of v20251026.810).  So I
> >>>>> think it can be installed.
> >>>>> 
> >>>>> Thanks for your efforts.  A small thing, but given the popularity of
> >>>>> modus, I suspect a number of people have been bitten by this.
> >>>> 
> >>>> Thanks for testing the patch.  Now installed on the master branch, and
> >>>> closing the bug.
> >>> 
> >>> Hi,
> >>> 
> >>> FWIW, I still see this bug with the following recipe:
> >>> 
> >>>     - emacs -Q
> >>>     - insert (load-theme 'modus-operandi)
> >>>     - M-C-x
> >>> 
> >>> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
> >> 
> >> Do you have a recent development version of modus-themes installed?
> > 
> > No I don't.  I'm using the one bundled with current Emacs.
> 
> This patch serves to _reveal_ an underlying issue with face inheritance present in older versions of modus.   So you’ll need to update, and the version in master will need to be updated as well. 

Why wasn't the version on the master branch updated already?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 29 Oct 2025 05:13:01 GMT) Full text and rfc822 format available.

Message #64 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Protesilaos Stavrou <prot <at> protesilaos.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: manuel <at> ledu-giraud.fr, JD Smith <jdtsmith <at> gmail.com>, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 29 Oct 2025 07:11:45 +0200
On 2025-10-29 05:27, Eli Zaretskii wrote:
> [...]
> 
>> >>> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
>> >>
>> >> Do you have a recent development version of modus-themes installed?
>> >
>> > No I don't.  I'm using the one bundled with current Emacs.
>> 
>> This patch serves to _reveal_ an underlying issue with face 
>> inheritance present in older versions of modus.   So you’ll need to 
>> update, and the version in master will need to be updated as well.
> 
> Why wasn't the version on the master branch updated already?

Because I am in the process of finalising the new major version of the 
theme. There are a ton of changes. I cannot just merge without testing 
everything and preparing the release notes.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 29 Oct 2025 12:26:02 GMT) Full text and rfc822 format available.

Message #67 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Protesilaos Stavrou <prot <at> protesilaos.com>
Cc: manuel <at> ledu-giraud.fr, jdtsmith <at> gmail.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 29 Oct 2025 14:24:44 +0200
> Date: Wed, 29 Oct 2025 07:11:45 +0200
> From: Protesilaos Stavrou <prot <at> protesilaos.com>
> Cc: JD Smith <jdtsmith <at> gmail.com>, manuel <at> ledu-giraud.fr,
>  79672 <at> debbugs.gnu.org
> 
> On 2025-10-29 05:27, Eli Zaretskii wrote:
> > [...]
> > 
> >> >>> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
> >> >>
> >> >> Do you have a recent development version of modus-themes installed?
> >> >
> >> > No I don't.  I'm using the one bundled with current Emacs.
> >> 
> >> This patch serves to _reveal_ an underlying issue with face 
> >> inheritance present in older versions of modus.   So you’ll need to 
> >> update, and the version in master will need to be updated as well.
> > 
> > Why wasn't the version on the master branch updated already?
> 
> Because I am in the process of finalising the new major version of the 
> theme. There are a ton of changes. I cannot just merge without testing 
> everything and preparing the release notes.

I see.  Well, then perhaps you could consider an emergency fix for the
master branch, even if later you decide to augment or modify it?
Because currently people who track the master branch cannot use
modus-themes at all: they get an error when activating them.

AFAICS, there's a single line in modus-themes.el that needs to be
tweaked.

TIA




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 29 Oct 2025 18:13:02 GMT) Full text and rfc822 format available.

Message #70 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Stéphane Marks <shipmints <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: jdtsmith <at> gmail.com, Protesilaos Stavrou <prot <at> protesilaos.com>,
 manuel <at> ledu-giraud.fr, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 29 Oct 2025 14:11:50 -0400
[Message part 1 (text/plain, inline)]
On Wed, Oct 29, 2025 at 8:26 AM Eli Zaretskii <eliz <at> gnu.org> wrote:

> > Date: Wed, 29 Oct 2025 07:11:45 +0200
> > From: Protesilaos Stavrou <prot <at> protesilaos.com>
> > Cc: JD Smith <jdtsmith <at> gmail.com>, manuel <at> ledu-giraud.fr,
> >  79672 <at> debbugs.gnu.org
> >
> > On 2025-10-29 05:27, Eli Zaretskii wrote:
> > > [...]
> > >
> > >> >>> Debugger entered--Lisp error: (error "Face inheritance results in
> inheritance cycle" button)
> > >> >>
> > >> >> Do you have a recent development version of modus-themes installed?
> > >> >
> > >> > No I don't.  I'm using the one bundled with current Emacs.
> > >>
> > >> This patch serves to _reveal_ an underlying issue with face
> > >> inheritance present in older versions of modus.   So you’ll need to
> > >> update, and the version in master will need to be updated as well.
> > >
> > > Why wasn't the version on the master branch updated already?
> >
> > Because I am in the process of finalising the new major version of the
> > theme. There are a ton of changes. I cannot just merge without testing
> > everything and preparing the release notes.
>
> I see.  Well, then perhaps you could consider an emergency fix for the
> master branch, even if later you decide to augment or modify it?
> Because currently people who track the master branch cannot use
> modus-themes at all: they get an error when activating them.
>
> AFAICS, there's a single line in modus-themes.el that needs to be
> tweaked.
>

Prot, yes please.  For people that have modus-themes installed via ELPA,
that might also need a quick fix so using ELPA + master cycle detection
works with modus. I've had to disable modus for the time being on master.
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 30 Oct 2025 05:54:01 GMT) Full text and rfc822 format available.

Message #73 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Protesilaos Stavrou <prot <at> protesilaos.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: manuel <at> ledu-giraud.fr, jdtsmith <at> gmail.com, 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 30 Oct 2025 07:53:08 +0200
On 2025-10-29 14:24, Eli Zaretskii wrote:
>> Date: Wed, 29 Oct 2025 07:11:45 +0200
>> From: Protesilaos Stavrou <prot <at> protesilaos.com>
>> Cc: JD Smith <jdtsmith <at> gmail.com>, manuel <at> ledu-giraud.fr,
>>  79672 <at> debbugs.gnu.org
>> 
>> On 2025-10-29 05:27, Eli Zaretskii wrote:
>> > [...]
>> >
>> >> >>> Debugger entered--Lisp error: (error "Face inheritance results in inheritance cycle" button)
>> >> >>
>> >> >> Do you have a recent development version of modus-themes installed?
>> >> >
>> >> > No I don't.  I'm using the one bundled with current Emacs.
>> >>
>> >> This patch serves to _reveal_ an underlying issue with face
>> >> inheritance present in older versions of modus.   So you’ll need to
>> >> update, and the version in master will need to be updated as well.
>> >
>> > Why wasn't the version on the master branch updated already?
>> 
>> Because I am in the process of finalising the new major version of the
>> theme. There are a ton of changes. I cannot just merge without testing
>> everything and preparing the release notes.
> 
> I see.  Well, then perhaps you could consider an emergency fix for the
> master branch, even if later you decide to augment or modify it?
> Because currently people who track the master branch cannot use
> modus-themes at all: they get an error when activating them.
> 
> AFAICS, there's a single line in modus-themes.el that needs to be
> tweaked.

I just changed that one line and pushed the commit. Thank you!




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 30 Oct 2025 05:57:01 GMT) Full text and rfc822 format available.

Message #76 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Protesilaos Stavrou <prot <at> protesilaos.com>
To: Stéphane Marks <shipmints <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, jdtsmith <at> gmail.com, manuel <at> ledu-giraud.fr,
 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 30 Oct 2025 07:56:00 +0200
On 2025-10-29 20:11, Stéphane Marks wrote:
>> [...]
>> 
>> AFAICS, there's a single line in modus-themes.el that needs to be
>> tweaked.
> 
> Prot, yes please.  For people that have modus-themes installed via
> ELPA, that might also need a quick fix so using ELPA + master cycle
> detection works with modus. I've had to disable modus for the time
> being on master.

I just made the change to emacs.git, but ELPA has to wait. I cannot push 
the change there because the modus-themes.git main branch has close to 
200 new commits since the last stable version. Many of them are massive 
changes in preparation for version 5.0.0.

[ Unless there is a way to push another branch to ELPA, in which case I 
am happy to do it. ]

Please use the built-in version or the one from ELPA-devel.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 30 Oct 2025 15:48:02 GMT) Full text and rfc822 format available.

Message #79 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Manuel Giraud <manuel <at> ledu-giraud.fr>
To: Protesilaos Stavrou <prot <at> protesilaos.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79672 <at> debbugs.gnu.org, jdtsmith <at> gmail.com
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 30 Oct 2025 16:47:13 +0100
Protesilaos Stavrou <prot <at> protesilaos.com> writes:

[...]

> I just changed that one line and pushed the commit. Thank you!

Thanks Prot!  It works as expected.
-- 
Manuel Giraud




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 30 Oct 2025 16:34:01 GMT) Full text and rfc822 format available.

Message #82 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Pedro Andres Aranda Gutierrez <paaguti <at> gmail.com>
To: 79672 <at> debbugs.gnu.org
Subject: Carrying over from https://github.com/minad/corfu/issues/597
Date: Thu, 30 Oct 2025 17:32:21 +0100
[Message part 1 (text/plain, inline)]
Hi,

my crash related to commit 23d8633579 is not related to the modus themes. I
have my own themes generated by my fork of themecreator.

Best, /PA
-- 
Fragen sind nicht da, um beantwortet zu werden,
Fragen sind da um gestellt zu werden
Georg Kreisler

"Sagen's Paradeiser" (ORF: Als Radiohören gefährlich war) => write BE!
Year 1 of the New Koprocracy
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 30 Oct 2025 17:42:01 GMT) Full text and rfc822 format available.

Message #85 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Stéphane Marks <shipmints <at> gmail.com>
To: Protesilaos Stavrou <prot <at> protesilaos.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, jdtsmith <at> gmail.com, manuel <at> ledu-giraud.fr,
 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 30 Oct 2025 13:41:22 -0400
[Message part 1 (text/plain, inline)]
On Thu, Oct 30, 2025 at 1:56 AM Protesilaos Stavrou <prot <at> protesilaos.com>
wrote:

> On 2025-10-29 20:11, Stéphane Marks wrote:
> >> [...]
> >>
> >> AFAICS, there's a single line in modus-themes.el that needs to be
> >> tweaked.
> >
> > Prot, yes please.  For people that have modus-themes installed via
> > ELPA, that might also need a quick fix so using ELPA + master cycle
> > detection works with modus. I've had to disable modus for the time
> > being on master.
>
> I just made the change to emacs.git, but ELPA has to wait. I cannot push
> the change there because the modus-themes.git main branch has close to
> 200 new commits since the last stable version. Many of them are massive
> changes in preparation for version 5.0.0.
>
> [ Unless there is a way to push another branch to ELPA, in which case I
> am happy to do it. ]
>
> Please use the built-in version or the one from ELPA-devel.
>

Thank you for the quick patch to master.  In case this helps anyone (or
they have a better idea), what I did to make this work, sharing my init.el
configuration for 30 and 31 (master) is force built-ins for master:

(unless (version< emacs-version "31")
  (setq custom-theme-load-path (list t)))

-Stéphane
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Thu, 30 Oct 2025 21:34:02 GMT) Full text and rfc822 format available.

Message #88 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Stéphane Marks <shipmints <at> gmail.com>
To: Protesilaos Stavrou <prot <at> protesilaos.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, jdtsmith <at> gmail.com, manuel <at> ledu-giraud.fr,
 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Thu, 30 Oct 2025 17:32:43 -0400
[Message part 1 (text/plain, inline)]
On Thu, Oct 30, 2025 at 1:41 PM Stéphane Marks <shipmints <at> gmail.com> wrote:

> On Thu, Oct 30, 2025 at 1:56 AM Protesilaos Stavrou <prot <at> protesilaos.com>
> wrote:
>
>> On 2025-10-29 20:11, Stéphane Marks wrote:
>> >> [...]
>> >>
>> >> AFAICS, there's a single line in modus-themes.el that needs to be
>> >> tweaked.
>> >
>> > Prot, yes please.  For people that have modus-themes installed via
>> > ELPA, that might also need a quick fix so using ELPA + master cycle
>> > detection works with modus. I've had to disable modus for the time
>> > being on master.
>>
>> I just made the change to emacs.git, but ELPA has to wait. I cannot push
>> the change there because the modus-themes.git main branch has close to
>> 200 new commits since the last stable version. Many of them are massive
>> changes in preparation for version 5.0.0.
>>
>> [ Unless there is a way to push another branch to ELPA, in which case I
>> am happy to do it. ]
>>
>> Please use the built-in version or the one from ELPA-devel.
>>
>
> Thank you for the quick patch to master.  In case this helps anyone (or
> they have a better idea), what I did to make this work, sharing my init.el
> configuration for 30 and 31 (master) is force built-ins for master:
>
> (unless (version< emacs-version "31")
>   (setq custom-theme-load-path (list t)))
>
> -Stéphane
>

To be more complete, it's this stanza:

;; Ensure modus-themes built-ins
(unless (version< emacs-version "31")
  (setq custom-theme-load-path (list t)))
(require-theme 'modus-themes)

`require-theme` must precede any `load-theme`, or `use-package` (for those
who use that style of configuration).
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Fri, 31 Oct 2025 15:38:02 GMT) Full text and rfc822 format available.

Message #91 received at 79672 <at> debbugs.gnu.org (full text, mbox):

From: Protesilaos Stavrou <prot <at> protesilaos.com>
To: Stéphane Marks <shipmints <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, jdtsmith <at> gmail.com, manuel <at> ledu-giraud.fr,
 79672 <at> debbugs.gnu.org
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Fri, 31 Oct 2025 17:37:18 +0200
On 2025-10-30 23:32, Stéphane Marks wrote:
> [...]
> 
> To be more complete, it's this stanza:
> 
> ;; Ensure modus-themes built-ins
> 
> (unless (version< emacs-version "31")
>   (setq custom-theme-load-path (list t)))
> (require-theme 'modus-themes)
> 
> `require-theme` must precede any `load-theme`, or `use-package` (for
> those who use that style of configuration).

Thank you and sorry for this inconvenience! Tomorrow I will probably 
publish version 5.0.0 of the themes. It is just a matter of finding the 
time to write the release notes.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 05 Nov 2025 19:10:02 GMT) Full text and rfc822 format available.

Message #94 received at 79672-done <at> debbugs.gnu.org (full text, mbox):

From: Fu Yuan <casouri <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79672-done <at> debbugs.gnu.org, prot <at> protesilaos.com,
 "J.D. Smith" <jdtsmith <at> gmail.com>
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 5 Nov 2025 11:08:49 -0800
> 
> 在 2025年10月27日,上午6:59,Eli Zaretskii <eliz <at> gnu.org> 写道:
> 
> 
>> 
>> From: "J.D. Smith" <jdtsmith <at> gmail.com>
>> Cc: prot <at> protesilaos.com,  79672 <at> debbugs.gnu.org
>> Date: Sun, 26 Oct 2025 20:09:15 -0400
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>>>> From: JD Smith <jdtsmith <at> gmail.com>
>>>> I will run with this for a while and report any problems.  I gather
>>>> this only runs during defface or similar, so we should expect no
>>>> performance regression.
>>> 
>>> Thanks, I will wait for your feedback before installing this.
>> 
>> I've run with this patch without issue for several days.  Prot has
>> recently updated modus-themes to be more careful with :inherit, so those
>> themes no longer trigger the new error (as of v20251026.810).  So I
>> think it can be installed.
>> 
>> Thanks for your efforts.  A small thing, but given the popularity of
>> modus, I suspect a number of people have been bitten by this.
> 
> Thanks for testing the patch.  Now installed on the master branch, and
> closing the bug.
> 

Nice change, it caught a bug in my personal theme ;)

Yuan



Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79672; Package emacs. (Wed, 05 Nov 2025 19:46:02 GMT) Full text and rfc822 format available.

Message #97 received at 79672-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Fu Yuan <casouri <at> gmail.com>
Cc: 79672-done <at> debbugs.gnu.org, prot <at> protesilaos.com, jdtsmith <at> gmail.com
Subject: Re: bug#79672: 30.2.50; infinite loop with circular face inheritance
Date: Wed, 05 Nov 2025 21:45:00 +0200
> From: Fu Yuan <casouri <at> gmail.com>
> Date: Wed, 5 Nov 2025 11:08:49 -0800
> Cc: "J.D. Smith" <jdtsmith <at> gmail.com>, prot <at> protesilaos.com,
>  79672-done <at> debbugs.gnu.org
> 
> Nice change, it caught a bug in my personal theme ;)

Happy to serve.




This bug report was last modified 1 day ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.