undefined-fun warning on with-slots+(setf slot-value) on structures due to lossage in type derivation
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Medium
|
Unassigned |
Bug Description
If you compile
(defstruct foo
slot)
(defun quux (cont)
(funcall cont))
(defun bar (foo-struct)
(declare (type foo foo-struct))
(with-slots (slot) foo-struct
(tagbody
(quux #'(lambda ()
TAG)))
you'll get the following undefined-function warning:
; file: /tmp/quux.lisp
; in: DEFUN BAR
; (SETF SLOT :VALUE)
; --> SETQ SETF
; ==>
; (SB-PCL:
;
; caught STYLE-WARNING:
; undefined function: (SB-PCL:
This is same function definition but with the use of WITH-SLOTS
expanded:
(defun bar2 (foo-struct)
(declare (type foo foo-struct))
(LET ((G951 FOO-STRUCT))
(DECLARE (IGNORABLE G951))
(DECLARE (SB-PCL:
G951
(
(TAGBODY
(QUUX #'(LAMBDA ()
TAG))))
The reason for that warning is that SBCL is, for some reason, not able
to derive the type of the G951 gensym in the closure passed to QUUX.
SBCL needs to know that G951 is of a structure type so it can transform
the SLOT-VALUE to the structure's accessor function.
I guess that SBCL gives up on type derivation at some point.
Notice that
(defun bar3 (foo-struct)
(declare (type foo foo-struct))
(SYMBOL-
(TAGBODY
(QUUX #'(LAMBDA ()
TAG)))
That is the alpha-converted version of the expansion, does _not_ trigger
the warning.
Ideally some compiler wizard will be able to hack type derivation.
I wonder why the definition of WITH-SLOTS contains this bit:
,@(let ((instance (extract-the instance)))
(and (symbolp instance)
Which is responsible for that %VARIABLE-REBINDING declaration you see in
BAR2.
Can't WITH-SLOTS simply omit the gensym-binding if the INSTANCE is a
symbol (and not a symbol-macro)?
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
This bug seems not to be reproducible on Linux x86-32, but on x86-64 it is.
SBCL version 1.0.34.7 on both systems.