more targetted warnings for probable DEFSTRUCT syntax errors
authorChristophe Rhodes <csr21@cantab.net>
Mon, 18 Nov 2013 14:11:45 +0000 (14:11 +0000)
committerChristophe Rhodes <csr21@cantab.net>
Mon, 18 Nov 2013 14:11:58 +0000 (14:11 +0000)
Some keyword defstruct slot names are more deserving of warnings
than others.  In particular, slot names matching defstruct
options (from name-and-options) are highly suspicious, and likely
never to be intended, as there is essentially always a different
way of writing what is meant.

The exception is when the CONC-NAME defstruct option is null,
which makes defstruct slots effectively have symbolic identity
rather than the normal stringish nature; don't emit full
warnings under those circumstances, even though doing
  (defstruct (foo :conc-name) (:constructor))
is a pretty spectacularly bad idea.

src/code/defstruct.lisp

index f42de7b..000fad3 100644 (file)
   (multiple-value-bind (name default default-p type type-p read-only ro-p)
       (typecase spec
         (symbol
-         (when (keywordp spec)
-           (style-warn "Keyword slot name indicates probable syntax ~
-                        error in DEFSTRUCT: ~S."
-                       spec))
+         (typecase spec
+           ((or null (member :conc-name :constructor :copier :predicate :named))
+            (warn "slot name of ~S indicates probable syntax error in DEFSTRUCT" spec))
+           (keyword
+            (style-warn "slot name of ~S indicates possible syntax error in DEFSTRUCT" spec)))
          spec)
         (cons
          (destructuring-bind
-               (name
-                &optional (default nil default-p)
-                &key (type nil type-p) (read-only nil ro-p))
+               (name &optional (default nil default-p)
+                     &key (type nil type-p) (read-only nil ro-p))
              spec
-           (values name
-                   default default-p
+           (when (dd-conc-name defstruct)
+             ;; the warning here is useful, but in principle we cannot
+             ;; distinguish between legitimate and erroneous use of
+             ;; these names when :CONC-NAME is NIL.  In the common
+             ;; case (CONC-NAME non-NIL), there are alternative ways
+             ;; of writing code with the same effect, so a full
+             ;; warning is justified.
+             (typecase name
+               ((member :conc-name :constructor :copier :predicate :include
+                        :print-function :print-object :type :initial-offset :pure)
+                (warn "slot name of ~S indicates probable syntax error in DEFSTRUCT" name))))
+           (values name default default-p
                    (uncross type) type-p
                    read-only ro-p)))
         (t (error 'simple-program-error