From 930a0e019b4c823da04d52e907d322a296fb9ae3 Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Wed, 2 Mar 2011 10:21:03 +0000 Subject: [PATCH] 1.0.46.20: better error messages for invalid variables 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 | 3 ++- src/compiler/ir1tran-lambda.lisp | 26 ++++++++++++++++---------- version.lisp-expr | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/compiler/ir1-translators.lisp b/src/compiler/ir1-translators.lisp index 74831c2..b33d94a 100644 --- a/src/compiler/ir1-translators.lisp +++ b/src/compiler/ir1-translators.lisp @@ -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))) diff --git a/src/compiler/ir1tran-lambda.lisp b/src/compiler/ir1tran-lambda.lisp index 6bf1843..63b14da 100644 --- a/src/compiler/ir1tran-lambda.lisp +++ b/src/compiler/ir1tran-lambda.lisp @@ -24,22 +24,28 @@ ;;; 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) diff --git a/version.lisp-expr b/version.lisp-expr index e00a859..54a9437 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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" -- 1.7.10.4