]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/gv.el
Un-revert changes mistakenly dropped by f9fabb2b
[gnu-emacs] / lisp / emacs-lisp / gv.el
index 229ad275bf5cf7019928898e41ce9c5381ccf42d..fae3bcb86f676b1521ff57766b512ee01da00a63 100644 (file)
@@ -1,6 +1,6 @@
 ;;; gv.el --- generalized variables  -*- lexical-binding: t -*-
 
-;; Copyright (C) 2012-2014 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
 ;; Keywords: extensions
@@ -89,10 +89,10 @@ DO must return an Elisp expression."
     (let* ((head (car place))
            (gf (function-get head 'gv-expander 'autoload)))
       (if gf (apply gf do (cdr place))
-        (let ((me (macroexpand place    ;FIXME: expand one step at a time!
-                               ;; (append macroexpand-all-environment
-                               ;;         gv--macro-environment)
-                               macroexpand-all-environment)))
+        (let ((me (macroexpand-1 place
+                                 ;; (append macroexpand-all-environment
+                                 ;;         gv--macro-environment)
+                                 macroexpand-all-environment)))
           (if (and (eq me place) (get head 'compiler-macro))
               ;; Expand compiler macros: this takes care of all the accessors
               ;; defined via cl-defsubst, such as cXXXr and defstruct slots.
@@ -493,9 +493,20 @@ This is like the `&' operator of the C language.
 Note: this only works reliably with lexical binding mode, except for very
 simple PLACEs such as (function-symbol 'foo) which will also work in dynamic
 binding mode."
-  (gv-letplace (getter setter) place
-    `(cons (lambda () ,getter)
-           (lambda (gv--val) ,(funcall setter 'gv--val)))))
+  (let ((code
+         (gv-letplace (getter setter) place
+           `(cons (lambda () ,getter)
+                  (lambda (gv--val) ,(funcall setter 'gv--val))))))
+    (if (or lexical-binding
+            ;; If `code' still starts with `cons' then presumably gv-letplace
+            ;; did not add any new let-bindings, so the `lambda's don't capture
+            ;; any new variables.  As a consequence, the code probably works in
+            ;; dynamic binding mode as well.
+            (eq (car-safe code) 'cons))
+        code
+      (macroexp--warn-and-return
+       "Use of gv-ref probably requires lexical-binding"
+       code))))
 
 (defsubst gv-deref (ref)
   "Dereference REF, returning the referenced value.