"The value NIL is not of type SB-KERNEL:LAYOUT"
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Medium
|
Unassigned |
Bug Description
;; From Alexandria; not interesting wrt. this report.
(defun remove-from-plist (plist &rest keys)
(loop for (key . rest) on plist by #'cddr
do (assert rest () "Expected a proper plist, got ~S" plist)
unless (member key keys :test #'eq)
collect key and collect (first rest)))
(defclass my-class (standard-class)
())
(defmethod sb-mop:
t)
(defclass my-object ()
((id :type integer :reader id-of))
(:metaclass my-class))
(defmethod initialize-instance ((class my-class) &rest initargs &key name direct-
(let ((my-object-class (find-class 'my-object)))
(if (or (eq name 'my-object)
(some (lambda (class) (subtypep class my-object-class))
(apply #'call-next-method class
#| Seems deleted code (?) triggers the problem somehow. Also, it does not happen when the first argument is
(CLASS T). I've understood (I think ..) that dispatch based on the first argument for SVUC is "pointless", but
should code like this cause trouble nonetheless? |#
(defmethod sb-mop:
(if nil
(setf (slot-value object 'id) 42)
(
(eval-when (:compile-toplevel :load-toplevel :execute)
(unintern 'test)
(unintern 'a)
(unintern 'test-a))
(defclass test ()
((a :reader test-a))
(:metaclass my-class))
I'm not sure what's wrong (and it's 4 in the morning.. :P). The deletion of code might confuse the compiler or the expansion of the DEFCLASS form or something.
SBCL 1.0.32.11 (I've confirmed it happening with 1.0.29 also).
Linux blackbox 2.6.30-2-amd64 #1 SMP Fri Sep 25 22:16:56 UTC 2009 x86_64 GNU/Linux
(:HUNCHENTOOT-
:SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL :SB-SOURCE-
:IEEE-
:STACK-
:COMPARE-
:STACK-
:STACK-
:CYCLE-COUNTER :COMPLEX-FLOAT-VOPS :FLOAT-EQL-VOPS :INLINE-CONSTANTS
:OS-PROVIDES-
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
Hi,
status confirmed
importance medium
tags clos mop pcl
done
Lars Rune Nøstdal <email address hidden> writes:
> (defclass my-object () superclasses) slot-value- using-class ((class my-class) (object my-object) eslotd) method) ))
> ((id :type integer :reader id-of))
> (:metaclass my-class))
>
> [...]
> (defmethod initialize-instance ((class my-class) &rest initargs &key name direct-
> (defmethod sb-mop:
> (if nil
> (setf (slot-value object 'id) 42)
> (call-next-
As mentioned on IRC, this is not conforming MOP code: here you
instantiate MY-CLASS, then you define methods that are applicable to
objects of MY-CLASS; however, "Portable methods on specified generic
functions specialized to portable metaobject classes must be defined
before any instances of those classes (or any subclasses) are created,
either directly or indirectly by a call to make-instance." The main
workaround for you is I think to use (find-class 'my-object nil) in your
initialize-instance method.
That said, I was able to reduce this to a test case which I think is
legal MOP code and fails in the same way:
(defclass my-class (standard-class) validate- superclass slot-value- using-class call-next- method) ))
())
(defmethod sb-mop:
((class my-class) (super-class standard-class))
t)
(defvar *foo*)
(defmethod sb-mop:
((class my-class) (object standard-object) eslotd)
(if *foo*
(setf (slot-value object 'id) 42)
(
(defclass my-object ()
((id :type integer :reader id-of))
(:metaclass my-class)))
(defclass test (my-object)
((a :reader test-a))
(:metaclass my-class))
I've Cced this to Pascal to ask him to check that the above is actually
legal MOP; in parallel, I'm working on a diagnosis and possible cure for
SBCL.
Cheers,
Christophe