From: Stefan Monnier <monnier@IRO.UMontreal.CA>
To: Oleksandr Manzyuk <manzyuk@gmail.com>
Cc: 10761-done@debbugs.gnu.org
Subject: bug#10761: 24.0.93; variable declared with defvar is not recognized as special
Date: Thu, 09 Feb 2012 16:52:20 -0500 [thread overview]
Message-ID: <jwvliobwu9a.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <CAAwZTsSAhqczPRheCFbu_ZD9MtXnL_Mj5MZ29_bkjTdQe=XJaQ@mail.gmail.com> (Oleksandr Manzyuk's message of "Wed, 8 Feb 2012 09:21:58 +0000")
> 1. emacs -Q
> 2. M-: (boundp 'pcomplete-stub) RET ==> nil
> 3. M-x shell
> 4. M-: (boundp 'pcomplete-stub) RET ==> t
> 5. M-: (special-variable-p 'pcomplete-stub) RET ==> nil
> 6. Open the file `pcomplete.el' (for example, by looking up the variable
> `pcomplete-stub') and M-x eval-buffer. Now (special-variable-p
> 'pcomplete-stub) evaluates to t.
Thanks for catching this. It's actually a pretty bad bug.
I've installed the patch below which I believe fixes the problem,
Stefan
=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog 2012-02-09 20:27:54 +0000
+++ lisp/ChangeLog 2012-02-09 21:50:23 +0000
@@ -1,3 +1,11 @@
+2012-02-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacs-lisp/bytecomp.el (byte-compile-file-form-defvar):
+ Don't fallback on byte-compile-defvar. Optimize (defvar foo) away.
+ (byte-compile-tmp-var): New const.
+ (byte-compile-defvar): Use it to minimize .elc size.
+ Just use `defvar' rather than simulate it (bug#10761).
+
2012-02-09 Glenn Morris <rgm@gnu.org>
* files.el (rename-uniquely): Doc fix. (Bug#3806)
=== modified file 'lisp/emacs-lisp/bytecomp.el'
--- lisp/emacs-lisp/bytecomp.el 2012-01-19 07:21:25 +0000
+++ lisp/emacs-lisp/bytecomp.el 2012-02-09 19:09:21 +0000
@@ -2237,10 +2237,6 @@
(put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar)
(put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar)
(defun byte-compile-file-form-defvar (form)
- (if (null (nth 3 form))
- ;; Since there is no doc string, we can compile this as a normal form,
- ;; and not do a file-boundary.
- (byte-compile-keep-pending form)
(when (and (symbolp (nth 1 form))
(not (string-match "[-*/:$]" (symbol-name (nth 1 form))))
(byte-compile-warning-enabled-p 'lexical))
@@ -2249,6 +2245,9 @@
(push (nth 1 form) byte-compile-bound-variables)
(if (eq (car form) 'defconst)
(push (nth 1 form) byte-compile-const-variables))
+ (if (and (null (cddr form)) ;No `value' provided.
+ (eq (car form) 'defvar)) ;Just a declaration.
+ nil
(cond ((consp (nth 2 form))
(setq form (copy-sequence form))
(setcar (cdr (cdr form))
@@ -4124,8 +4123,10 @@
(push (nth 1 (nth 1 form)) byte-compile-global-not-obsolete-vars))
(byte-compile-normal-call form))
+(defconst byte-compile-tmp-var (make-symbol "def-tmp-var"))
+
(defun byte-compile-defvar (form)
- ;; This is not used for file-level defvar/consts with doc strings.
+ ;; This is not used for file-level defvar/consts.
(when (and (symbolp (nth 1 form))
(not (string-match "[-*/:$]" (symbol-name (nth 1 form))))
(byte-compile-warning-enabled-p 'lexical))
@@ -4148,32 +4149,21 @@
(push var byte-compile-bound-variables)
(if (eq fun 'defconst)
(push var byte-compile-const-variables))
- (byte-compile-body-do-effect
- (list
- ;; Put the defined variable in this library's load-history entry
- ;; just as a real defvar would, but only in top-level forms.
- (when (and (cddr form) (null byte-compile-current-form))
- `(setq current-load-list (cons ',var current-load-list)))
- (when (> (length form) 3)
(when (and string (not (stringp string)))
(byte-compile-warn "third arg to `%s %s' is not a string: %s"
fun var string))
- `(put ',var 'variable-documentation ,string))
+ (byte-compile-form-do-effect
(if (cddr form) ; `value' provided
- (let ((byte-compile-not-obsolete-vars (list var)))
- (if (eq fun 'defconst)
- ;; `defconst' sets `var' unconditionally.
- (let ((tmp (make-symbol "defconst-tmp-var")))
;; Quote with `quote' to prevent byte-compiling the body,
;; which would lead to an inf-loop.
- `(funcall '(lambda (,tmp) (defconst ,var ,tmp))
- ,value))
- ;; `defvar' sets `var' only when unbound.
- `(if (not (default-boundp ',var)) (setq-default ,var ,value))))
- (when (eq fun 'defconst)
+ `(funcall '(lambda (,byte-compile-tmp-var)
+ (,fun ,var ,byte-compile-tmp-var ,@(nthcdr 3 form)))
+ ,value)
+ (if (eq fun 'defconst)
;; This will signal an appropriate error at runtime.
- `(eval ',form)))
- `',var))))
+ `(eval ',form)
+ ;; A simple (defvar foo) just returns foo.
+ `',var)))))
(defun byte-compile-autoload (form)
(byte-compile-set-symbol-position 'autoload)
prev parent reply other threads:[~2012-02-09 21:52 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-08 9:21 bug#10761: 24.0.93; variable declared with defvar is not recognized as special Oleksandr Manzyuk
2012-02-09 21:52 ` Stefan Monnier [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jwvliobwu9a.fsf-monnier+emacs@gnu.org \
--to=monnier@iro.umontreal.ca \
--cc=10761-done@debbugs.gnu.org \
--cc=manzyuk@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.