From d6600481ae9423eb2c51150967050afb05c301b8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Tue, 14 Jun 2022 19:09:20 +0200 Subject: [PATCH] Run cconv for dynbound code as well Make cconv work for dynamically bound code and always run it. This allows later stages to benefit from transformations and normalisations in cconv. * lisp/emacs-lisp/bytecomp.el (byte-compile-preprocess): Always run cconv. * lisp/emacs-lisp/cconv.el (cconv--analyze-function) (cconv-analyze-form): In dynbound code, treat all variable bindings as dynamic (lambda, let, let* and condition-case). --- lisp/emacs-lisp/bytecomp.el | 4 +--- lisp/emacs-lisp/cconv.el | 29 ++++++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 1f868d2217c..af74c0699b9 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2557,9 +2557,7 @@ list that represents a doc string reference. ;; macroexpand-all. ;; (if (memq byte-optimize '(t source)) ;; (setq form (byte-optimize-form form for-effect))) - (cond - (lexical-binding (cconv-closure-convert form)) - (t form))) + (cconv-closure-convert form)) ;; byte-hunk-handlers cannot call this! (defun byte-compile-toplevel-file-form (top-level-form) diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index b12f1db677e..eca1123899c 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -664,18 +664,19 @@ FORM is the parent form that binds this var." ;; Push it before recursing, so cconv-freevars-alist contains entries in ;; the order they'll be used by closure-convert-rec. (push freevars cconv-freevars-alist) - (dolist (arg args) - (cond - ((byte-compile-not-lexical-var-p arg) - (byte-compile-warn-x - arg - "Lexical argument shadows the dynamic variable %S" - arg)) - ((eq ?& (aref (symbol-name arg) 0)) nil) ;Ignore &rest, &optional, ... - (t (let ((varstruct (list arg nil nil nil nil))) - (cl-pushnew arg byte-compile-lexical-variables) - (push (cons (list arg) (cdr varstruct)) newvars) - (push varstruct newenv))))) + (when lexical-binding + (dolist (arg args) + (cond + ((byte-compile-not-lexical-var-p arg) + (byte-compile-warn-x + arg + "Lexical argument shadows the dynamic variable %S" + arg)) + ((eq ?& (aref (symbol-name arg) 0)) nil) ;Ignore &rest, &optional, ... + (t (let ((varstruct (list arg nil nil nil nil))) + (cl-pushnew arg byte-compile-lexical-variables) + (push (cons (list arg) (cdr varstruct)) newvars) + (push varstruct newenv)))))) (dolist (form body) ;Analyze body forms. (cconv-analyze-form form newenv)) ;; Summarize resulting data about arguments. @@ -724,7 +725,7 @@ This function does not return anything but instead fills the (cconv-analyze-form value (if (eq letsym 'let*) env orig-env))) - (unless (byte-compile-not-lexical-var-p var) + (unless (or (byte-compile-not-lexical-var-p var) (not lexical-binding)) (cl-pushnew var byte-compile-lexical-variables) (let ((varstruct (list var nil nil nil nil))) (push (cons binder (cdr varstruct)) newvars) @@ -769,6 +770,8 @@ This function does not return anything but instead fills the (`(condition-case ,var ,protected-form . ,handlers) (cconv-analyze-form protected-form env) + (unless lexical-binding + (setq var nil)) (when (and var (symbolp var) (byte-compile-not-lexical-var-p var)) (byte-compile-warn-x var "Lexical variable shadows the dynamic variable %S" var)) -- 2.39.2