;;; 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
(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.
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.