Open
Description
Expected Behavior
Dune RPC should return the same diagnostic as the OCaml compiler
Actual Behavior
Some lines are off by one but it doesn't look like it's consistent
Reproduction
I have this simple file:
module type A = sig
val a : int
val b : float
end
module M (A : A) = struct
let a = A.a + A.a
end
module AI = struct
let a = 3
let b = 4
end
module MI = M (AI)
When compiling I have the following error:
File "bin/main.ml", line 15, characters 12-18:
15 | module MI = M (AI)
^^^^^^
Error: Modules do not match: sig val a : int val b : int end
is not included in A
Values do not match: val b : int is not included in val b : float
The type int is not compatible with the type float
File "bin/main.ml", line 3, characters 2-15: Expected declaration
File "bin/main.ml", line 12, characters 6-7: Actual declaration
If I replace A.a + A.a with A.a + A.b I have the following compilation error:
File "bin/main.ml", line 7, characters 16-19:
7 | let a = A.a + A.b
^^^
Error: The value A.b has type float but an expression was expected of type
int
But if I start an LSP server with a dune watch process I receive the following diagnostic:
("/home/mattias/test_ocaml/bin/main.ml"
((:message
"The value \"A.b\" has type \"float\" but an expression was expected of type\n \"int\""
:range (:end (:character 19 :line 6) :start (:character 16 :line 6))
:severity 1 :source "dune")
(:message
"Modules do not match: sig val a : int val b : int end is not included in \nA\nValues do not match: val b : int is not included in val b : float\nThe type int is not compatible with the type float"
:range (:end (:character 18 :line 14) :start (:character 12 :line 14))
:relatedInformation
[(:location
(:range (:end (:character 15 :line 3) :start (:character 2 :line 3)) :uri
"file:///home/mattias/test_ocaml/bin/main.ml")
:message "Expected declaration")
(:location
(:range (:end (:character 7 :line 12) :start (:character 6 :line 12)) :uri
"file:///home/mattias/test_ocaml/bin/main.ml")
:message "Actual declaration")]
:severity 1 :source "ocamllsp")))
As you can see
- the first error is located at line 6, off by -1
- the second error is located at line 14, off by -1
- the related information are located at line 3 and 12
Now if I fix this file and create its corresponding mli file with the following content
module type A = sig
val a : int
val b : int
end
I receive the following diagnostic:
("/home/mattias/test_ocaml/bin/main.ml"
((:message
"The implementation \"bin/main.ml\"\ndoes not match the interface \"bin/main.ml\": \nModule type declarations do not match:\n module type A = sig val a : int val b : float end\ndoes not match\n module type A = sig val a : int val b : int end\nAt position \"module type A = <here>\"\nModule types do not match:\n sig val a : int val b : float end\nis not equal to\n sig val a : int val b : int end\nAt position \"module type A = <here>\"\nValues do not match: val b : float is not included in val b : int\nThe type \"float\" is not compatible with the type \"int\""
:range (:end (:character 0 :line 0) :start (:character 0 :line 0))
:relatedInformation
[(:location
(:range (:end (:character 13 :line 2) :start (:character 2 :line 2)) :uri
"file:///home/mattias/test_ocaml/bin/main.mli")
:message "Expected declaration")
(:location
(:range (:end (:character 15 :line 2) :start (:character 2 :line 2)) :uri
"file:///home/mattias/test_ocaml/bin/main.ml")
:message "Actual declaration")]
:severity 1 :source "dune")))
This time, the related information are located at line 2, off by -1.
This inconsistent behaviour prevents me from saying "increment line by one unless you're formatting a related information part".
Specifications
- Version of
dune
(output ofdune --version
): 3.17.2 - Version of
ocaml
(output ofocamlc --version
): 5.3.0 - Operating system (distribution and version):
OS: cachyos rolling Kernel: x86_64 Linux 6.14.2-2-cachyos