//lisp/dns: fails to typecheck with SBCL 2.5.7

#452
Opened by sterni at 2025-09-16T11·59+00

This is the error log:

; compiling file "/nix/store/n41chfyhihbpwlbc1b756wsa4fwx88ra-message.lisp" (written 01 JAN 1970 12:00:01 AM):
; file: /nix/store/n41chfyhihbpwlbc1b756wsa4fwx88ra-message.lisp
; in: DEFBINARY DNS-QUESTION
;     (LISP-BINARY:DEFBINARY DNS::DNS-QUESTION
;         (:BYTE-ORDER :BIG-ENDIAN :EXPORT T)
;       (DNS::QNAME "" :TYPE
;        (LISP-BINARY:CUSTOM :LISP-TYPE DNS::QNAME :READER #'DNS::READ-QNAME
;         :WRITER #'DNS::WRITE-QNAME))
;       (DNS::QTYPE 0 :TYPE DNS::DNS-TYPE)
;       (DNS::QCLASS 0 :TYPE 16))
; --> CLOSER-MOP:DEFMETHOD DEFMETHOD PROGN EVAL-WHEN
; --> SB-PCL::%DEFMETHOD-EXPANDER SB-PCL::LOAD-DEFMETHOD SB-PCL::LOAD-DEFMETHOD
; --> LIST* LET* SB-INT:NAMED-LAMBDA FUNCTION SYMBOL-MACROLET
; --> SB-PCL::FAST-LEXICAL-METHOD-FUNCTIONS
; --> SB-PCL::BIND-FAST-LEXICAL-METHOD-FUNCTIONS FLET SB-PCL::BIND-ARGS LET*
; --> LOCALLY SYMBOL-MACROLET BLOCK LET* LET SYMBOL-MACROLET PROGN SETQ THE +
; --> FUNCALL
; ==>
;   1
;
; caught WARNING:
;   Derived type of
;   (SB-KERNEL:%INSTANCE-REF (THE DNS::DNS-QUESTION SB-C::OBJECT) 1) is
;     (VALUES DNS::QNAME &OPTIONAL),
;   conflicting with its asserted type
;     STREAM.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; in: DEFBINARY DNS-RR
;     (LISP-BINARY:DEFBINARY DNS::DNS-RR
;         (:BYTE-ORDER :BIG-ENDIAN :EXPORT T)
;       (DNS::NAME NIL :TYPE
;        (LISP-BINARY:CUSTOM :LISP-TYPE DNS::QNAME :READER #'DNS::READ-QNAME
;         :WRITER #'DNS::WRITE-QNAME))
;       (TYPE 0 :TYPE DNS::DNS-TYPE)
;       (CLASS 0 :TYPE 16)
;       (DNS::TTL 0 :TYPE 32)
;       (DNS::RDLENGTH 0 :TYPE 16)
;       (DNS::RDATA #() :TYPE
;        (EVAL (CASE TYPE (# '#) (# '#) (# '#) (# '#) (OTHERWISE `#)))))
; --> CLOSER-MOP:DEFMETHOD DEFMETHOD PROGN EVAL-WHEN
; --> SB-PCL::%DEFMETHOD-EXPANDER SB-PCL::LOAD-DEFMETHOD SB-PCL::LOAD-DEFMETHOD
; --> LIST* LET* SB-INT:NAMED-LAMBDA FUNCTION SYMBOL-MACROLET
; --> SB-PCL::FAST-LEXICAL-METHOD-FUNCTIONS
; --> SB-PCL::BIND-FAST-LEXICAL-METHOD-FUNCTIONS FLET SB-PCL::BIND-ARGS LET*
; --> LOCALLY SYMBOL-MACROLET BLOCK LET* LET SYMBOL-MACROLET PROGN SETQ THE +
; --> FUNCALL
; ==>
;   1
;
; caught WARNING:
;   Derived type of (SB-KERNEL:%INSTANCE-REF (THE DNS::DNS-RR SB-C::OBJECT) 1) is
;     (VALUES DNS::QNAME &OPTIONAL),
;   conflicting with its asserted type
;     STREAM.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
;   caught 2 WARNING conditions
; wrote //build/-nix-store-n41chfyhihbpwlbc1b756wsa4fwx88ra-message.lisp.fasl

I confirmed that this issue happens with SBCL 2.5.7, but not with 2.5.5.

I am struggling to understand why this would happen:

$ nix-build -E 'with import ~/src/depot {}; nix.buildLisp.sbclWith (with third_party.lisp; [ lisp-binary ])'
$ ./result/bin/sbcl
* (load "package.lisp")
* (load "message.lisp")
; ...
* (in-package :dns)
* (macroexpand '(defbinary dns-test (:byte-order :big-endian) (qname "" :type (custom :lisp-type qname :reader #'read-qname))))
(PROGN
 (DEFSTRUCT DNS-TEST (QNAME "" :TYPE QNAME))
 (CLOSER-MOP:DEFMETHOD READ-BINARY
   ((TYPE (EQL 'DNS-TEST)) #:STREAM-SYMBOL-313)
   (LISP-BINARY-UTILS:LET-VALUES* ((#:BYTE-COUNT-312 0)
                                   (*BYTE-ORDER* *BYTE-ORDER*)
                                   (QNAME
                                    (MULTIPLE-VALUE-BIND
                                        (#:FORM-VALUE-316
                                         #:MOST-RECENT-BYTE-COUNT-315)
                                        (FUNCALL #'READ-QNAME
                                                 #:STREAM-SYMBOL-313)
                                      (COND
                                       ((NOT
                                         (NUMBERP
                                          #:MOST-RECENT-BYTE-COUNT-315))
                                        (RESTART-CASE (ERROR
                                                       (FORMAT NIL
                                                               "Evaluation of ~a did not produce a byte count as its second value"
                                                               (WITH-OUTPUT-TO-STRING
                                                                   (LISP-BINARY::OUT)
                                                                 (PRINT
                                                                  '(FUNCALL
                                                                    #'READ-QNAME
                                                                    #:STREAM-SYMBOL-313)
                                                                  LISP-BINARY::OUT))))
                                          (USE-VALUE (LISP-BINARY::VAL) :REPORT
                                                     "Enter an alternate value, dropping whatever was read."
                                                     :INTERACTIVE
                                                     (LAMBDA ()
                                                       (FORMAT T
                                                               "Enter a new value for ~a: "
                                                               'QNAME)
                                                       (LIST (EVAL (READ))))
                                                     (SETF #:FORM-VALUE-316
                                                             LISP-BINARY::VAL)
                                                     (SETF #:MOST-RECENT-BYTE-COUNT-315
                                                             0))
                                          (LISP-BINARY::ENTER-SIZE
                                           (LISP-BINARY::SIZE) :REPORT
                                           "Enter a byte count manually"
                                           :INTERACTIVE
                                           (LAMBDA ()
                                             (FORMAT T
                                                     "Enter the byte count: ")
                                             (FORCE-OUTPUT)
                                             (LIST (EVAL (READ))))
                                           (SETF #:MOST-RECENT-BYTE-COUNT-315
                                                   LISP-BINARY::SIZE))))
                                       (T
                                        (INCF #:BYTE-COUNT-312
                                              #:MOST-RECENT-BYTE-COUNT-315)
                                        #:FORM-VALUE-316)))))
     (VALUES (MAKE-DNS-TEST :QNAME QNAME) #:BYTE-COUNT-312)))
 (CLOSER-MOP:DEFMETHOD WRITE-BINARY
   ((DNS-TEST DNS-TEST) #:STREAM-SYMBOL-313)
   (LET* ((#:BYTE-COUNT-312 0) (*BYTE-ORDER* *BYTE-ORDER*))
     (WITH-SLOTS (QNAME)
         DNS-TEST
       (PROGN (INCF #:BYTE-COUNT-312 (PROGN 0)))
       #:BYTE-COUNT-312)))
 'DNS-TEST)
T

  1. macro expansion is exactly the same between both versions.

    sterni at 2025-09-16T12·03+00