1.0.46.20: better error messages for invalid variables
authorNikodemus Siivola <nikodemus@random-state.net>
Wed, 2 Mar 2011 10:21:03 +0000 (10:21 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Wed, 2 Mar 2011 10:21:03 +0000 (10:21 +0000)
 Based on patch by Roman Marynchak, lp#387333.

 * Same code checks for LET and LET* in addition to lambda-lists, so make sure
   the messages make sense for both contexts. Binding forms converted to
   LAMBDA -- like MULTIPLE-VALUE-BIND -- still get odd messages for duplicate
   variable names, though.

 * Make the messages for keywords, defined constants, and global lexicals
   better.

src/compiler/ir1-translators.lisp
src/compiler/ir1tran-lambda.lisp
version.lisp-expr

index 74831c2..b33d94a 100644 (file)
@@ -639,7 +639,8 @@ be a lambda expression."
              (varify-lambda-arg name
                                 (if (eq context 'let*)
                                     nil
-                                    (names)))))
+                                    (names))
+                                context)))
       (dolist (spec bindings)
         (cond ((atom spec)
                (let ((var (get-var spec)))
index 6bf1843..63b14da 100644 (file)
 ;;; If it is losing, we punt with a COMPILER-ERROR. NAMES-SO-FAR is a
 ;;; list of names which have previously been bound. If the NAME is in
 ;;; this list, then we error out.
-(declaim (ftype (sfunction (t list) lambda-var) varify-lambda-arg))
-(defun varify-lambda-arg (name names-so-far)
+(declaim (ftype (sfunction (t list &optional t) lambda-var) varify-lambda-arg))
+(defun varify-lambda-arg (name names-so-far &optional (context "lambda list"))
   (declare (inline member))
   (unless (symbolp name)
-    (compiler-error "The lambda variable ~S is not a symbol." name))
+    (compiler-error "~S is not a symbol, and cannot be used as a variable." name))
   (when (member name names-so-far :test #'eq)
-    (compiler-error "The variable ~S occurs more than once in the lambda list."
-                    name))
+    (compiler-error "The variable ~S occurs more than once in the ~A."
+                    name
+                    context))
   (let ((kind (info :variable :kind name)))
-    (cond ((or (keywordp name) (eq kind :constant))
-           (compiler-error "The name of the lambda variable ~S is already in use to name a constant."
+    (cond ((keywordp name)
+           (compiler-error "~S is a keyword, and cannot be used as a local variable."
+                           name))
+          ((eq kind :constant)
+           (compiler-error "~@<~S names a defined constant, and cannot be used as a ~
+                            local variable.~:@>"
                            name))
           ((eq :global kind)
-           (compiler-error "The name of the lambda variable ~S is already in use to name a global variable."
-                           name)))
-    (cond ((eq kind :special)
+           (compiler-error "~@<~S names a global lexical variable, and cannot be used ~
+                            as a local variable.~:@>"
+                           name))
+          ((eq kind :special)
            (let ((specvar (find-free-var name)))
              (make-lambda-var :%source-name name
                               :type (leaf-type specvar)
index e00a859..54a9437 100644 (file)
@@ -20,4 +20,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.46.19"
+"1.0.46.20"