1.0.4.46: allow &environment and disallow &aux in DEFSETF lambda-lists
authorNikodemus Siivola <nikodemus@random-state.net>
Sun, 8 Apr 2007 12:51:34 +0000 (12:51 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Sun, 8 Apr 2007 12:51:34 +0000 (12:51 +0000)
 * Reported by Samium Gromoff.
 * Test-cases.

src/code/early-setf.lisp
src/code/parse-defmacro.lisp
tests/setf.impure.lisp
version.lisp-expr

index ee7cc7d..99926ae 100644 (file)
@@ -399,12 +399,12 @@ GET-SETF-EXPANSION directly."
              (multiple-value-bind (body local-decs doc)
                  (parse-defmacro `(,lambda-list ,@store-variables)
                                  whole-var body access-fn 'defsetf
+                                 :environment env-var
                                  :anonymousp t)
                `(eval-when (:compile-toplevel :load-toplevel :execute)
                   (assign-setf-macro
                    ',access-fn
                    (lambda (,access-form-var ,env-var)
-                     (declare (ignore ,env-var))
                      (%defsetf ,access-form-var ,(length store-variables)
                                (lambda (,whole-var)
                                  ,@local-decs
index 225c2f7..eea2801 100644 (file)
                   (defmacro-error (format nil "required argument after ~A"
                                           restp)
                       context name))
-                (process-sublist var "REQUIRED-" `(car ,path))
+                (when (process-sublist var "REQUIRED-" `(car ,path))
+                  ;; Note &ENVIRONMENT from DEFSETF sublist
+                  (aver (eq context 'defsetf))
+                  (setf env-arg-used t))
                 (setq path `(cdr ,path)
                       minimum (1+ minimum)
                       maximum (1+ maximum)))
                (&environment
                 (cond (env-illegal
                        (error "&ENVIRONMENT is not valid with ~S." context))
-                      (sublist
+                      ;; DEFSETF explicitly allows &ENVIRONMENT, and we get
+                      ;; it here in a sublist.
+                      ((and sublist (neq context 'defsetf))
                        (error "&ENVIRONMENT is only valid at top level of ~
                              lambda-list."))
                       (env-arg-used
                   (error "Multiple ~A in ~A lambda-list." var context))
                 (setq allow-other-keys-p t))
                (&aux
+                (when (eq context 'defsetf)
+                  (error "~A not allowed in a ~A lambda-list." var context))
                 (when aux-seen
                   (error "Multiple ~A in ~A lambda-list." '&aux context))
                 (setq now-processing :auxs
index b159173..62c7987 100644 (file)
   (setf (macro-function 'nothing-at-all nil) fun)
   (assert (eq fun (macro-function 'nothing-at-all nil))))
 
+
+;;; DEFSETF accepts &ENVIRONMENT but not &AUX
+(defsetf test-defsetf-env-1  (&environment env) (new)
+  (declare (ignore new))
+  (if (macro-function 'defsetf-env-trick env)
+      :local
+      :global))
+
+(defsetf test-defsetf-env-2  (local global &environment env) (new)
+  (declare (ignore new))
+  (if (macro-function 'defsetf-env-trick env)
+      local
+      global))
+
+(aver (eq :local (macrolet ((defsetf-env-trick ()))
+                   (setf (test-defsetf-env-1) 13))))
+
+(aver (eq :global (setf (test-defsetf-env-1) 13)))
+
+(aver (eq :local (macrolet ((defsetf-env-trick ()))
+                   (setf (test-defsetf-env-2 :local :oops) 13))))
+
+(aver (eq :global (setf (test-defsetf-env-2 :oops :global) 13)))
+
+(aver (eq :error
+          (handler-case
+              (eval '(defsetf test-defsetf-aux (&aux aux) (new) nil))
+            (error ()
+              :error))))
+
 ;;; success
index 6355e03..0649a25 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.4.45"
+"1.0.4.46"