Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/inclusion-diff-by-name.polish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Report every difference between the record fields or variant constructors of an implementation and its interface, matched by name: missing, extra, renamed and reordered entries, and say which side is the actual and which the expected declaration.
348 changes: 241 additions & 107 deletions compiler/ml/includecore.ml

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions compiler/ml/includecore.mli
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@ type type_mismatch =
| Field_mutable of Ident.t
| Field_optional of Ident.t
| Field_arity of Ident.t
| Field_names of int * string * string
| Field_renamed of string * string
| Field_runtime_name of Ident.t * string * string
| Field_missing of bool * Ident.t
| Field_order of string list
| Constructor_type of Ident.t
| Constructor_arity of Ident.t
| Constructor_names of int * string * string
| Constructor_renamed of string * string
| Constructor_missing of bool * Ident.t
| Constructor_order of string list
| Constructor_record of Ident.t * type_mismatch list
| Record_representation of record_representation * record_representation
| Unboxed_representation of bool
| Immediate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
Expected declaration (/.../fixtures/OptionalInlineImplIntf.res:2:3-23):
type t = A({x?: int})

The optional attribute of field x is different.
The records of constructor A differ:
The optional attribute of field x is different.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

We've found a bug for you!
/.../fixtures/inclusion_constructor_extra.res:5:5-7:1

3 │ module M: {
4 │ type t = Red | Green | Blue | Gray
5 │ } = {
6 │  type t = Black | Red | Green | Blue | Grey
7 │ }
8 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_constructor_extra.res:6:3-44):
type t = Black | Red | Green | Blue | Grey

Expected declaration (/.../fixtures/inclusion_constructor_extra.res:4:3-36):
type t = Red | Green | Blue | Gray

The constructor Grey is named Gray in the expected declaration.
The constructor Black is only present in the actual declaration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

We've found a bug for you!
/.../fixtures/inclusion_constructor_order.res:5:5-7:1

3 │ module M: {
4 │ type t = A(int) | B(string) | C
5 │ } = {
6 │  type t = B(int) | A(int) | C
7 │ }
8 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_constructor_order.res:6:3-30):
type t = B(int) | A(int) | C

Expected declaration (/.../fixtures/inclusion_constructor_order.res:4:3-33):
type t = A(int) | B(string) | C

The types for constructor B are not equal.
The constructors are in another order in the expected declaration:
A, B, C.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

We've found a bug for you!
/.../fixtures/inclusion_field_missing.res:5:5-7:1

3 │ module M: {
4 │ type t = {name: string, age: int, email: string}
5 │ } = {
6 │  type t = {name: string, email: string}
7 │ }
8 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_field_missing.res:6:3-40):
type t = {name: string, email: string}

Expected declaration (/.../fixtures/inclusion_field_missing.res:4:3-50):
type t = {name: string, age: int, email: string}

The field age is only present in the expected declaration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

We've found a bug for you!
/.../fixtures/inclusion_field_order.res:5:5-7:1

3 │ module M: {
4 │ type t = {a: int, b: int, c: int, d: int}
5 │ } = {
6 │  type t = {c: int, a: int, b: int, e: int}
7 │ }
8 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_field_order.res:6:3-43):
type t = {c: int, a: int, b: int, e: int}

Expected declaration (/.../fixtures/inclusion_field_order.res:4:3-43):
type t = {a: int, b: int, c: int, d: int}

The field d is only present in the expected declaration.
The field e is only present in the actual declaration.
The fields are in another order in the expected declaration:
a, b, c.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

We've found a bug for you!
/.../fixtures/inclusion_field_renamed.res:4:5-6:1

2 │ module M: {
3 │ type t = {name: string, email: string, age: int}
4 │ } = {
5 │  type t = {name: string, mail: string, age: int}
6 │ }
7 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_field_renamed.res:5:3-49):
type t = {name: string, mail: string, age: int}

Expected declaration (/.../fixtures/inclusion_field_renamed.res:3:3-50):
type t = {name: string, email: string, age: int}

The field mail is named email in the expected declaration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

We've found a bug for you!
/.../fixtures/inclusion_field_several.res:4:5-6:1

2 │ module M: {
3 │ type t = {id: int, mutable name: string, age: int, @as("e-mail") email
│ ?: string}
4 │ } = {
5 │  type t = {id: string, name: string, age: float, email: string}
6 │ }
7 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_field_several.res:5:3-64):
type t = {id: string, name: string, age: float, email: string}

Expected declaration (/.../fixtures/inclusion_field_several.res:3:3-82):
type t = {id: int, mutable name: string, age: int, @as("e-mail") email?: string}

The types for field id are not equal.
The mutability of field name is different.
The types for field age are not equal.
The optional attribute of field email is different.
The field email has the runtime name "email" in the actual declaration,
but "e-mail" in the expected declaration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

We've found a bug for you!
/.../fixtures/inclusion_inline_record.res:4:5-6:1

2 │ module M: {
3 │ type t = Person({name: string, age: int}) | Anonymous
4 │ } = {
5 │  type t = Person({age: int, name: string, nick: string}) | Anonymous
6 │ }
7 │

Signature mismatch:

Actual declaration (/.../fixtures/inclusion_inline_record.res:5:3-69):
type t = Person({age: int, name: string, nick: string}) | Anonymous

Expected declaration (/.../fixtures/inclusion_inline_record.res:3:3-55):
type t = Person({name: string, age: int}) | Anonymous

The records of constructor Person differ:
The field nick is only present in the actual declaration.
The fields are in another order in the expected declaration:
name, age.
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@
Expected declaration (/.../fixtures/variant_payload_tag_mismatch.res:3:3-36):
type t = A({x: int}) | C({x: int})

The internal representations for case A are not equal.
The internal representations for case A are not equal.
The internal representations for case C are not equal.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// An extra constructor at the front is reported as extra, and a constructor
// each declaration lacks at the same position as a renaming
module M: {
type t = Red | Green | Blue | Gray
} = {
type t = Black | Red | Green | Blue | Grey
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Constructors in another order are reported with the expected order, next to
// the differences of each constructor
module M: {
type t = A(int) | B(string) | C
} = {
type t = B(int) | A(int) | C
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// A field missing in the middle is reported as missing, not as a renaming of
// the fields after it
module M: {
type t = {name: string, age: int, email: string}
} = {
type t = {name: string, email: string}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Fields in another order are reported with the expected order, next to the
// fields that only one declaration has
module M: {
type t = {a: int, b: int, c: int, d: int}
} = {
type t = {c: int, a: int, b: int, e: int}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// A field that each declaration lacks after the same field is a renaming
module M: {
type t = {name: string, email: string, age: int}
} = {
type t = {name: string, mail: string, age: int}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Every field that differs is reported, not only the first one
module M: {
type t = {id: int, mutable name: string, age: int, @as("e-mail") email?: string}
} = {
type t = {id: string, name: string, age: float, email: string}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// The differences of an inline record are reported under its constructor
module M: {
type t = Person({name: string, age: int}) | Anonymous
} = {
type t = Person({age: int, name: string, nick: string}) | Anonymous
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
Expected declaration (/.../fixtures/Iface_field_names_mismatch/Foo.resi:1:1-25):
type t = {x: int, y: int}

Fields number 1 have different names, a and x.
The field a is named x in the expected declaration.
The field b is named y in the expected declaration.
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
Expected declaration (/.../fixtures/Iface_type_decl_record/Foo.resi:1:1-25):
type t = {x: int, y: int}

Fields number 2 have different names, z and y.
The field z is named y in the expected declaration.
Loading