jyp / dante

389 stars 52 forks source link

Dante breaks on parse error with Company completion at the same time #129

Closed cumber closed 1 year ago

cumber commented 4 years ago

Multiple times an hour, I find Dante suddenly stops processing things, which I notice by flycheck's error annotations no longer updating as I'm changing the file.

Frequently (but not 100% of the time) it seems to happen while I'm editing import lists, when dante runs an auto-check half way through what I'm writing, so the resultant state is an error saying parse error (possibly incorrect indentation or mismatched brackets) that just doesn't go away.

Running dante-restart invariably fixes the problem (although I also have to disable and re-enable flycheck, despite #14 being reported and fixed a couple of years ago).

Trying to narrow down the conditions that cause it, I've discovered that I can reliably trigger it by having Dante run at the same time as Company completion when the current buffer contains a parse error.

For example, after cabal init and touch cabal.project.local (to use the new-repl method, since that's what I'm doing in my real project), I added an import to the generated Main.hs:

module Main where

import Data.List ( intercalate )

main :: IO ()
main = putStrLn "Hello, Haskell!"

If I take out the ( intercalate ) part and type it back in with a pause part way through so that Flycheck runs Dante and Company would show a completion prompt (e.g. ( inter and then pause), then the problem triggers 100% of the time; a parse error is reported at the following main and never changes with following updates.

If I type ( intercalate ) fast enough without pausing, then there is no problem.

If I type ( in and then pause (prefix short enough that Company completion doesn't run) then Dante reports the parse error at main, but continues to respond to further changes.

If instead of deleting the whole import list I keep the parentheses and only delete intercalate, then typing inter back and pausing gets a completion prompt from Company, but this problem doesn't occur (since the buffer doesn't contain a Haskell parse error, just an unknown identifier error?).

In my real usage I could swear that I've seen the error that breaks Dante be something other than a parse error, but I haven't reproduced an example.

With company-mode disabled I didn't encounter this problem, so possibly related to #48?

I'm not sure whether it helps any, but when Dante stops responding, running dante-diagnose shows this output:

default-directory "/tmp/scratch/foo/"
dante-command-line ("cabal" "new-repl" "foo" "--builddir=dist/dante")
dante-state (ghc-err loading)
dante-queue (#[257 "r\302\301!\203\0\302\301!q\210\212\301b\210\300!*\207" [#[257 "\211\204\0\300?\205\0\306\307\310\"\304\"\211\303\205\0\211\211\203(\0\307\311\"\301!\262\202i\0\302\211\300\211\312\313\305!\304#\314\315\211\305\315\316%\300\203G\0\317\202H\0\320\321\322\323\324\325\326\300\301\304\305&\327\"\330\331%\"\262\262\262\262\262\262\262\262\207" [nil #[257 "\303\304p!!\301\305\306\307\310\311\312\313\314\300
\"\315\"\316\317%\"\320\203I\0@\321!
>\2040\0\322\323\324D\"\210\211\325H\326=\204=\0\211B\262\210\211T\262A\262\202\0\266\211\237\262\"\207" [haskell-dante #[128 "\301\302\300#\207" [#s(flycheck-syntax-check #<buffer Main.hs> haskell-dante nil "/tmp/scratch/foo/") apply flycheck-report-buffer-checker-status] 5 "

(fn &rest ARGS)"] cl-struct-flycheck-error-tags dante-local-name dante-temp-file-name finished nil mapcar make-byte-code 257 "\302\300p\301$\207" vconcat vector [dante-fly-message] 6 "

(fn IT)" 0 type-of signal wrong-type-argument flycheck-error 7 splice] 13 "

(fn MESSAGES)"] 14161 nil "/tmp/scratch/foo/Main.hs" "/run/user/1000/danteI1d9pc.hs" s-equals\? buffer-local-value dante-loaded-file dante-load-message puthash dante-local-name write-region nil 0 ":set -fbyte-code" ":set -fobject-code" dante-async-call make-byte-code 257 "p\211\304q\306\305\203
\0\307\202\0\310\300\203\0\311\202\0\312\313\303!Q!\314\312\315\316\317\320\321\322\301\302#\323\"\324\325%#\262\262\262\207" vconcat vector [dante-async-write ":r" ":l " "*" "" dante-local-name dante-load-loop nil make-byte-code 257 "\211\211G\305U\203\0\211A\262\242\202\0\306\307\310GD\"\211A\262\242@\301\211\266\203\302q\300!\262\262\207" vconcat vector [dante-loaded-file dante-load-message 3 signal wrong-number-of-arguments nil] 7 "

(fn V17)"] 16 "

(fn V12)" dante-interpreted dante-temp-epoch dante-original-buffer-map] 23 "

(fn V4)"] #<marker at 52 in Main.hs> marker-buffer] 3 "

(fn BUFFER)"])
dante-loaded-file "/tmp/scratch/foo/Main.hs"
dante-load-message (("/run/user/1000/danteI1d9pc.hs" "5:1" "error:" "    parse error (possibly incorrect indentation or mismatched brackets)
"))
lcr-process-callback #[257 "\303\304\305\300#\210r\306\302!\203\0\306\302!q\210\212\302b\210\301!*\207" [#<buffer *dante:foo::/tmp/scratch/foo/*> #[257 "\302\303\"\210\300\304\305\306#!\210\307\301!\207" [#[257 "\300\242P\300\240\301\304\300\242\"\240\305\302\242!\262\262\207" [("| ") (nil) (#[0 "\303\242?\211\203\0\305\306\307\310\311\312\302\303\304#\313\"\314\315%!\202,\0\316\302\242\317\320\224SO!\301q\300!\262\262\207" [#[257 "\300\211\242A\240\302\301\242!\207" [((#("import Data.List ( inter" 0 6 (face haskell-keyword-face fontified t) 6 7 (fontified t) 7 11 (face haskell-constructor-face fontified t) 11 16 (face haskell-constructor-face fontified t) 16 17 (fontified t) 17 18 (face (rainbow-delimiters-depth-1-face) fontified t) 18 19 (fontified t) 19 24 (face (rainbow-identifiers-identifier-7) fontified t)))) (#[0 "\302\242\203\0\302\242@\211\304\305\306\307\310\311\302\303\"\312\"\313\314%\"\262\207\315\316\300\"\304\305\306\317\310\311\301!\320\"\321\322%\"\207" ["inter" #[257 "\300\242\302=\203\0\303  B\300\240\207" [(exited) unread-command-events none company-foo] 3 "

(fn CANDIDATES)"] ((#("import Data.List ( inter" 0 6 (face haskell-keyword-face fontified t) 6 7 (fontified t) 7 11 (face haskell-constructor-face fontified t) 11 16 (face haskell-constructor-face fontified t) 16 17 (fontified t) 17 18 (face (rainbow-delimiters-depth-1-face) fontified t) 18 19 (fontified t) 19 24 (face (rainbow-identifiers-identifier-7) fontified t)))) #11 dante-async-call make-byte-code 257 "\300\211\242A\240\302\301\242!\207" vconcat vector [lcr-yield] 4 "

(fn V24)" format ":complete repl %S" "\211\301!\302\303\304@\305Q!8\306\307\310\311\312\313!\314\"\315\316%A\"\266\202\300!\262\207" [s-lines 2 read "(" ")" mapcar make-byte-code 257 "\301\302\303\300P#\207" vconcat vector [replace-regexp-in-string "\\\"" ""] 6 "

(fn IT)"] 11 "

(fn V26)"] 11]) lcr-yield] 4 "

(fn V24)"] #<buffer Main.hs> ("| ") (nil) #6 dante-async-read make-byte-code 257 "\300\242P\300\240\301\304\300\242\"\240\305\302\242!\262\262\207" vconcat vector [dante-ghci-prompt string-match lcr-yield] 7 "

(fn V63)" s-trim-right 0 1] 10]) dante-ghci-prompt string-match lcr-yield] 7 "

(fn V63)"] #<buffer *dante:foo::/tmp/scratch/foo/*> dante-debug inputs s-replace "
" "" dante-schedule-next] 6 "

(fn INPUT)"] #<marker at 1 in *dante:foo::/tmp/scratch/foo/*> lcr-set-local lcr-process-callback nil marker-buffer] 5 "

(fn INPUT)"]
cumber commented 4 years ago

Oh yeah, I obtain Dante through Nix. It seems to be using commit a25ae9e5b5425cffdd88d498777e90ea8655fa37 currently.

jyp commented 1 year ago

I've given up on trying to complete on unloadable files. So this issue is fixed by default.