Skip to content

Variadic forms of case-lambda cause an error in geiser-syntax--scan-locals

For me, the following throws an error, which is then reported to me by corfu:

(define foo
  (case-lambda
    [(foo . bar) ba🖰]))

If I (or corfu) try to complete-symbol when the point is on the position indicated by 🖰, it gives the following error and stack-trace (the latter of which I've trimmed for concision):

Debugger entered--Lisp error: (wrong-type-argument listp bar)
  car(bar)
  (let ((n (car tail))) (if n (progn ...)) ...)
  (while tail (let ((n (car tail))) ...))
  (let ((tail (and (> nesting 0) (car (car (last form)))))) (while tail ...))
  (progn ...)
  (if (geiser-syntax--symbol-eq head 'case-lambda) (progn ...) ...)
  (let* ((head ...)))
  (if ...)
  (if ...)
  geiser-syntax--scan-locals(nil nil (case-lambda ((foo . bar) bi)) 1 (foo))

From this it seems like the issue comes from geiser-syntax--scan-locals not understanding the variadic case-lambda form. More specifically, line 441 of geiser-syntax.el iterates over (caar (last form)), which seems like the binding form. It seems like there's already the function geiser-syntax--linearize in scope which is intended to solve this problem. I tried replacing the entire dolist term with the following:

          (dolist (n (and (> nesting 0) (geiser-syntax--linearize (caar (last form)))))
            (when n (push n locals)))

This seemed to work, at least on the test case I had. I'd be happy to send it as a PR and add test cases if this can be reproduced.

Edited by rvs314