[MOP] #'(SETF CLASS-NAME) does not accept non-symbol data as class name
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
The MOP states that the class's name is allowed to be arbitrary Lisp data, not just a symbol. See http://
Therefore:
CL-USER> (defclass quux () ((fred :accessor fred)))
#<STANDARD-CLASS QUUX>
CL-USER> (setf (class-name *) '(quux))
This produces an error:
Required argument is not a symbol: (QUUX)
[Condition of type SB-INT:
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {100C510603}>)
Backtrace:
0: (SB-PCL:
Locals:
METHOD = #<SB-MOP:
1: (SB-PCL:
Locals:
ADD/REMOVE = SB-PCL::ADD
CLASS = #<STANDARD-CLASS (COMMON-
DSLOTD = #<SB-MOP:
DSLOTDS = (#<SB-MOP:
LOCATION = #S(SB-C:
SLOT-DOC = NIL
SLOT-NAME = FRED
2: ((:METHOD SHARED-INITIALIZE :AFTER (SB-PCL::STD-CLASS T)) #<STANDARD-CLASS (COMMON-
Locals:
CLASS = #<STANDARD-CLASS (COMMON-
3: ((SB-PCL::EMF SHARED-INITIALIZE) #<unused argument> #<unused argument> #<STANDARD-CLASS (COMMON-
Locals:
4: ((:METHOD REINITIALIZE-
Locals:
5: ((SB-PCL::EMF REINITIALIZE-
Locals:
6: ((:METHOD (SETF CLASS-NAME) (T T)) (QUUX) #<STANDARD-CLASS (COMMON-
Locals:
CLASS = #<STANDARD-CLASS (COMMON-
7: ((LAMBDA ()))
Locals:
#:*504 = #<STANDARD-CLASS (COMMON-
#:NEW1 = (QUUX)
8: (SB-INT:
Locals:
9: (EVAL (SETF (CLASS-NAME *) (QUOTE (QUUX))))
Locals:
Inspecting the class object shows that the class's name was changed, though:
CL-USER> (class-name *)
(FROB)
The error was in the fixup, as hinted by SHARED-INITIALIZE :AFTER and SB-PCL:
I have traced the further sources of the error to:
https:/
https:/
SBCL 1.4.11.
Further investigation shows that SB-MOP: METHOD- LAMBDA- LIST returns an erroneous value.
CL-USER> (defclass quux () ((fred :accessor fred :initform 42))) LISP-USER: :QUUX> method- lambda- list) METHOD- LAMBDA- LIST) METHOD- LAMBDA- LIST #<STANDARD-METHOD (COMMON-LISP:SETF COMMON- LISP:CLASS- NAME) (T T) {10008A0023}>) METHOD- LAMBDA- LIST returned (SB-PCL::NEW-VALUE CLASS) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:REINITIALI ZE-INSTANCE :BEFORE (SB-PCL: :SLOT-CLASS) {10009F6043}>) METHOD- LAMBDA- LIST returned (CLASS &KEY SB-PCL: :DIRECT- SUPERCLASSES) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:REINITIALI ZE-INSTANCE :AFTER (SB-PCL: :SLOT-CLASS) {10009F6053}>) METHOD- LAMBDA- LIST returned (CLASS &REST SB-PCL::INITARGS &KEY) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:REINITIALI ZE-INSTANCE (SB-PCL: :SLOT-OBJECT) {10008A21F3}>) METHOD- LAMBDA- LIST returned
(SB-KERNEL: INSTANCE &REST SB-PCL::INITARGS) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:SHARED- INITIALIZE :AFTER (SB-PCL::STD-CLASS T) {1000598433}>) METHOD- LAMBDA- LIST returned
(SB-PCL: :DIRECT- SUPERCLASSES NIL SB-PCL: :DIRECT- SUPERCLASSES- P)
(SB-PCL: :DIRECT- SLOTS NIL SB-PCL: :DIRECT- SLOTS-P)
(SB-PCL: :DIRECT- DEFAULT- INITARGS NIL SB-PCL: :DIRECT- DEFAULT- INITARGS- P)) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:SHARED- INITIALIZE :BEFORE (CLASS T) {1000598453}>) METHOD- LAMBDA- LIST returned METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:SHARED- INITIALIZE (SB-PCL: :SLOT-OBJECT T) {1000164C23}>) METHOD- LAMBDA- LIST returned
(SB-KERNEL: INSTANCE SB-PCL::SLOT-NAMES &REST SB-PCL::INITARGS) METHOD- LAMBDA- LIST #<SB-MOP: STANDARD- READER- METHOD COMMON- LISP-USER: :FRED, slot:FRED, ((CLASS #<STANDARD-CLASS (COMMON- LISP-USER: :FROB) {100C572303}>)) {100CC3C6F3}>) METHOD- LAMBDA- LIST returned ((FROB)) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:INITIALIZE -INSTANCE (SB-PCL: :SLOT-OBJECT) {1000164CF3}>) METHOD- LAMBDA- LIST returned
(SB-KERNEL: INSTANCE &REST SB-PCL::INITARGS) METHOD- LAMBDA- LIST #<STANDARD-METHOD COMMON- LISP:SHARED- INITIALIZE (SB-PCL: :SLOT-OBJECT T) {1000164C23}>) METHOD- LAMBDA- LIST returned
(SB-KERNEL: INSTANCE SB-PCL::SLOT-NAMES &REST SB-PCL::INITARGS)
#<STANDARD-CLASS COMMON-
CL-USER> (trace sb-mop:
(SB-MOP:
CL-USER> (setf (class-name (find-class 'quux)) '(frob))
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
(CLASS SB-PCL::SLOT-NAMES &KEY
0: (SB-MOP:
0: SB-MOP:
(CLASS SB-PCL::SLOT-NAMES &KEY SB-PCL::NAME)
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
0: (SB-MOP:
0: SB-MOP:
;; Error signaled here
In particular:
0: (SB-MOP: METHOD- LAMBDA- LIST #<SB-MOP: STANDARD- READER- METHOD COMMON- LISP-USER: :FRED, slot:FRED, ((CLASS #<STANDARD-CLASS (COMMON- LISP-USER: :FROB) {100C572303}>)) {100CC3C6F3}>) METHOD- LAMBDA- LIST returned ((FROB))
0: SB-MOP:
((FROB)) is not a valid unspecialized lambda list. This lambda list should have had a single mandatory argument that is a symbol, so, something like (OBJECT).
METHOD-LAMBDA-LIST is only a reader, which means that the lambda list is set to the method metaobject in a different way.