diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2013-06-13 22:31:28 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2013-06-13 22:31:28 -0400 |
commit | 0b31660d3c10a0f8e243dd67bd0ecaf2c847d1e6 (patch) | |
tree | c98ad57350666702eb75c8c0978f8d7c8e55f8e7 /lisp/emacs-lisp | |
parent | 99c812809854a1405ba879814b8ae9a09e82a5e4 (diff) | |
download | emacs-0b31660d3c10a0f8e243dd67bd0ecaf2c847d1e6.tar.gz emacs-0b31660d3c10a0f8e243dd67bd0ecaf2c847d1e6.tar.bz2 emacs-0b31660d3c10a0f8e243dd67bd0ecaf2c847d1e6.zip |
* lisp/emacs-lisp/bytecomp.el (byte-compile-force-lexical-warnings): New var.
(byte-compile-preprocess): Use it.
(byte-compile-file-form-defalias): Try a bit harder to use macros we
can't quite recognize.
(byte-compile-add-to-list): Remove.
* lisp/emacs-lisp/cconv.el (cconv-warnings-only): New function.
(cconv-closure-convert): Add assertion.
* lisp/emacs-lisp/map-ynp.el: Use lexical-binding.
(map-y-or-n-p): Remove unused vars `tail' and `object'.
Factor out some repeated code.
* etc/NEWS (utf-8 for el): Move to the incompatible section.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 1 | ||||
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 35 | ||||
-rw-r--r-- | lisp/emacs-lisp/cconv.el | 14 | ||||
-rw-r--r-- | lisp/emacs-lisp/map-ynp.el | 48 |
4 files changed, 45 insertions, 53 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 7375c2176ba..7214501362d 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -287,6 +287,7 @@ (byte-compile--reify-function fn))))) (if (eq (car-safe newfn) 'function) (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form))) + ;; This can happen because of macroexp-warn-and-return &co. (byte-compile-log-warning (format "Inlining closure %S failed" name)) form)))) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index e603f76f41d..391401ae5d6 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2174,6 +2174,8 @@ list that represents a doc string reference. byte-compile-maxdepth 0 byte-compile-output nil)))) +(defvar byte-compile-force-lexical-warnings nil) + (defun byte-compile-preprocess (form &optional _for-effect) (setq form (macroexpand-all form byte-compile-macro-environment)) ;; FIXME: We should run byte-optimize-form here, but it currently does not @@ -2182,9 +2184,10 @@ list that represents a doc string reference. ;; macroexpand-all. ;; (if (memq byte-optimize '(t source)) ;; (setq form (byte-optimize-form form for-effect))) - (if lexical-binding - (cconv-closure-convert form) - form)) + (cond + (lexical-binding (cconv-closure-convert form)) + (byte-compile-force-lexical-warnings (cconv-warnings-only form)) + (t form))) ;; byte-hunk-handlers cannot call this! (defun byte-compile-toplevel-file-form (form) @@ -4240,6 +4243,12 @@ binding slots have been popped." lam)) (unless (byte-compile-file-form-defmumble name macro arglist body rest) + (when macro + (if (null fun) + (message "Macro %s unrecognized, won't work in file" name) + (message "Macro %s partly recognized, trying our luck" name) + (push (cons name (eval fun)) + byte-compile-macro-environment))) (byte-compile-keep-pending form)))) ;; We used to just do: (byte-compile-normal-call form) @@ -4268,26 +4277,6 @@ binding slots have been popped." 'byte-hunk-handler 'byte-compile-form-make-variable-buffer-local) (defun byte-compile-form-make-variable-buffer-local (form) (byte-compile-keep-pending form 'byte-compile-normal-call)) - -(byte-defop-compiler-1 add-to-list byte-compile-add-to-list) -(defun byte-compile-add-to-list (form) - ;; FIXME: This could be used for `set' as well, except that it's got - ;; its own opcode, so the final `byte-compile-normal-call' needs to - ;; be replaced with something else. - (pcase form - (`(,fun ',var . ,_) - (byte-compile-check-variable var 'assign) - (if (assq var byte-compile--lexical-environment) - (byte-compile-log-warning - (format "%s cannot use lexical var `%s'" fun var) - nil :error) - (unless (or (not (byte-compile-warning-enabled-p 'free-vars)) - (boundp var) - (memq var byte-compile-bound-variables) - (memq var byte-compile-free-references)) - (byte-compile-warn "assignment to free variable `%S'" var) - (push var byte-compile-free-references))))) - (byte-compile-normal-call form)) ;;; tags diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 761e33c059d..70fa71a0da4 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -143,7 +143,19 @@ Returns a form where all lambdas don't have any free variables." ;; Analyze form - fill these variables with new information. (cconv-analyse-form form '()) (setq cconv-freevars-alist (nreverse cconv-freevars-alist)) - (cconv-convert form nil nil))) ; Env initially empty. + (prog1 (cconv-convert form nil nil) ; Env initially empty. + (cl-assert (null cconv-freevars-alist))))) + +;;;###autoload +(defun cconv-warnings-only (form) + "Add the warnings that closure conversion would encounter." + (let ((cconv-freevars-alist '()) + (cconv-lambda-candidates '()) + (cconv-captured+mutated '())) + ;; Analyze form - fill these variables with new information. + (cconv-analyse-form form '()) + ;; But don't perform the closure conversion. + form)) (defconst cconv--dummy-var (make-symbol "ignored")) diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el index 13202a9ce4d..1919d47687b 100644 --- a/lisp/emacs-lisp/map-ynp.el +++ b/lisp/emacs-lisp/map-ynp.el @@ -1,4 +1,4 @@ -;;; map-ynp.el --- general-purpose boolean question-asker +;;; map-ynp.el --- general-purpose boolean question-asker -*- lexical-binding:t -*- ;; Copyright (C) 1991-1995, 2000-2013 Free Software Foundation, Inc. @@ -79,7 +79,7 @@ are meaningful here. Returns the number of actions taken." (let* ((actions 0) - user-keys mouse-event map prompt char elt tail def + user-keys mouse-event map prompt char elt def ;; Non-nil means we should use mouse menus to ask. use-menus delayed-switch-frame @@ -89,13 +89,15 @@ Returns the number of actions taken." (next (if (functionp list) (lambda () (setq elt (funcall list))) (lambda () (when list - (setq elt (pop list)) - t))))) + (setq elt (pop list)) + t)))) + (try-again (lambda () + (let ((x next)) + (setq next (lambda () (setq next x) elt)))))) (if (and (listp last-nonmenu-event) use-dialog-box) ;; Make a list describing a dialog box. - (let ((object (if help (capitalize (nth 0 help)))) - (objects (if help (capitalize (nth 1 help)))) + (let ((objects (if help (capitalize (nth 1 help)))) (action (if help (capitalize (nth 2 help))))) (setq map `(("Yes" . act) ("No" . skip) ,@(mapcar (lambda (elt) @@ -129,8 +131,8 @@ Returns the number of actions taken." (unwind-protect (progn (if (stringp prompter) - (setq prompter `(lambda (object) - (format ,prompter object)))) + (setq prompter (lambda (object) + (format prompter object)))) (while (funcall next) (setq prompt (funcall prompter elt)) (cond ((stringp prompt) @@ -176,9 +178,7 @@ Returns the number of actions taken." next (lambda () nil))) ((eq def 'quit) (setq quit-flag t) - (setq next `(lambda () - (setq next ',next) - ',elt))) + (funcall try-again)) ((eq def 'automatic) ;; Act on this and all following objects. (if (funcall prompter elt) @@ -219,40 +219,30 @@ the current %s and exit." (with-current-buffer standard-output (help-mode))) - (setq next `(lambda () - (setq next ',next) - ',elt))) - ((and (symbolp def) (commandp def)) - (call-interactively def) - ;; Regurgitated; try again. - (setq next `(lambda () - (setq next ',next) - ',elt))) + (funcall try-again)) + ((and (symbolp def) (commandp def)) + (call-interactively def) + ;; Regurgitated; try again. + (funcall try-again)) ((vectorp def) ;; A user-defined key. (if (funcall (aref def 0) elt) ;Call its function. ;; The function has eaten this object. (setq actions (1+ actions)) ;; Regurgitated; try again. - (setq next `(lambda () - (setq next ',next) - ',elt)))) + (funcall try-again))) ((and (consp char) (eq (car char) 'switch-frame)) ;; switch-frame event. Put it off until we're done. (setq delayed-switch-frame char) - (setq next `(lambda () - (setq next ',next) - ',elt))) + (funcall try-again)) (t ;; Random char. (message "Type %s for help." (key-description (vector help-char))) (beep) (sit-for 1) - (setq next `(lambda () - (setq next ',next) - ',elt))))) + (funcall try-again)))) (prompt (funcall actor elt) (setq actions (1+ actions)))))) |