summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2013-06-13 22:31:28 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2013-06-13 22:31:28 -0400
commit0b31660d3c10a0f8e243dd67bd0ecaf2c847d1e6 (patch)
treec98ad57350666702eb75c8c0978f8d7c8e55f8e7 /lisp/emacs-lisp
parent99c812809854a1405ba879814b8ae9a09e82a5e4 (diff)
downloademacs-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.el1
-rw-r--r--lisp/emacs-lisp/bytecomp.el35
-rw-r--r--lisp/emacs-lisp/cconv.el14
-rw-r--r--lisp/emacs-lisp/map-ynp.el48
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))))))