jaredly / jaredly/reason-language-server
Unbound local modules
Nobody has claimed this yet.
- Dominant language
- OCaml
- Stars
- 649
- Forks
- 85
- PR merge metrics
- No merged PRs in 30d
Description
Modules opened from relative files are reported as unbound although the corresponding files exist. E.g. for
```
λ tree chapter_3/
chapter_3/
├── dune
├── solutions.ml
└── test.ml
```
and the following line in `chapter_3/test.ml`
```
open Solutions
```
reason-language-server reports `Error: Unbound module Solutions`.
## Steps to reproduce
1. **Start project code-server**
```sh
git clone https://github.com/sinnerschrader/ocaml-from-the-very-beginning
cd ocaml-from-the-very-beginning
git checkout code-server
docker-compose up # start browser at localhost:8443
```
2. **Generate .merlin files / cross check**
* Open code-server terminal via `Terminal` > `New Terminal`
* Execute `dune runtest`
* See all tests executing successfully without "Unbound module" errors
3. **Access `chapter_3/test.ml`**

4. **See `Solutions` being reported as unbound although `chapter_3/solutions.ml` exists**
/repo/node_modules/.lsp/debug.log
```
Hello - from /root/.code-server/extensions/jaredly.reason-vscode-1.5.2/bin.native.linux
Previous log location: /tmp/lsp.log
Sending notification {"jsonrpc": "2.0", "method": "client/registerCapability", "params": {"registrations": [{"id": "watching", "method": "workspace/didChangeWatchedFiles", "registerOptions": {"watchers": [{"globPattern": "**/bsconfig.json", "globPattern": "**/.merlin"}]}}]}}
Sending response {"id": 0, "jsonrpc": "2.0", "result": {"capabilities": {"textDocumentSync": 1, "hoverProvider": true, "completionProvider": {"resolveProvider": true, "triggerCharacters": ["."]}, "signatureHelpProvider": {"triggerCharacters": ["("]}, "definitionProvider": true, "typeDefinitionProvider": true, "referencesProvider": true, "documentSymbolProvider": true, "codeActionProvider": true, "executeCommandProvider": {"commands": ["reason-language-server.add_to_interface_inner"]}, "codeLensProvider": {"resolveProvider": true}, "documentHighlightProvider": true, "documentRangeFormattingProvider": true, "documentFormattingProvider": true, "documentFormattingProvider": true, "renameProvider": true}}}
Read message
{"jsonrpc":"2.0","method":"initialized","params":{}}
Read message
{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"reason_language_server":{"location":"","build_system_override_by_root":{},"refmt":"","lispRefmt":"","format_width":"80","per_value_codelens":false,"dependencies_codelens":true,"opens_codelens":true,"show_module_path_on_hover":true,"reloadOnChange":false,"show_debug_errors":false,"autoRebuild":true}}}}
Read message
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml","languageId":"ocaml","version":1,"text":"open OUnit2\nopen Solutions\n\nlet tests =\n [\n \"not false => true\">:: \n (fun _ -> assert_equal true (not false));\n\n \"not false => true\">::\n (fun _ -> assert_equal false (not true));\n\n \"nsum 10\">::\n (fun _ -> assert_equal 0 (nsum 0));\n\n \"nsum 10\">::\n (fun _ -> assert_equal 55 (nsum 10));\n\n \"exp 2 2\">::\n (fun _ -> assert_equal 4 (exp 2 2));\n\n \"exp 2 0\">::\n (fun _ -> assert_equal 1 (exp 2 0));\n\n (* \"exp 2 -1\">::\n (fun _ -> assert_equal 0.5 (exp 2. -1)); *)\n\n \"isupper A\">::\n (fun _ -> assert_equal true (isupper 'A'));\n\n \"isupper u\">::\n (fun _ -> assert_equal false (isupper 'u'));\n\n \"isupper 0\">::\n (fun _ -> assert_equal false (isupper '0'));\n\n \"islower A\">::\n (fun _ -> assert_equal false (islower 'A'));\n\n \"islower u\">::\n (fun _ -> assert_equal true (islower 'u'));\n\n \"islower 0\">::\n (fun _ -> assert_equal false (islower '0'));\n ]\n\nlet () =\n run_test_tt_main (\"tests\" >::: tests)\n"}}}
Found a `dune` file at /repo/chapter_3
]] Making a new jbuilder package at /repo/chapter_3
=== Project root: /repo
Detected `opam` dependency manager for local use
=== Build dir: /repo/_build
Get ocaml stdlib dirs
Include subdirs? no :/
Got a compiled base /repo/_build/default/chapter_3/.test.eobjs
Local file: /repo/chapter_3/solutions.ml
Local .cmt file: /repo/_build/default/chapter_3/.test.eobjs/Solutions.cmt
Local file: /repo/chapter_3/test.ml
Local .cmt file: /repo/_build/default/chapter_3/.test.eobjs/Test.cmt
>> Collecting deps for /root/.opam/latest/lib/variantslib
>> Collecting deps for /root/.opam/latest/lib/typerep
>> Collecting deps for /root/.opam/latest/lib/time_now
>> Collecting deps for /root/.opam/latest/lib/stdio
>> Collecting deps for /root/.opam/latest/lib/splittable_random
>> Collecting deps for /root/.opam/latest/lib/sexplib0
>> Collecting deps for /root/.opam/latest/lib/sexplib
>> Collecting deps for /root/.opam/latest/lib/ppx_sexp_conv/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/ppx_module_timer/runtime
>> Collecting deps for /root/.opam/latest/lib/ppx_inline_test/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/ppx_inline_test/config
>> Collecting deps for /root/.opam/latest/lib/ppx_hash/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/ppx_expect/config
>> Collecting deps for /root/.opam/latest/lib/ppx_expect/common
>> Collecting deps for /root/.opam/latest/lib/ppx_expect/collector
>> Collecting deps for /root/.opam/latest/lib/ppx_enumerate/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/ppx_compare/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/ppx_bench/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/ppx_assert/runtime-lib
>> Collecting deps for /root/.opam/latest/lib/parsexp
>> Collecting deps for /root/.opam/latest/lib/ocaml
>> Collecting deps for /root/.opam/latest/lib/oUnit
>> Collecting deps for /root/.opam/latest/lib/jane-street-headers
>> Collecting deps for /root/.opam/latest/lib/fieldslib
>> Collecting deps for /root/.opam/latest/lib/core_kernel/base_for_tests
>> Collecting deps for /root/.opam/latest/lib/core_kernel
>> Collecting deps for /root/.opam/latest/lib/bytes
>> Collecting deps for /root/.opam/latest/lib/bin_prot/shape
>> Collecting deps for /root/.opam/latest/lib/bin_prot
>> Collecting deps for /root/.opam/latest/lib/base_quickcheck
>> Collecting deps for /root/.opam/latest/lib/base_bigstring
>> Collecting deps for /root/.opam/latest/lib/base/shadow_stdlib
>> Collecting deps for /root/.opam/latest/lib/base/md5
>> Collecting deps for /root/.opam/latest/lib/base/caml
>> Collecting deps for /root/.opam/latest/lib/base
>> Collecting deps for /root/.opam/latest/lib/ocaml
Depedency dirs /root/.opam/latest/lib/variantslib /root/.opam/latest/lib/typerep /root/.opam/latest/lib/time_now /root/.opam/latest/lib/stdio /root/.opam/latest/lib/splittable_random /root/.opam/latest/lib/sexplib0 /root/.opam/latest/lib/sexplib /root/.opam/latest/lib/ppx_sexp_conv/runtime-lib /root/.opam/latest/lib/ppx_module_timer/runtime /root/.opam/latest/lib/ppx_inline_test/runtime-lib /root/.opam/latest/lib/ppx_inline_test/config /root/.opam/latest/lib/ppx_hash/runtime-lib /root/.opam/latest/lib/ppx_expect/config /root/.opam/latest/lib/ppx_expect/common /root/.opam/latest/lib/ppx_expect/collector /root/.opam/latest/lib/ppx_enumerate/runtime-lib /root/.opam/latest/lib/ppx_compare/runtime-lib /root/.opam/latest/lib/ppx_bench/runtime-lib /root/.opam/latest/lib/ppx_assert/runtime-lib /root/.opam/latest/lib/parsexp /root/.opam/latest/lib/ocaml /root/.opam/latest/lib/oUnit /root/.opam/latest/lib/jane-street-headers /root/.opam/latest/lib/fieldslib /root/.opam/latest/lib/core_kernel/base_for_tests /root/.opam/latest/lib/core_kernel /root/.opam/latest/lib/bytes /root/.opam/latest/lib/bin_prot/shape /root/.opam/latest/lib/bin_prot /root/.opam/latest/lib/base_quickcheck /root/.opam/latest/lib/base_bigstring /root/.opam/latest/lib/base/shadow_stdlib /root/.opam/latest/lib/base/md5 /root/.opam/latest/lib/base/caml /root/.opam/latest/lib/base /root/.opam/latest/lib/ocaml
>> Build system running: opam exec -- dune build @install --root .
>>> stdout
>>> stderr
[WARNING] Running as root is not recommended
Affected files:
Cleaning bsconfig.json
Sending notification {"jsonrpc": "2.0", "method": "textDocument/publishDiagnostics", "params": {"uri": "file:///repo/chapter_3/bsconfig.json", "diagnostics": []}}
Running diagnostics for file:///repo/chapter_3/test.ml
➡️ running bsc /root/.opam/latest/bin/ocamlopt.opt -c -I '/repo/_build/default/chapter_3/.test.eobjs' -I '/root/.opam/latest/lib/variantslib' -I '/root/.opam/latest/lib/typerep' -I '/root/.opam/latest/lib/time_now' -I '/root/.opam/latest/lib/stdio' -I '/root/.opam/latest/lib/splittable_random' -I '/root/.opam/latest/lib/sexplib0' -I '/root/.opam/latest/lib/sexplib' -I '/root/.opam/latest/lib/ppx_sexp_conv/runtime-lib' -I '/root/.opam/latest/lib/ppx_module_timer/runtime' -I '/root/.opam/latest/lib/ppx_inline_test/runtime-lib' -I '/root/.opam/latest/lib/ppx_inline_test/config' -I '/root/.opam/latest/lib/ppx_hash/runtime-lib' -I '/root/.opam/latest/lib/ppx_expect/config' -I '/root/.opam/latest/lib/ppx_expect/common' -I '/root/.opam/latest/lib/ppx_expect/collector' -I '/root/.opam/latest/lib/ppx_enumerate/runtime-lib' -I '/root/.opam/latest/lib/ppx_compare/runtime-lib' -I '/root/.opam/latest/lib/ppx_bench/runtime-lib' -I '/root/.opam/latest/lib/ppx_assert/runtime-lib' -I '/root/.opam/latest/lib/parsexp' -I '/root/.opam/latest/lib/ocaml' -I '/root/.opam/latest/lib/oUnit' -I '/root/.opam/latest/lib/jane-street-headers' -I '/root/.opam/latest/lib/fieldslib' -I '/root/.opam/latest/lib/core_kernel/base_for_tests' -I '/root/.opam/latest/lib/core_kernel' -I '/root/.opam/latest/lib/bytes' -I '/root/.opam/latest/lib/bin_prot/shape' -I '/root/.opam/latest/lib/bin_prot' -I '/root/.opam/latest/lib/base_quickcheck' -I '/root/.opam/latest/lib/base_bigstring' -I '/root/.opam/latest/lib/base/shadow_stdlib' -I '/root/.opam/latest/lib/base/md5' -I '/root/.opam/latest/lib/base/caml' -I '/root/.opam/latest/lib/base' -I '/root/.opam/latest/lib/ocaml' -bin-annot -w @a-4-29-40-41-42-44-45-48-58-59-60-40 -strict-sequence -strict-formats -short-paths -keep-locs -impl /repo/_build/.lsp/Test.ast with pwd /repo/chapter_3
<< Making lastDefinitions with type error for file:///repo/chapter_3/test.ml
type error here File "/repo/_build/.lsp/Test.ast", line 2, characters 5-14:
Error: Unbound module Solutions
Sending notification {"jsonrpc": "2.0", "method": "textDocument/publishDiagnostics", "params": {"uri": "file:///repo/chapter_3/test.ml", "diagnostics": [{"range": {"start": {"line": 1, "character": 5}, "end": {"line": 1, "character": 14}}, "message": "Error: Unbound module Solutions", "severity": 1}]}}
Read message
{"jsonrpc":"2.0","id":1,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml"},"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}},"context":{"diagnostics":[]}}}
[server] Got a method textDocument/codeAction
[server] processing took 0.431060791016ms
Sending response {"id": 1, "jsonrpc": "2.0", "result": null}
Read message
{"jsonrpc":"2.0","id":2,"method":"textDocument/codeLens","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml"}}}
[server] Got a method textDocument/codeLens
[server] processing took 1.46317481995ms
Sending response {"id": 2, "jsonrpc": "2.0", "result": [{"range": {"start": {"line": 0, "character": 0}, "end": {"line": 0, "character": 0}}, "command": {"title": "Dependencies: ", "command": ""}}, {"range": {"start": {"line": 0, "character": 5}, "end": {"line": 0, "character": 11}}, "command": {"title": "Unused open", "command": ""}}]}
Read message
{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml"},"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}},"context":{"diagnostics":[]}}}
[server] Got a method textDocument/codeAction
[server] processing took 0.74291229248ms
Sending response {"id": 3, "jsonrpc": "2.0", "result": null}
Read message
{"jsonrpc":"2.0","id":4,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml"},"position":{"line":8,"character":20}}}
[server] Got a method textDocument/hover
[server] processing took 1.71613693237ms
Sending response {"id": 4, "jsonrpc": "2.0", "result": null}
Read message
{"jsonrpc":"2.0","id":5,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml"},"range":{"start":{"line":3,"character":11},"end":{"line":3,"character":11}},"context":{"diagnostics":[]}}}
[server] Got a method textDocument/codeAction
[server] processing took 1.33109092712ms
Sending response {"id": 5, "jsonrpc": "2.0", "result": null}
Read message
{"jsonrpc":"2.0","id":6,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///repo/chapter_3/test.ml"},"position":{"line":12,"character":1}}}
[server] Got a method textDocument/hover
[server] processing took 0.643014907837ms
Sending response {"id": 6, "jsonrpc": "2.0", "result": null}
```
Relevant ocamlopt call
```
/root/.opam/latest/bin/ocamlopt.opt -c -I '/repo/_build/default/chapter_3/.test.eobjs' -I '/root/.opam/latest/lib/variantslib' -I '/root/.opam/latest/lib/typerep' -I '/root/.opam/latest/lib/time_now' -I '/root/.opam/latest/lib/stdio' -I '/root/.opam/latest/lib/splittable_random' -I '/root/.opam/latest/lib/sexplib0' -I '/root/.opam/latest/lib/sexplib' -I '/root/.opam/latest/lib/ppx_sexp_conv/runtime-lib' -I '/root/.opam/latest/lib/ppx_module_timer/runtime' -I '/root/.opam/latest/lib/ppx_inline_test/runtime-lib' -I '/root/.opam/latest/lib/ppx_inline_test/config' -I '/root/.opam/latest/lib/ppx_hash/runtime-lib' -I '/root/.opam/latest/lib/ppx_expect/config' -I '/root/.opam/latest/lib/ppx_expect/common' -I '/root/.opam/latest/lib/ppx_expect/collector' -I '/root/.opam/latest/lib/ppx_enumerate/runtime-lib' -I '/root/.opam/latest/lib/ppx_compare/runtime-lib' -I '/root/.opam/latest/lib/ppx_bench/runtime-lib' -I '/root/.opam/latest/lib/ppx_assert/runtime-lib' -I '/root/.opam/latest/lib/parsexp' -I '/root/.opam/latest/lib/ocaml' -I '/root/.opam/latest/lib/oUnit' -I '/root/.opam/latest/lib/jane-street-headers' -I '/root/.opam/latest/lib/fieldslib' -I '/root/.opam/latest/lib/core_kernel/base_for_tests' -I '/root/.opam/latest/lib/core_kernel' -I '/root/.opam/latest/lib/bytes' -I '/root/.opam/latest/lib/bin_prot/shape' -I '/root/.opam/latest/lib/bin_prot' -I '/root/.opam/latest/lib/base_quickcheck' -I '/root/.opam/latest/lib/base_bigstring' -I '/root/.opam/latest/lib/base/shadow_stdlib' -I '/root/.opam/latest/lib/base/md5' -I '/root/.opam/latest/lib/base/caml' -I '/root/.opam/latest/lib/base' -I '/root/.opam/latest/lib/ocaml' -bin-annot -w @a-4-29-40-41-42-44-45-48-58-59-60-40 -strict-sequence -strict-formats -short-paths -keep-locs -impl /repo/_build/.lsp/Test.ast
```
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the report with chapter_3/test.ml, chapter_3/solutions.ml, and the chapter_3/dune file using the listed docker-compose and dune runtest steps. Start with the included .lsp/debug.log, especially the local .cmt entries and diagnostic command, then trace local-module handling. Done means open Solutions no longer produces an "Unbound module Solutions" diagnostic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ocaml
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100