DOLIST macro expansion can't handled type declaration properly.
Describe the problem here.
How to reproduce the issue
> (compile nil
(lambda ()
(dolist (s '("foo" "bar" "baz") s)
(declare (type string s))
(check-type s string))))
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; Style warning:
;;; ! The variable S is not used.
;;; Warning:
;;; ! Failed type assertion for value NIL and type STRING
;;; Warning:
;;; ! In LET body, the type of the form S is SYMBOL, not STRING.
;;; End of Pass 1.
#<compiled-function 0000000004d8ebc0>
T
> (macroexpand
'(dolist (s '("foo" "bar" "baz") s)
(declare (type string s))
(check-type s string)))
(BLOCK NIL
(LET* ((SI::%DOLIST-VAR '("foo" "bar" "baz")) S) ;; <==== initialized by NIL
(DECLARE (TYPE STRING S))
(SI:WHILE SI::%DOLIST-VAR
(SETQ S (FIRST SI::%DOLIST-VAR))
(CHECK-TYPE S STRING)
(SETQ SI::%DOLIST-VAR (REST SI::%DOLIST-VAR)))
(SETQ S NIL) ;; <=== SETQed by NIL
S))
How to fix this issue (in my opinion)
https://gitlab.com/embeddable-common-lisp/ecl/blob/develop/src/lsp/export.lsp#L60
`(block nil
(let* ((%dolist-var ,expr)
,var)
(declare ,@declarations)
(si::while %dolist-var
(setq ,var (first %dolist-var))
,@body
(setq %dolist-var (rest %dolist-var)))
,(when exit `(setq ,var nil))
,@exit))
fix to ===>
`(block nil
(let* ((%dolist-var ,expr)
(,var (first %dolist-var)))
(declare ,@declarations)
(si::while %dolist-var
,@body
(setq %dolist-var (rest %dolist-var))
(setq ,var (first %dolist-var)))
,(when exit
`(let ((,var nil))
(declare (ignorable ,var))
,@exit))))
then...
> (macroexpand
'(dolist (s '("foo" "bar" "baz") s)
(declare (type string s))
(check-type s string)))
(BLOCK NIL
(LET* ((SI::%DOLIST-VAR '("foo" "bar" "baz")) (S (FIRST SI::%DOLIST-VAR)))
(DECLARE (TYPE STRING S))
(SI:WHILE SI::%DOLIST-VAR
(CHECK-TYPE S STRING)
(SETQ SI::%DOLIST-VAR (REST SI::%DOLIST-VAR))
(SETQ S (FIRST SI::%DOLIST-VAR)))
(LET ((S NIL))
(DECLARE (IGNORABLE S))
S)))
T
Provide details regarding ECL version (or preferably commit), operating system and if revelant the build options and versions of the build tools.
> (lisp-implementation-version)
"16.1.3"