emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master a32c55b: * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Avoid known


From: Stefan Monnier
Subject: master a32c55b: * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Avoid known cl-defsubst breakage
Date: Sun, 5 Apr 2020 09:54:59 -0400 (EDT)

branch: master
commit a32c55bd9f3aa06b74adc9630b55689972c52356
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Avoid known cl-defsubst 
breakage
---
 lisp/emacs-lisp/cl-macs.el | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 7f5d197..45a308e 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2970,14 +2970,26 @@ Supported keywords for slots are:
     (pcase-dolist (`(,cname ,args ,doc) constrs)
       (let* ((anames (cl--arglist-args args))
             (make (cl-mapcar (function (lambda (s d) (if (memq s anames) s d)))
-                           slots defaults)))
-       (push `(,cldefsym ,cname
+                             slots defaults))
+            ;; `cl-defsubst' is fundamentally broken: it substitutes
+             ;; its arguments into the body's `sexp' much too naively
+             ;; when inlinling, which results in various problems.
+             ;; For example it generates broken code if your
+             ;; argument's name happens to be the same as some
+             ;; function used within the body.
+             ;; E.g. (cl-defsubst sm-foo (list) (list list))
+             ;; will expand `(sm-foo 1)' to `(1 1)' rather than to `(list t)'!
+             ;; Try to catch this known case!
+            (con-fun (or type #'record))
+            (unsafe-cl-defsubst
+             (or (memq con-fun args) (assq con-fun args))))
+       (push `(,(if unsafe-cl-defsubst 'cl-defun cldefsym) ,cname
                    (&cl-defs (nil ,@descs) ,@args)
                  ,(if (stringp doc) doc
                     (format "Constructor for objects of type `%s'." name))
                  ,@(if (cl--safe-expr-p `(progn ,@(mapcar #'cl-second descs)))
                        '((declare (side-effect-free t))))
-                 (,(or type #'record) ,@make))
+                 (,con-fun ,@make))
               forms)))
     (if print-auto (nconc print-func (list '(princ ")" cl-s) t)))
     ;; Don't bother adding to cl-custom-print-functions since it's not used



reply via email to

[Prev in Thread] Current Thread [Next in Thread]