[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#63564: 29.0.91; (setcdr) behaves differently between natively and by
From: |
Mattias Engdegård |
Subject: |
bug#63564: 29.0.91; (setcdr) behaves differently between natively and byte compiled code |
Date: |
Thu, 18 May 2023 20:01:48 +0200 |
18 maj 2023 kl. 19.45 skrev Jimmy Wong <wyuenho@gmail.com>:
> As Mattias has noted, this commit on markdown-mode did fix the issues, it
> would still be nice to know why the natively compiled version behaves
> differently from the byte compiled version tho. This could be good learning
> for occasional elisp devs such as myself to know what to watch out for.
The code was mutating a program constant (quoted list) which is a no-no in
Elisp. As luck has it, a new warning in Emacs 30 discovered it and a
markdown-mode maintainer changed the code accordingly (the commit message says
that he 'fixed a warning' but he really fixed broken code; the warning is fine).
Technically, the error likely occurred because the native compiler propagated
that constant to its points of use where it underwent some compile-time
evaluation. Essentially:
(let ((root '(nil)))
...
(let ((sibling-alist (last (cdr root)))) ; sibling-alist = nil
(dotimes (_ (1- level))
(setq sibling-alist (last (cdar sibling-alist)))) ; still nil
(setcdr sibling-alist alist) ; boom
In Emacs 30 the byte-compiler is able to do some of that propagation as well,
and rightly so.
Don't mutate program constants. It's not safe, and it has never been safe.
bug#63564: 29.0.91; (setcdr) behaves differently between natively and byte compiled code, Mattias Engdegård, 2023/05/18