changeset 5570:6c76f5b7e2e3

Be more careful still in #'cl-defsubst-expand. lisp/ChangeLog addition: 2011-09-11 Aidan Kehoe <kehoea@parhasard.net> * cl-macs.el (cl-defsubst-expand): Be more careful still here, make sure that any references to variables in BODY don't access those values in the enclosing scope when that would be inappropriate. Add some documentation of a potential reasonable approach to avoiding the problems with our (non-Common Lisp-conformant) #'symbol-macrolet.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 11 Sep 2011 16:05:05 +0100
parents d19b6e3bdf91
children 5273dd66a1ba 86d6adeb1cf4
files lisp/ChangeLog lisp/cl-macs.el
diffstat 2 files changed, 34 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sat Sep 10 13:17:29 2011 +0100
+++ b/lisp/ChangeLog	Sun Sep 11 16:05:05 2011 +0100
@@ -1,3 +1,13 @@
+2011-09-11  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl-macs.el (cl-defsubst-expand):
+	Be more careful still here, make sure that any references to
+	variables in BODY don't access those values in the enclosing scope
+	when that would be inappropriate.
+	Add some documentation of a potential reasonable approach to
+	avoiding the problems with our (non-Common Lisp-conformant)
+	#'symbol-macrolet.
+
 2011-09-10  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* cl-macs.el (cl-defsubst-expand):
--- a/lisp/cl-macs.el	Sat Sep 10 13:17:29 2011 +0100
+++ b/lisp/cl-macs.el	Sun Sep 11 16:05:05 2011 +0100
@@ -3238,18 +3238,25 @@
                              (if (or simple (cl-const-expr-p argv))
                                  (progn 
 				   ;; Avoid infinite loop on symbol macro
-				   ;; expansion, make sure none of the argvs
-				   ;; refer to the symbols in the argns.
+				   ;; expansion:
 				   (or (block find
-                                         ;; Can't use cl-expr-contains, that
-                                         ;; doesn't descend lambdas:
-					 (subst nil argn argvs :test
-						#'(lambda (elt tree)
+                                         (subst nil argn argvs :test
+                                                #'(lambda (elt tree)
+                                                    ;; Give nil if argn is
+                                                    ;; in argvs somewhere:
 						    (if (eq elt tree)
-							(return-from find t))))
-					 nil)
-				       (push (list argn argv) symbol-macros))
-				   (and unsafe (list (list argn argv))))
+							(return-from find)))))
+                                       (let ((copy-symbol (copy-symbol argn)))
+                                         ;; Rename ARGN within BODY so it
+                                         ;; doesn't conflict with its value
+                                         ;; in the including scope:
+                                         (setq body
+                                               (cl-macroexpand-all
+                                                body `((,(eq-hash argn)
+                                                        ,copy-symbol)))
+                                               argn copy-symbol)))
+                                   (push (list argn argv) symbol-macros)
+                                   (and unsafe (list (list argn argv))))
                                (list (list argn argv))))
                          argns argvs)))
       `(let ,lets
@@ -3260,6 +3267,13 @@
              ;; bound). We don't have GNU's issue where the replacement will
              ;; be done when the symbol is used in a function context,
              ;; because we're using #'symbol-macrolet instead of #'subst.
+             ;;
+             ;; #'symbol-macrolet as specified by Common Lisp is shadowed by
+             ;; #'let, #'let* and lambda argument lists, and that would suit
+             ;; our purposes here perfectly; we could implement it in
+             ;; cl-macroexpand-all by shadowing any existing symbol macros
+             ;; when we descend let forms or arglist lambdas. Doing it
+             ;; unconditionally could well break #'loop, though.
              ,symbol-macros
            ,body)))))