Steel Bank Common Lisp

DEFSTRUCT allows () as slot

Reported by Tobias C. Rittweiler on 2010-09-09
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Low
Unassigned

Bug Description

A colleque of mine changed a defclass to defstruct,
and forgot to remove the superclass list:

  (defstruct quux ()
    x)

SBCL happily compiles that one down, and creates a
a layout with an initial slot named NIL. However,
it should actually choke on it because that syntax
is not allowed as per DEFSTRUCT's CLHS entry.

I cannot reproduce it easily, but this actually
manifested itself by the following nasty PCL error.

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION
    SB-MOP:SLOT-DEFINITION-LOCATION (1)>
when called with arguments
  (#<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION NIL {D4CED51}>).
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [RETRY] Retry calling the generic function.
 1: [RETRY] Retry SLIME REPL evaluation request.
 2: [*ABORT] Return to SLIME's top level.
 3: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" RUNNING {BE9AC21}>)

Backtrace:
  0: ((SB-PCL::FAST-METHOD NO-APPLICABLE-METHOD (T)) #<unavailable argument> #<unavailable argument> #<STANDARD-GENERIC-FUNCTION SB-MOP:SLOT-DEFINITION-LOCATION (1)>)[:EXTERNAL]
      Locals:
        SB-DEBUG::ARG-0 = 4
        SB-DEBUG::ARG-1 = :<NOT-AVAILABLE>
        SB-DEBUG::ARG-2 = :<NOT-AVAILABLE>
        SB-DEBUG::ARG-3 = #<STANDARD-GENERIC-FUNCTION SB-MOP:SLOT-DEFINITION-LOCATION (1)>
  1: (SB-PCL::CALL-NO-APPLICABLE-METHOD #<STANDARD-GENERIC-FUNCTION SB-MOP:SLOT-DEFINITION-LOCATION (1)> (#<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION NIL {D4CED51}>))
      Locals:
        SB-DEBUG::ARG-0 = #<STANDARD-GENERIC-FUNCTION SB-MOP:SLOT-DEFINITION-LOCATION (1)>
        SB-DEBUG::ARG-1 = (#<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION NIL {D4CED51}>)
  2: (SB-PCL::ACCESSOR-VALUES-INTERNAL ..)
      Locals:
        SB-DEBUG::ARG-0 = SB-PCL::READER
        SB-DEBUG::ARG-1 = #<STRUCTURE-CLASS SAGE>
        SB-DEBUG::ARG-2 = (#<SB-PCL::GLOBAL-READER-METHOD ..>)
  3: (SB-PCL::CACHE-MISS-VALUES-INTERNAL ..)
      Locals:
        SB-DEBUG::ARG-0 = #<STANDARD-GENERIC-FUNCTION (SB-PCL::SLOT-ACCESSOR :GLOBAL ..) (1)>
        SB-DEBUG::ARG-1 = #S(SB-PCL::ARG-INFO ..)
        SB-DEBUG::ARG-2 = (#<SB-KERNEL:LAYOUT for SAGE {B75F851}>)
        SB-DEBUG::ARG-3 = (#<STRUCTURE-CLASS SAGE>)
        SB-DEBUG::ARG-4 = ((SB-PCL::CLASS-EQ #<STRUCTURE-CLASS SAGE>))
        SB-DEBUG::ARG-5 = SB-PCL::ACCESSOR
  4: (SB-PCL::CACHE-MISS-VALUES ..)
  5: (SB-PCL::INITIAL-DFUN ..)
      Locals:
        SB-DEBUG::ARG-0 = #<STANDARD-GENERIC-FUNCTION (SB-PCL::SLOT-ACCESSOR :GLOBAL ..) (1)>
        SB-DEBUG::ARG-1 = (#S(SAGE ..))

Tobias C. Rittweiler (tcr) wrote :

Stas Boukarev pointed out to me that NIL actually *is* allowed because a slot-name
is specified to be a symbol -- and NIL is a symbol of course.

This means that there's some bug somewhere of the line (when (...) ...) which
is not valid for a slot name being NIL.

Still, using NIL as a slot-name is sufficiently weird to warrant a style-warning, methinks. :-)

Nikodemus Siivola (nikodemus) wrote :

The PCL problem is probably related to CLHS forbidding constants as DEFCLASS slot names.

A reproducible test-case would be nice...

Nikodemus Siivola (nikodemus) wrote :

Not "Triaged" till we have a test-case.

Changed in sbcl:
importance: Undecided → Low
status: New → Confirmed

Test case:

(defstruct foo nil)
(defun baz (x) (slot-value x 'nil))
(baz (make-foo :nil 3))

The reason for this is that NIL is used as a "safe" slot-name that can't exist in accessor-values-internal, passed to find-slot-definition, and downstream code is then surprised by actually finding a structure-slotd.

Changed in sbcl:
status: Confirmed → Triaged
assignee: nobody → Christophe Rhodes (csr21-cantab)
Changed in sbcl:
status: Triaged → Fix Committed
assignee: Christophe Rhodes (csr21-cantab) → nobody
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers