ocaml-lsp icon indicating copy to clipboard operation
ocaml-lsp copied to clipboard

Spurious `Unbound module Foo` after making changes in `foo.ml`

Open copy opened this issue 2 years ago • 7 comments

It's not 100% reproducible in my project, but the following seems to work:

opam source patdiff
cd patdiff*
rm bin/compare.mli
dune build -w bin/main.exe # leave running in the background
  1. make a type error in bin/compare.ml (I added let x = "a" + 42 at the bottom)
  2. observe that bin/main.ml reports Unbound module Compare (somewhat expected, as there is no mli)
  3. fix the type error (I commented it out)
  4. the Unbound module Compare error in main.ml is still there

Relevant for reproduction, I open both files in the same vim instance, and use the following to autosave on every change:

command! AutoWrite autocmd TextChanged,InsertLeave <buffer> try | undojoin | silent! update | catch /^Vim\%((\a\+)\)\=:E790/ | finally | silent! update | endtry
augroup autowrite
    autocmd!
    autocmd Filetype ocaml AutoWrite
augroup END

Restarting lsp fixes the issue. Other changes to either ml file seem to preserve the issue.

Here is a recording: https://asciinema.org/a/6HG60xy5grl0hlF5BxMcxxPLK And the lsp logfile: lsp.log

copy avatar Nov 09 '23 23:11 copy

I made a fairly minimal reproduction:

#!/bin/sh
cat >dune-project <<EOF
(lang dune 3.11)
EOF

cat >main.ml <<EOF
open Lib
let () = print_string v
EOF

cat >lib.ml <<EOF
let v = "42"
EOF

cat >dune <<EOF
(executable
 (name main)
 (modules main)
 (libraries lib))

(library
 (name lib)
 (modules lib))
EOF

opam switch create . 5.1.0
ocaml-platform
# Inferring tools version...
#  -> dune.3.11.1 will be built from source
#  -> dune-release.2.0.0 will be installed from cache
#  -> merlin.4.12-501 will be installed from cache
#  -> ocaml-lsp-server.1.16.2 will be installed from cache
#  -> odoc.2.3.0 will be installed from cache
#  -> ocamlformat.0.26.1 will be installed from cache

dune build

###################
#### No issue with manual builds

# 1. Introduce an error in lib and rebuild:
# cat >lib.ml <<EOF
# let v : float = "42"
# EOF

# 2. Now lsp says, in main.ml:
# ocamllsp: Unbound module Lib

# 3. Fix the error and rebuild:
# cat >lib.ml <<EOF
# let v = "42"
# EOF

# 4. lsp has no more errors

####################
##### But with dune -watch

# 1. Run `dune build -w`
# 2. Introduce the same error than before
# 3. LSP shows unbound module error in main.ml
# 4. Fix the issue, dune should rebuild ok
# 5. Go back to main.ml. Unbound module error stays even after edit, even after
#    exiting and restarting dune. Only restarting the lsp removes the stalled
#    error.

@rgrinberg : I guess the issue is likely due to Dune RPC since manual dune builds don't triggers it. It happens quite often when working on a project with dune watch active.

voodoos avatar Nov 10 '23 10:11 voodoos