Why
A signature mismatch printed every enclosing module in full, then the two declarations, then their locations as "file:line:" lines with a label on the next line that read like headings with nothing under them, and the reasons without a break. Which text was where had to be matched up by hand, and declarations that read the same looked like a declaration not including itself. The type checker's errors separate their parts with blank lines and indent the content under a lead-in.
Includemod.report_error now leaves out a module or module type comparison when an item inside it follows, so that only the items that differ are printed, each after a line naming where it is: "In module P:", "In module type P.T:", "In the result of functor P:", "In the parameter X of functor P:", or "At position ..." otherwise, once for items at the same position. Missing items are listed in the order of the expected signature, and in a functor's parameter, where inclusion is reversed, the implementation's side is still the actual declaration.
modifiedDiagnostic type declaration in an interface
// Foo.restype t = {a: int, b: int}// Foo.resitype t = {x: int, y: int}Before
After
The implementation Foo.resThe implementation Foo.resdoes not match the interface foo.cmi:does not match the interface foo.cmi:Type declarations do not match: Actual declaration (Foo.res:1:1-25): type t = {a: int, b: int} type t = {a: int, b: int}is not included in Expected declaration (Foo.resi:1:1-25): type t = {x: int, y: int} type t = {x: int, y: int}Foo.resi:1:1-25: Expected declarationFoo.res:1:1-25: Actual declaration Fields number 1 have different names, a and x.Fields number 1 have different names, a and x.
modifiedDiagnostic value in a nested module
// Foo.resmodule Inner = { let value = "not an int"}// Foo.resimodule Inner: { let value: int}Before
After
In module Inner:In module Inner:Modules do not match: { let value: string }is not included in { let value: int }In module Inner:Values do not match: let value: string is not included in let value: intFoo.resi:2:3-16: Expected declarationFoo.res:2:7-11: Actual declaration Actual declaration (Foo.res:2:7-11): let value: string Expected declaration (Foo.resi:2:3-16): let value: int
modifiedDiagnostic functor result
module type S = { type t}module M: { module F: (X: S) => S with type t = X.t} = { module F = (X: S) => { type t = int }}Before
After
Signature mismatch:Signature mismatch:Modules do not match: …In module F:Modules do not match: …At position module F: (X) => <here>Modules do not match: …At position module F: (X) => <here>Type declarations do not match: In the result of functor F: Actual declaration (functor_signature_mismatch.res:9:5-16): type t = int type t = intis not included in Expected declaration (functor_signature_mismatch.res:6:36): type t = X.t type t = X.tfunctor_signature_mismatch.res:6:36: Expected declarationfunctor_signature_mismatch.res:9:5-16: Actual declaration
modifiedDiagnostic functor parameter
module M: { module F: (X: {let a: int}) => {}} = { module F = (X: {let a: string}) => {}}Before
After
Signature mismatch:Modules do not match:… the module, then the functor, each pair printed in fullAt position module F: (X: <here>) => ...Values do not match: let a: int is not included in let a: stringinclusion_layout_functor_parameter.res:12:7-19: Expected declarationinclusion_layout_functor_parameter.res:6:7-16: Actual declarationIn the parameter X of functor F: Actual declaration (inclusion_layout_functor_parameter.res:12:7-19): let a: string Expected declaration (inclusion_layout_functor_parameter.res:6:7-16): let a: int
modifiedDiagnostic missing values
module M: { module N: { let a: int let b: string }} = { module N = {}}Before
After
Signature mismatch:Modules do not match:… the module, then module N, each pair printed in full In module N:In module N:The value `b` is required but not providedinclusion_layout_missing_values.res:5:5-17: Expected declarationIn module N:The value `a` is required but not providedinclusion_layout_missing_values.res:4:5-14: Expected declaration The value `a` is required but not provided. Expected declaration (inclusion_layout_missing_values.res:4:5-14): let a: int The value `b` is required but not provided. Expected declaration (inclusion_layout_missing_values.res:5:5-17): let b: string
modifiedDiagnostic runtime representation reason
Before
After
Their runtime representations differ:Their runtime representations differ:the first declaration states values whose typeof is "object",the second declaration states values whose typeof is "string". The actual declaration states values whose typeof is "object". The expected declaration states values whose typeof is "string".
Subst.extension_constructor dropped the location of an extension constructor when writing a .cmi, unlike every other declaration. It keeps it now, so the expected side of an extension mismatch has a position, and reanalyze also records a reference to an exception declared in an interface.
modifiedDiagnostic extension constructor declared in an interface
// Foo.restype t += Boom(string)// Foo.resitype t += Boom(int)
Before
After
Foo.res: Expected declarationExpected declaration (Foo.resi:4:3-13): type t += Boom(int)
Review
- Is anything dropped that was useful? The enclosing modules printed in full repeated the items below them; the path line names where the items are. A big part was printed as "..." for the same reason, so the size check is gone.
- Why "actual" and "expected" and not "implementation" and "interface"? The same errors are reported for module type constraints and functor arguments within one file, where there is no interface.