intero error: wrong-type-argument stringp nil
Asked Answered
H

1

5

I'm trying to get intero running. After install, opening a Haskell file from an existing stack project results in:

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  signal(wrong-type-argument (stringp nil))
  flycheck-buffer()
  flycheck-buffer-automatically()
  flycheck-perform-deferred-syntax-check()
  set-window-buffer(#<window 1 on Lib.hs> #<buffer Lib.hs>)
  window--display-buffer(#<buffer Lib.hs> #<window 1 on Lib.hs> reuse ((inhibit-same-window)))
  display-buffer-same-window(#<buffer Lib.hs> ((inhibit-same-window)))
  display-buffer(#<buffer Lib.hs> (display-buffer-same-window (inhibit-same-window)))
  pop-to-buffer(#<buffer Lib.hs> (display-buffer-same-window (inhibit-same-window)) nil)
  pop-to-buffer-same-window(#<buffer Lib.hs>)
  find-file("~/test/src/Lib.hs" t)
  funcall-interactively(find-file "~/test/src/Lib.hs" t)
  call-interactively(find-file nil nil)
  command-execute(find-file)

When I run flycheck-buffer in the same buffer, nothing happens, even when there are errors in the source code.

Here are the contents of my .emacs file:

(setq debug-on-error t)

(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(package-initialize)
(package-refresh-contents)

(package-install 'intero)
(add-hook 'haskell-mode-hook 'intero-mode)

Since I'm on Mac Os I also tried adding (as suggested on the flycheck page):

(package-install 'exec-path-from-shell)
(exec-path-from-shell-initialize)

But it makes no difference.

Here are the installed package versions:

$ ls ~/.emacs.d/elpa/
archives/
company-20191114.1356/
dash-20191109.1327/
epl-20180205.2049/
flycheck-20191126.1329/
haskell-mode-20191120.1923/
intero-20191103.1239/
pkg-info-20150517.1143/

This is using GNU Emacs 26.3.

Harlan answered 26/11, 2019 at 20:26 Comment(4)
You can try stepping through flycheck-buffer by instrumenting it with edebug-defun (see Edebug). Looking at the code of flycheck-buffer, it's not clear to me where the error happens: if you are unable to use Edebug, you might at least try loading the uncompiled version of flycheck.el with (load-library "flycheck.el") and posting a more detailed backtrace.Impediment
Using edebug reveals that in flycheck-buffer the call to (flycheck-start-current-syntax-check checker) returns nil. Does this mean that it can't find the intero binary (checker is set to "intero")?Harlan
Returning nil is not a problem: does it signal an error? If so, try again and step into it with i instead of executing the call with SPACE, and then continue drilling down until you find the culprit.Impediment
So it's somewhere below flycheck-syntax-check-start, the subexpression (funcall (flycheck-checker-get checker 'start) checker callback) does not return. I can't seem to get inside it with i, it says "funcall is a builtin function".Harlan
A
6

TL;DR

I found two issues and a (at least temporary) fix for each of them. I am submitting pull requests for both of them, but in the mean time you can fix the issue for yourself either by editing the intero.el file directly, or (recommended way) by using the great el-patch package.

1) intero-ghc-version not set

This is due to the fact of using the intero-ghc-version local variable instead of calling the function (intero-ghc-version) in the intero-ghci-output-flags function (L.2668) intero.el

Fix: patch the function intero-ghci-output-flags : replace

(split-string intero-ghc-version "\\."))))

by

(split-string (intero-ghc-version) "\\."))))

(notice the added parentheses)

2) misuse of append for string concatenation in intero-start-process-in-buffer

append is for lists, concat is for strings, an easy mistake, especially when in Haskell String is equivalent to [Char] (so technically... a list!)

fix: patch the function intero-start-process-in-buffer, L.2335 of the intero.el: replace

 (process-send-string process (append ":set " flag "\n")))

by

 (process-send-string process (concat ":set " flag "\n")))

line 2335 of the current version of the source code, using el-patch)

Once these modifications are made, you should be up and running!


Initial answer


Same issue here.

Not a definitive answer, but I have the same issue and might have pinned down the issue to the function intero-ghci-output-flags being run as the intero-ghc-version variable is not set properly. Feel free to correct me as I might have missed some things.

By following the error messages, I confirm it happens in (flycheck-start-current-syntax-check checker) in the flycheck-buffer function.
Running this directly from the haskell buffer shows that the error happens when calling (split-string intero-ghc-version "\\.") from the intero-ghci-output-flags function in the intero.el file (Line 2671).

This tries to split the intero version (as set by the intero-ghc-version function above in the file).
It seems the variable's value is nil, as confirmed by running M-x describe-variable -> intero-ghc-version.

During my tests I got seemingly imprevisible results from (intero-ghc-version). Sometimes (at least on the first run?) it returns "8.4.4",
sometimes it fails with "Wrong type argument: stringp, (58 115 101 116 32 45 102 111 98 106 ...)

I am able to manually run the function intero-ghci-output-flags and get the proper output without error, once, and it fails if I run it a second time.

the function (intero-ghc-version-raw) consistently returns "8.4.4" however.

After experimenting the error message that spontaneously appears is transformed to:

Debugger entered--Lisp error: (wrong-type-argument stringp (58 115 101 116 32 45 102 111 98 106 101 99 116 45 99 111 100 101 . "\n"))
  process-send-string(#<process stack> (58 115 101 116 32 45 102 111 98 106 101 99 116 45 99 111 100 101 . "\n"))
  #f(compiled-function (flag) #<bytecode 0x1785fe9>)("-fobject-code")
  mapc(#f(compiled-function (flag) #<bytecode 0x1785fe9>) ("-fobject-code"))
  intero-start-process-in-buffer(#<buffer  intero:backend:pubiber /home/mika/programmation/haskell/pubiber> nil #<buffer Lib.hs> nil)
  intero-get-worker-create(backend nil #<buffer Lib.hs> nil)
  intero-buffer(backend)
  intero-eldoc()

The ASCII char sequence in the error message is ":set -fobject-code". The "-fobject-code" in the message is the result of the intero-ghci-output-flags function, so it seems it finally worked properly but the rest of the code failed.

Note: The fact that the file gets re-evaluated whenever intero tries to start a session might to explain why I get inconsistent results when running the functions several times.

PS running arch linux, system updated a few minutes ago, all emacs package updated.

---- EDIT ----

So after looking a bit more, in the function intero-start-process-in-buffer, that uses the flags to start the intero process in the lines 2334-2337:

      (set-process-query-on-exit-flag process nil)
      (mapc
       (lambda (flag)
         (process-send-string process (append ":set " flag "\n")))
       (intero-ghci-output-flags))
      (process-send-string process ":set -fdefer-type-errors\n")

they use append instead of concat to create the command.
replacing append by concat fixes this second error, and intero boots normally and seems to work properly (after setting intero-ghc-version).

---- EDIT 2 ----

Just figured out the original issue: The function uses the variable intero-ghc-version instead of calling the function with the same name. The function is supposed to act as a lazy loader of the value, calling intero-ghc-version-raw the first time, and returning the cached value the subsequent times.

Calling the variable directly didn't allow the value to be set initially. See the TL;DR for the temporary fix.

Agnesagnese answered 22/12, 2019 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.