ocaml / merlin

Context sensitive completion for OCaml in Vim and Emacs
https://ocaml.github.io/merlin/
MIT License
1.58k stars 232 forks source link

`case-analysis` fails to load module #1786

Open liam923 opened 3 months ago

liam923 commented 3 months ago

See the below cram test:

Create the types Box.t and Either.t, each of which are in their own module and file.
Box.t depends on Either.t.

  $ cat >either.ml <<EOF
  > type t = Left | Right
  > EOF

  $ cat >box.ml <<EOF
  > type t = Box of Either.t
  > EOF

  $ $OCAMLC either.ml box.ml

Create the file that we'll use to demonstrate the error

  $ touch foo.ml

In Persistent_env.find_pers_struct, the module Either fails to be found:

  $ $MERLIN single case-analysis -start 3:8 -end 3:8 -filename foo.ml <<EOF
  > let f (x : Box.t) =
  >   match x with
  >   | Box _ -> 10
  > EOF
  {
    "class": "exception",
    "value": "Not_found
  Raised at Ocaml_typing__Persistent_env.find_pers_struct in file \"src/ocaml/typing/persistent_env.ml\", line 259, characters 28-43
  Called from Ocaml_typing__Persistent_env.find in file \"src/ocaml/typing/persistent_env.ml\", line 309, characters 6-59
  Called from Ocaml_typing__Env.find_module_components in file \"src/ocaml/typing/env.ml\", line 1100, characters 17-43
  Called from Ocaml_typing__Env.find_structure_components in file \"src/ocaml/typing/env.ml\", line 1111, characters 23-56
  Called from Ocaml_typing__Env.find_type_data in file \"src/ocaml/typing/env.ml\", line 1211, characters 19-50
  Called from Ocaml_typing__Env.find_type_descrs in file \"src/ocaml/typing/env.ml\", line 1275, characters 2-24
  Called from Merlin_analysis__Destruct.gen_patterns in file \"src/analysis/destruct.ml\", line 102, characters 16-45
  Called from Merlin_analysis__Destruct.refine_complete_match in file \"src/analysis/destruct.ml\", line 675, characters 18-56
  Called from Merlin_utils__Misc.try_finally in file \"src/utils/misc.ml\", line 45, characters 8-15
  Re-raised at Merlin_utils__Misc.try_finally in file \"src/utils/misc.ml\", line 62, characters 10-24
  Called from Merlin_utils__Misc.protect_refs.(fun) in file \"src/utils/misc.ml\", line 82, characters 10-14
  Re-raised at Merlin_utils__Misc.protect_refs.(fun) in file \"src/utils/misc.ml\", line 84, characters 38-45
  Called from Ocaml_typing__Persistent_env.without_cmis in file \"src/ocaml/typing/persistent_env.ml\", lines 156-158, characters 10-27
  Called from Merlin_utils__Std.let_ref in file \"src/utils/std.ml\", line 695, characters 8-12
  Re-raised at Merlin_utils__Std.let_ref in file \"src/utils/std.ml\", line 697, characters 30-39
  Called from Merlin_commands__New_commands.run in file \"src/commands/new_commands.ml\", line 93, characters 15-53
  Called from Merlin_utils__Std.let_ref in file \"src/utils/std.ml\", line 695, characters 8-12
  Re-raised at Merlin_utils__Std.let_ref in file \"src/utils/std.ml\", line 697, characters 30-39
  Called from Merlin_utils__Misc.try_finally in file \"src/utils/misc.ml\", line 45, characters 8-15
  Re-raised at Merlin_utils__Misc.try_finally in file \"src/utils/misc.ml\", line 62, characters 10-24
  Called from Stdlib__Fun.protect in file \"fun.ml\", line 34, characters 8-15
  Re-raised at Stdlib__Fun.protect in file \"fun.ml\", line 39, characters 6-52
  Called from Merlin_kernel__Mocaml.with_state in file \"src/kernel/mocaml.ml\", line 18, characters 8-38
  Re-raised at Merlin_kernel__Mocaml.with_state in file \"src/kernel/mocaml.ml\", line 20, characters 42-53
  Called from Dune__exe__New_merlin.run.(fun) in file \"src/frontend/ocamlmerlin/new/new_merlin.ml\", lines 106-107, characters 14-50
  ",
    "notifications": []
  }

If we explicitly use Either (by opening it), we force it to load and the query works
as expected:

  $ $MERLIN single case-analysis -start 4:8 -end 4:8 -filename foo.ml <<EOF
  > open Either
  > let f (x : Box.t) =
  >   match x with
  >   | Box _ -> 10
  > EOF
  {
    "class": "return",
    "value": [
      {
        "start": {
          "line": 4,
          "col": 4
        },
        "end": {
          "line": 4,
          "col": 9
        }
      },
      "Box (Left) | Box (Right)"
    ],
    "notifications": []
  }

Merlin version: b602e95e (master)

voodoos commented 3 months ago

Thanks for the report and the reproduction @liam923 It's an interesting corner-case... cc @xvw since it concerns destruct (even if not the core of it's logic).

xvw commented 3 months ago

Interesting ! Thanks ! I'll take a look soon!