Structure accessor compile-time type mismatch gives uninformative source form.

Bug #1982042 reported by Charles
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Undecided
Unassigned

Bug Description

I believe this a regression, but I'm not sure. Either way:

(defstruct foo
  (a 0 :type integer))

(defun x (foo)
  (car (foo-a foo)))

gives this unhelpful warning:

; caught WARNING:
; Derived type of
; (SB-KERNEL:%INSTANCE-REF (THE COMMON-LISP-USER::FOO COMMON-LISP-USER::FOO) 0)
; is
; (VALUES INTEGER &OPTIONAL),
; conflicting with its asserted type
; LIST.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
; printed 1 note

I would have expected the accessor name to be in the source form rather than an opaque call to %INSTANCE-REF, which makes it hard to figure out which slot is being referred to.

Revision history for this message
Charles (karlosz) wrote :

This must have regressed with the slew of structure changes done in the past decade. CMU CL gives a much better error:

; In: DEFUN X

; (FOO-A FOO)
; Warning: Result is a INTEGER, not a (VALUES &OPTIONAL LIST &REST T).

Revision history for this message
Christophe Rhodes (csr21-cantab) wrote :

The source-path associated with the WARNING is the same as with the previous note, which then doesn't get repeated (documented at http://www.sbcl.org/manual/#The-Parts-of-a-Compiler-Diagnostic). You can see this if you muffle the note with

    (declaim (muffle-conditions compiler-note))

at the top of the file.

I'm not sure that I would take the description of CMU CL's error as "better": it doesn't explain at all why the result being an INTEGER is a problem; the fact that FOO-A returns an integer is only a problem because it is being used as the argument to CAR.

Revision history for this message
Charles (karlosz) wrote :

I'm not sure what you mean. Instead of

 (SB-KERNEL:%INSTANCE-REF (THE COMMON-LISP-USER::FOO COMMON-LISP-USER::FOO) 0)

wouldn't it be better to have:

 (FOO-A FOO)

My issue isn't with the new wording: It definitely makes more sense to report it as the derived type conflicting with the asserted type. Rather I am wondering whether users really want to see %instance-ref with a numeric index rather than (FOO-A FOO) (which was the point with the comparison with cmu cl)

Revision history for this message
Christophe Rhodes (csr21-cantab) wrote :

I think my point is that the message you're quoting is not the whole story.

The full warning message includes the source path, and is:

; file: /tmp/foo.lisp
; in: DEFUN BAR
; (CAR (FOO-A X))
;
; caught WARNING:
; Derived type of (SB-KERNEL:%INSTANCE-REF (THE FOO X) 0) is
; (VALUES INTEGER &OPTIONAL),
; conflicting with its asserted type
; LIST.
; See also:
; The SBCL Manual, Node "Handling of Types"

which includes both the source that the user has written, including the call to FOO-A, and also what it has been transformed into by SBCL. I can live with that, particularly if it consistent with a general principle for interpreting compiler diagnostics.

That said, we're not completely honouring the general principles.

Adding (defmacro baz (y) `(foo-a ,y)) and replacing the explicit call to foo-a with a call to baz does not give the processing path that I might have expected. Is this because the processing path is associated with the BAZ call, but the diagnostic is associated with the call to CAR?

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.