Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interop between dune and merlin since 2.8 does not work with ppx_expect #4479

Open
jberdine opened this issue Apr 10, 2021 · 15 comments · Fixed by ocaml/opam-repository#18494
Assignees

Comments

@jberdine
Copy link
Contributor

Expected Behavior

With the project in #4478, building with dune and then querying using ocamlmerlin succeeds:

$ dune build
$ ocamlmerlin single errors -filename lib/sublib/bar.ml < lib/sublib/bar.ml
{"class":"return","value":[],"notifications":[],"timing":{"clock":39,"cpu":34,"query":2,"pp":0,"reader":4,"ppx":22,"typer":7,"error":0}}

Actual Behavior

With dune 2.7.1 and merlin 4.1, the actual behavior is as expected. But with later versions of dune, ocamlmerlin cannot find the source file:

$ dune build
$ ocamlmerlin single errors -filename lib/sublib/bar.ml < lib/sublib/bar.ml
{"class":"return","value":[{"start":{"line":0,"col":-1},"end":{"line":0,"col":-1},"type":"typer","sub":[],"valid":true,"message":"I/O error: bar.ml: No such file or\ndirectory"}],"notifications":[],"timing":{"clock":47,"cpu":29,"query":2,"pp":0,"reader":4,"ppx":21,"typer":2,"error":0}}

Reproduction

Specifications

  • Version of dune (output of dune --version): 2.8.5
  • Version of ocaml (output of ocamlc --version): 4.11.1
  • Operating system (distribution and version): macos 11.2.3
@jberdine
Copy link
Contributor Author

Cc @voodoos who may know about this.

@voodoos
Copy link
Collaborator

voodoos commented Apr 12, 2021

Yes it is a known issue and in fact it is already fixed on master (and the 411 branch).
It will be part of the next release.

You can pin the following branch if you would like to try it beforehand: opam pin https://github.com/ocaml/merlin.git#411

@jberdine
Copy link
Contributor Author

Thanks, I will retest. So far in my full environment (which uses 4.12), opam pin add dune --dev does not resolve this issue.

@voodoos
Copy link
Collaborator

voodoos commented Apr 12, 2021

