Weak type inference in BREAK

Bug #1814367 reported by Michał "phoe" Herda
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Undecided
Unassigned

Bug Description

* (defclass foo () ())
#<STANDARD-CLASS COMMON-LISP-USER::FOO>
* (defun bar () (break (make-instance 'foo)))
BAR
* (defun baz () (break (make-hash-table)))
; in: DEFUN BAZ
; (BREAK (MAKE-HASH-TABLE))
;
; caught WARNING:
; Derived type of (MAKE-HASH-TABLE) is
; (VALUES HASH-TABLE &OPTIONAL),
; conflicting with its asserted type
; (OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING FUNCTION).
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
BAZ

DEFUN BAR should signal a warning, just like DEFUN BAZ does.

An instance of FOO is not of type (OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING FUNCTION) as it is not a vector or a base string, and it is not a function because it is not a funcallable instance.

SBCL 1.4.15 on Linux.

Revision history for this message
Stas Boukarev (stassats) wrote :

(defclass foo () ())

(defun bar ()
  (break (make-instance 'foo)))

(setf (find-class 'foo) (defclass f () () (:metaclass sb-mop:funcallable-standard-class)))

(defmethod initialize-instance :after ((f f) &key)
  (sb-mop:set-funcallable-instance-function f (lambda (stream) (format stream "BREAK"))))

(bar)

=>

debugger invoked on a SIMPLE-CONDITION in thread
#<THREAD "main thread" RUNNING {10005F05B3}>:
  BREAK

Revision history for this message
Michał "phoe" Herda (phoe-krk) wrote :

In other words, you need to define a class, define a function that makes its instances via MAKE-INSTANCE with a symbol, then replace the class bound to that class name with a funcallable class. Ugly, but a valid edge case.

However, this still fails when MAKE-INSTANCE is given a class instead of a class name:

* (defclass foo () ())
#<STANDARD-CLASS COMMON-LISP-USER::FOO>
* (defun bar () (break (make-instance #.(find-class 'foo))))
BAR ;; no warning

The object given to MAKE-INSTANCE is not funcallable since CHANGE-CLASS does not work on class metaobjects.

Revision history for this message
Stas Boukarev (stassats) wrote :

I don't believe you have (break (make-instance #.(find-class 'foo)) in your code.

Revision history for this message
Michał "phoe" Herda (phoe-krk) wrote :

Truth be told, neither do I.

Revision history for this message
Stas Boukarev (stassats) wrote :

It doesn't warn for (the list (make-instance 'foo)), now that can be fixed.

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.