You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7a1245e
Browse filesBrowse the repository at this point in the historyBrowse files
Show signature mismatches as the actual and expected declaration, each under its location
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.
Diagnostic modified (type declaration in an interface):
Example:
// Foo.res
type t = {a: int, b: int}
// Foo.resi
type t = {x: int, y: int}
Before (diagnostic):
The implementation Foo.res
does not match the interface foo.cmi:
Type declarations do not match:
type t = {a: int, b: int}
is not included in
type t = {x: int, y: int}
Foo.resi:1:1-25:
Expected declaration
Foo.res:1:1-25:
Actual declaration
Fields number 1 have different names, a and x.
After (diagnostic):
The implementation Foo.res
does not match the interface foo.cmi:
Actual declaration (Foo.res:1:1-25):
type t = {a: int, b: int}
Expected declaration (Foo.resi:1:1-25):
type t = {x: int, y: int}
Fields number 1 have different names, a and x.
Diagnostic modified (value in a nested module):
Example:
// Foo.res
module Inner = {
let value = "not an int"
}
// Foo.resi
module Inner: {
let value: int
}
Before (diagnostic):
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: int
Foo.resi:2:3-16:
Expected declaration
Foo.res:2:7-11:
Actual declaration
After (diagnostic):
In module Inner:
Actual declaration (Foo.res:2:7-11):
let value: string
Expected declaration (Foo.resi:2:3-16):
let value: int
Diagnostic modified (functor result):
Example:
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 (diagnostic):
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:
type t = int
is not included in
type t = X.t
functor_signature_mismatch.res:6:36:
Expected declaration
functor_signature_mismatch.res:9:5-16:
Actual declaration
After (diagnostic):
Signature mismatch:
In the result of functor F:
Actual declaration (functor_signature_mismatch.res:9:5-16):
type t = int
Expected declaration (functor_signature_mismatch.res:6:36):
type t = X.t
Diagnostic modified (functor parameter):
Example:
module M: {
module F: (X: {let a: int}) => {}
} = {
module F = (X: {let a: string}) => {}
}
Before (diagnostic):
Signature mismatch:
Modules do not match:
… the module, then the functor, each pair printed in full
At position module F: (X: <here>) => ...
Values do not match: let a: int is not included in let a: string
inclusion_layout_functor_parameter.res:12:7-19:
Expected declaration
inclusion_layout_functor_parameter.res:6:7-16:
Actual declaration
After (diagnostic):
In 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
Diagnostic modified (missing values):
Example:
module M: {
module N: {
let a: int
let b: string
}
} = {
module N = {}
}
Before (diagnostic):
Signature mismatch:
Modules do not match:
… the module, then module N, each pair printed in full
In module N:
The value `b` is required but not provided
inclusion_layout_missing_values.res:5:5-17:
Expected declaration
In module N:
The value `a` is required but not provided
inclusion_layout_missing_values.res:4:5-14:
Expected declaration
After (diagnostic):
In module N:
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
Diagnostic modified (runtime representation reason):
Before (diagnostic):
Their runtime representations differ:
the first declaration states values whose typeof is "object",
the second declaration states values whose typeof is "string".
After (diagnostic):
Their runtime representations differ:
The actual declaration states values whose typeof is "object".
The expected declaration states values whose typeof is "string".
Diagnostic modified (extension constructor declared in an interface):
Example:
// Foo.res
type t += Boom(string)
// Foo.resi
type t += Boom(int)
Before (diagnostic):
Foo.res:
Expected declaration
After (diagnostic):
Expected declaration (Foo.resi:4:3-13):
type t += Boom(int)
Matching modified (what an inclusion error prints, Includemod.report_error):
Before (text):
every symptom from the whole module down, a big one as "...";
"In module P:" or "At position <module type with <here>>" before each
After (text):
the header (implementation against interface), then only the symptoms
at the end of the path: a module or module type comparison is left out
when an item inside it follows
"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 consecutive items at the same position
missing items in the order of the expected signature
in a functor's parameter, where inclusion is reversed, the
implementation's side is still the actual declaration
Representation modified (extension constructor locations in .cmi files, Subst.extension_constructor):
Before (representation):
ext_loc ↦ Location.none when saving
After (representation):
ext_loc ↦ kept when locations are kept, as for every other declaration
effect: reanalyze also records a reference to an exception declared in an interface
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.
Review: 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.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLpf7RN1MiRcubPgRn
Signed-off-by: Christoph Knittel <ck@cca.io>
- Show a signature mismatch as the actual and the expected declaration, each under its location, with only the items that differ and the module path to them.
2
+
- Keep the location of an extension constructor or exception declared in an interface, so that errors and reanalyze point to it.
0 commit comments