It is expected because the issue in on Merlin's side, not Dune's.
opam pin https://github.com/ocaml/merlin.git should fix it for 4.12.
(for OCaml 4.11 use opam pin https://github.com/ocaml/merlin.git#411)

Please tell me if that is effectively the case when you find the time to try 🙂

@jberdine
Copy link
Contributor Author

Ah, sorry for messing up the test.

I have just tried dune 2.8.0-395-g65404cf973 and ocamlmerlin v4.1-59-g0caac250d6 . The test case in the linked PR does now work as expected. There file not found error persists in my full environment, so there is something else going on that I need to figure out.

@voodoos
Copy link
Collaborator

voodoos commented Apr 12, 2021

I will also try to reproduce.

@voodoos
Copy link
Collaborator

voodoos commented Apr 12, 2021

When isolating you test from Dune's test tree and building it with dune 2.8.3 I do get the error using merlin 4.1-412:
{"class":"return","value":[{"start":{"line":0,"col":-1},"end":{"line":0,"col":-1},"type":"typer","sub":[],"valid":true,"message":"I/O error: bar.ml: No such file or\ndirectory"}],"notifications":[],"timing":{"clock":61,"cpu":33,"query":1,"pp":0,"reader":4,"ppx":25,"typer":4,"error":0}}

However after pinning opam pin https://github.com/ocaml/merlin.git I get the expected behaviour:
{"class":"return","value":[],"notifications":[],"timing":{"clock":60,"cpu":36,"query":1,"pp":0,"reader":4,"ppx":22,"typer":9,"error":0}}

I think the issue comes from the fact that you try to build your test from inside Dune's tree. Calling dune build from that folder does nothing. To have a working test you need a run.t file with instructions that will be played in a sandboxed environment when running the tests. (and it not really possible to test ocamlmerlin behavior in Dune tests because of the sandboxing)

(I believe Cram tests folders are treated similarly to data_only folders)

@voodoos
Copy link
Collaborator

voodoos commented Apr 12, 2021

I pushed a commit to your branch with a working test that can be run using dune build @dune-merlin-ppx_expect:
6a36538

It does work when Merlin master is installed, but not with current stable (so the CI is expected to fail).

voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:
      + improve prefixing of generated constructors in Destruct by filtering
        opened modules (ocaml/merlin#1277)
      + make the destruct command more resilient to ill-typed expressions and
        when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
    - introduce a new AST node for holes (`_`), allow correct typing of these
      holes and add a new `holes` command that returns the locations of all
      holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - Windows: system command variant: do not open a window console when
      launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
      between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
    - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
      navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
    - emacs: modernization of the elisp code and conformance with coding
      guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover constructor disambiguation and record fields (ocaml/merlin#1276)
    - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:
      + improve prefixing of generated constructors in Destruct by filtering
        opened modules (ocaml/merlin#1277)
      + make the destruct command more resilient to ill-typed expressions and
        when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
    - introduce a new AST node for holes (`_`), allow correct typing of these
      holes and add a new `holes` command that returns the locations of all
      holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - Windows: system command variant: do not open a window console when
      launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
      between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
    - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
      navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
    - emacs: modernization of the elisp code and conformance with coding
      guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover constructor disambiguation and record fields (ocaml/merlin#1276)
    - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
    CHANGES:

    Tue Apr 12 11:44:22 AM CET 2021

      + merlin binary
        - external configuration reading:
          + use relative paths to communicate with Dune when possible. This solves
            issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
            fixes ocaml/merlin#1288)
          + make the `workdir` configuration value when using the
            `dune ocaml-merlin` configuration provider the same as when using
            `dot-merlin-reader` so that ppxes behaves in the same way as before
            (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
        - destruct:
          + improve prefixing of generated constructors in Destruct by filtering
            opened modules (ocaml/merlin#1277)
          + make the destruct command more resilient to ill-typed expressions and
            when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
        - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
        - introduce a new AST node for holes (`_`), allow correct typing of these
          holes and add a new `holes` command that returns the locations of all
          holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
        - Mppx: don't restore cookies after invocation. Ppx are invoked only once
          so there is no need to manage cookies. This small change should increase
          performance and should not change any other behavior (ocaml/merlin#1309)
        - Windows: system command variant: do not open a window console when
          launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
        - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
      + editor modes
        - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
          between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
        - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
          navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
        - emacs: modernization of the elisp code and conformance with coding
          guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
        - vim & emacs : new client-side "merlin use package" commands, restoring
          previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
      + test suite
        - cover constructor disambiguation and record fields (ocaml/merlin#1276)
        - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
        - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:  make the destruct command more resilient to ill-typed
      expressions and when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - windows:
      + system command variant: do not open a window console when
        launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
      + fix Emacs hanging when starting Merlin (ocaml/merlin#1263)
      + fix path canonicalization (ocaml/merlin#1254)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - emacs:
      + modernization of the elisp code and conformance with coding
        guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
      + use opam var where applicable (ocaml/merlin#1310)
      + fix "wrong number of argument" (ocaml/merlin#1250 by @atharvashukla, fixes ocaml/merlin#1234)
      + fix for Neovim's CursorMoved semantics (ocaml/merlin#1213 by @ddickstein)
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
@jberdine
Copy link
Contributor Author

@voodoos I updated the test case in #4478 so that it hits the file not found error with:

❯ dune --version
2.8.0-395-g65404cf973

and

❯ ocamlmerlin -version
The Merlin toolkit version v4.1-59-g0caac250d6, for Ocaml 4.12.0

The main point seems that using a subdir stanza leads to the file not being found.

@voodoos
Copy link
Collaborator

voodoos commented Apr 13, 2021

Indeed, this is an issue. Dune should pass more information to Merlin to handle these cases.

If I am not mistaken this is probably not a new issue, that is, not due to the new "interop", as Merlin has always been considering the ppx workdir to be the directory in which the nearest .merlin (and dune file) resides.

There is a discussion on how to improve the current behaviour (which is known to be imperfect) in this Merlin issue: ocaml/merlin#1292.

Your test is a good example of broken behaviour, thank you for taking the time to putting it in place, we will try to improve that in the next iterations of Dune.

@voodoos voodoos added the bug label Apr 13, 2021
@voodoos voodoos added this to the 3.0 milestone Apr 13, 2021
@jberdine
Copy link
Contributor Author

Thanks for the confirmation. It seems that a number of things have to conspire to trigger this behavior.

I'm not sure whether or not to categorize this as a new issue. On one hand, with dune 2.7.1, this example works. On the other hand, that seems to be because the .merlin file is generated in the lib subdir even though the nearest enclosing dune file is in the directory above, which makes the paths correct perhaps just by lucky coincidence. I wonder if there is a "quick fix" change in similar spirit to ocaml/merlin#1284 that would set the workdir to where the .merlin file used to be generated, which with subdir stanzas is not necessarily where the nearest enclosing dune file is.

Maybe this is more relevant to the linked merlin issue, but it seems clearly desirable for dune to pass enough information to merlin that merlin can replicate the ppx.exe invocation that dune uses for the "real" build. It does make me wonder if it might be more robust over the longer term to use a higher-level abstraction of e.g. having dune pass the full command to merlin, rather than merlin having to reconstruct it. This would be somewhat analogous to compilation databases.

@voodoos
Copy link
Collaborator

voodoos commented Apr 14, 2021

Oh you are right, because dune generated the .merlin in the subdir it was working before and this is a regression with the new interop. We definitively need to improve that.

Meanwhile, I just tried a silly (but easy) workaround: adding an empty dune file to your subdir tricks Merlin into the correct behaviour. (with merlin master that is pending release).

@voodoos
Copy link
Collaborator

voodoos commented Apr 14, 2021

Reopening since there is still an issue to solve. We might open a new issue without all the debug history (or hide a few comments).

@voodoos voodoos reopened this Apr 14, 2021
@kit-ty-kate kit-ty-kate reopened this May 17, 2021
@ghost ghost removed this from the 3.0 milestone Oct 20, 2021
@rgrinberg
Copy link
Member

@voodoos any updates on this? It's not clear to me what still needs to be done for this issue.

@voodoos
Copy link
Collaborator

voodoos commented Apr 27, 2022

Not sure any more, I will try to reproduce when I find the time. If I remind well there is still room for improvement in the way Merlin starts the ppxes (that might differ from what Dune does).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants