MAKE-ARRAY can't detect some ELEMENT-TYPE in compile-time
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
(defun test-ubyte32 (vector)
(declare (optimize (speed 3) (safety 0))
(let* ((n (length vector))
(res (make-array n :element-type (array-element-type vector))))
(dotimes (i n res)
(setf (aref res i) (aref vector i)))))
; note: unable to
; optimize
; due to type uncertainty:
; The first argument is a (SIMPLE-ARRAY * (*)), not a SIMPLE-STRING.
MAKE-ARRAY can't detect that RES has the same element type as VECTOR and fails to optimize it. On the other hand, the following example is successfully optimized:
(defun test-fixnum (vector)
(declare (optimize (speed 3) (safety 0))
(let* ((n (length vector))
(res (make-array n :element-type (array-element-type vector))))
(dotimes (i n res)
(setf (aref res i) (aref vector i)))))
As far as I can see, the cause of this phenomenon is that CONS-TYPE is not a singleton. LVAR-TYPE of ELEMENT-TYPE is (CONS (MEMBER UNSIGNED-BYTE) (CONS (INTEGER 32 32) NULL)) in the first example but is (MEMBER FIXNUM) in the second one. Only the latter is constant-folded as FIXNUM.
By introducing the function TYPE-CONSTANT-
Results of compilations:
https:/
Changed in sbcl: | |
status: | Fix Committed → Fix Released |
That changes
(defparameter *cons* '(0))
(defun test (x)
(declare (optimize (speed 3) (safety 0))
((cons (integer 0 0) null) x))
(find x '(#.*cons*)))
(test *cons*) => NIL.