REDUCE type warning, ignores :INITIAL-VALUE

Bug #1885515 reported by Michael South on 2020-06-29
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

SBCL version 2.0.4.

In some circumstances REDUCE type inference appears to ignore INITIAL-VALUE and assumes that the sequence elements are always passed as the first argument to the lambda. If it has sufficient knowledge of the sequence's type it may issue a warning if the lambda declares something diffent. Don't know if it actually affects code generation.

In the test cases below, the sequence is a vector of STRING, but :INITIAL-VALUE is a fixnum, and the lambda declares it so.

In the first case we define two arrays and declare their types, and then select one of the two to pass to the reduction. The selection appears to be crucial in generating the warning, and it makes no difference whether it appears in the REDUCE form or in the LET assignments.

In the second case, ignoring T2 makes the warning go away; this is done by placing T1 on both sides of the IF: '(if choose t1 t1)'

In the third case, omitting the type declarations for T1 and T2 make the warning go away.

Finally, the first case is repeated to verify it wasn't a one-time problem.

sbcl --no-userinit
This is SBCL 2.0.4, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (defun xbar (choose)
  (let* ((t1 (make-array 0 :element-type 'string :initial-contents nil))
         (t2 (make-array 0 :element-type 'string :initial-contents nil)))
    (declare (type (simple-array string 1) t1 t2))
    (reduce (lambda (r x) (declare (type fixnum r) (type t x))
              (+ r (sxhash x)))
            (the (simple-array string 1) (if choose t1 t2))
            :initial-value 0)))
; in: DEFUN XBAR
; (REDUCE
; (LAMBDA (R X)
; (DECLARE (TYPE FIXNUM R)
; (TYPE T X))
; (+ R (SXHASH X)))
; (THE (SIMPLE-ARRAY STRING 1)
; (IF CHOOSE
; T1
; T2))
; :INITIAL-VALUE 0)
;
; caught WARNING:
; The function (LAMBDA (R X) :IN XBAR) is called by REDUCE with (STRING STRING) but it accepts (FIXNUM
; T).
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
XBAR
* (defun xbar (choose)
  (let* ((t1 (make-array 0 :element-type 'string :initial-contents nil))
         (t2 (make-array 0 :element-type 'string :initial-contents nil)))
    (declare (type (simple-array string 1) t1 t2) (ignorable t2))
    (reduce (lambda (r x) (declare (type fixnum r) (type t x))
              (+ r (sxhash x)))
            (the (simple-array string 1) (if choose t1 t1))
            :initial-value 0)))
WARNING: redefining COMMON-LISP-USER::XBAR in DEFUN
XBAR
* (defun xbar (choose)
  (let* ((t1 (make-array 0 :element-type 'string :initial-contents nil))
         (t2 (make-array 0 :element-type 'string :initial-contents nil)))
    (reduce (lambda (r x) (declare (type fixnum r) (type t x))
              (+ r (sxhash x)))
            (the (simple-array string 1) (if choose t1 t2))
            :initial-value 0)))
WARNING: redefining COMMON-LISP-USER::XBAR in DEFUN
XBAR
* ;; And back to the original case...
(defun xbar (choose)
  (let* ((t1 (make-array 0 :element-type 'string :initial-contents nil))
         (t2 (make-array 0 :element-type 'string :initial-contents nil)))
    (declare (type (simple-array string 1) t1 t2))
    (reduce (lambda (r x) (declare (type fixnum r) (type t x))
              (+ r (sxhash x)))
            (the (simple-array string 1) (if choose t1 t2))
            :initial-value 0)))
; in: DEFUN XBAR
; (REDUCE
; (LAMBDA (R X)
; (DECLARE (TYPE FIXNUM R)
; (TYPE T X))
; (+ R (SXHASH X)))
; (THE (SIMPLE-ARRAY STRING 1)
; (IF CHOOSE
; T1
; T2))
; :INITIAL-VALUE 0)
;
; caught WARNING:
; The function (LAMBDA (R X) :IN XBAR) is called by REDUCE with (STRING STRING) but it accepts (FIXNUM
; T).
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
WARNING: redefining COMMON-LISP-USER::XBAR in DEFUN
XBAR
*

Happens on both Linux and OSX.

~ $ uname -a
Linux speedy 5.4.0-20200222a-speedyized #19 SMP PREEMPT Sat Feb 22 18:08:28 PST 2020 x86_64 Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz GenuineIntel GNU/Linux

This is SBCL 2.0.4, an implementation of ANSI Common Lisp.

*features*
(:ASDF-PACKAGE-SYSTEM :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX
 :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :X86-64 :GENCGC :64-BIT :ANSI-CL
 :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LINUX :LITTLE-ENDIAN
 :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB :SB-PACKAGE-LOCKS
 :SB-THREAD :SB-UNICODE :SBCL :UNIX)

$ uname -a
Darwin msouth-mbp.msouth.org 19.0.0 Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64 x86_64

This is SBCL 2.0.4, an implementation of ANSI Common Lisp.

*features*
(:QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2
 :ASDF :OS-MACOSX :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :X86-64
 :GENCGC :64-BIT :ANSI-CL :BSD :COMMON-LISP :DARWIN :IEEE-FLOATING-POINT
 :LITTLE-ENDIAN :MACH-O :PACKAGE-LOCAL-NICKNAMES :SB-CORE-COMPRESSION :SB-LDB
 :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL :UNIX)

Stas Boukarev (stassats) on 2020-06-29
Changed in sbcl:
status: New → Confirmed
Stas Boukarev (stassats) on 2020-07-06
Changed in sbcl:
status: Confirmed → Fix Committed
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers