Skip to content

Commit 1ae640b

Browse files
committed
add fixture tests for error/warning messages
1 parent cb0ab83 commit 1ae640b

15 files changed

+103
-9
lines changed

compiler/ml/typecore.ml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,15 +1608,6 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env sp
16081608
(fun (l : Types.label_declaration) -> Ident.name l.ld_id)
16091609
rest_labels
16101610
in
1611-
(* Warn if all rest fields are already explicit — the rest record will be empty *)
1612-
if
1613-
rest_field_names <> []
1614-
&& List.for_all
1615-
(fun f -> List.mem f explicit_fields)
1616-
rest_field_names
1617-
then
1618-
Location.prerr_warning rest_pat.ppat_loc
1619-
Warnings.Bs_record_rest_empty;
16201611
(* Validate: fields in both explicit and rest must be optional in the explicit pattern *)
16211612
let not_optional =
16221613
List.filter
@@ -1674,6 +1665,15 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env sp
16741665
(Ident.name rest_label.ld_id, rest_type_lid.txt) )))
16751666
rest_labels
16761667
| [] -> ());
1668+
(* Warn if all rest fields are already explicit — the rest record will be empty *)
1669+
if
1670+
rest_field_names <> []
1671+
&& List.for_all
1672+
(fun f -> List.mem f explicit_fields)
1673+
rest_field_names
1674+
then
1675+
Location.prerr_warning rest_pat.ppat_loc
1676+
Warnings.Bs_record_rest_empty;
16771677
let rest_type_args =
16781678
match rest_type_args_syntax with
16791679
| [] -> List.map (fun _ -> newvar ()) rest_decl.type_params
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
Warning number 111
3+
/.../fixtures/record_rest_empty_warning.res:3:16-26
4+
5+
1 │ type source = {a: int, b?: string}
6+
2 │ type sub = {b?: string}
7+
3 │ let {a, ?b, ...sub as rest} = ({a: 1}: source)
8+
4 │
9+
10+
All fields of the rest type are already present in the explicit pattern. The rest record will always be empty.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/record_rest_extra_field.res:3:12-14
4+
5+
1 │ type source = {a: int, x: int}
6+
2 │ type sub = {a: int, b: string}
7+
3 │ let {x, ...sub as rest} = ({a: 1, x: 2}: source)
8+
4 │
9+
10+
Field `b` in the rest type `sub` does not exist in the source record type.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/record_rest_field_missing.res:3:12-22
4+
5+
1 │ type source = {a: int, b: string, c: bool, d: float}
6+
2 │ type sub = {b: string}
7+
3 │ let {a, ...sub as rest} = ({a: 1, b: "x", c: true, d: 1.0}: source)
8+
4 │
9+
10+
The following fields are not part of the rest type `sub`:
11+
- c
12+
- d
13+
14+
List these fields in the record pattern before the spread so they're not present in the rest record.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/record_rest_field_not_optional.res:3:12-22
4+
5+
1 │ type source = {a?: int, b?: string, c: bool}
6+
2 │ type sub = {a?: int, b?: string}
7+
3 │ let {a, ...sub as rest}: source = {c: true}
8+
4 │
9+
10+
The following field appears in both the explicit pattern and the rest type `sub`:
11+
- a
12+
13+
Mark it as optional (`?a`) in the explicit pattern.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/record_rest_invalid_type.res:2:12-21
4+
5+
1 │ type source = {a: int, b: string}
6+
2 │ let {a, ...'a as rest} = ({a: 1, b: "x"}: source)
7+
3 │
8+
9+
Record rest pattern must have the form: ...Type.t as name
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/record_rest_not_record.res:3:12-20
4+
5+
1 │ type source = {a: int, b: string}
6+
2 │ type notRecord = One | Two
7+
3 │ let {a, ...notRecord as rest} = ({a: 1, b: "x"}: source)
8+
4 │
9+
10+
Type notRecord is not a record type and cannot be used as a record rest pattern.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/record_rest_requires_type_annotation.res:2:12-18
4+
5+
1 │ type source = {a: int, b: string}
6+
2 │ let {a, ...theRest} = ({a: 1, b: "x"}: source)
7+
3 │
8+
9+
Record rest pattern `...theRest` requires a type annotation. Use `...Type.t as theRest`.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type source = {a: int, b?: string}
2+
type sub = {b?: string}
3+
let {a, ?b, ...sub as rest} = ({a: 1}: source)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type source = {a: int, x: int}
2+
type sub = {a: int, b: string}
3+
let {x, ...sub as rest} = ({a: 1, x: 2}: source)

0 commit comments

Comments
 (0)