Weak type inference in BREAK

Bug #1814367 reported by Michał Herda on 2019-02-02
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
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.

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

Michał 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.

Stas Boukarev (stassats) wrote :

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

Michał Herda (phoe-krk) wrote :

Truth be told, neither do I.

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  Edit
Everyone can see this information.

Other bug subscribers