Skip to content

Commit f04fb33

Browse files
committed
Code gen: improve pattern matching of optional fields.
Pattern matching of optional fields such as ```res | {x: 1, y: "hello"} ``` can be specialised as the constants already imply the values cannot be absent.
1 parent 43d2bbf commit f04fb33

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

compiler/ml/parmatch.ml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,25 @@ let all_record_args lbls =
524524
(fun lbl -> (mknoloc (Longident.Lident "?temp?"), lbl, omega))
525525
lbl_all
526526
in
527-
List.iter (fun ((_, lbl, _) as x) -> t.(lbl.lbl_pos) <- x) lbls;
527+
List.iter
528+
(fun ((id, lbl, pat) as x) ->
529+
let lbl_is_optional () =
530+
match lbl.lbl_repres with
531+
| Record_optional_labels labels -> List.mem lbl.lbl_name labels
532+
| _ -> false
533+
in
534+
let x =
535+
match pat.pat_desc with
536+
| Tpat_construct
537+
( {txt = Longident.Ldot (Longident.Lident "*predef*", "Some")},
538+
_,
539+
[({pat_desc = Tpat_constant _} as c)] )
540+
when lbl_is_optional () ->
541+
(id, lbl, c)
542+
| _ -> x
543+
in
544+
t.(lbl.lbl_pos) <- x)
545+
lbls;
528546
Array.to_list t
529547
| _ -> fatal_error "Parmatch.all_record_args"
530548

tests/tests/src/DictTests.mjs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,22 @@ let intDict = {
1717
};
1818

1919
function inferDictByPattern(dict) {
20-
let match = dict.one;
21-
if (match === 1) {
22-
let match$1 = dict.three;
23-
if (match$1 === 3) {
24-
let match$2 = dict.four;
25-
if (match$2 === 4) {
26-
dict["five"] = 5;
27-
return;
28-
}
29-
30-
}
31-
20+
if (dict.one === 1 && dict.three === 3 && dict.four === 4) {
21+
dict["five"] = 5;
22+
return;
3223
}
33-
let match$3 = dict.two;
34-
if (match$3 === 1) {
35-
console.log("two");
36-
} else {
24+
if (dict.two !== 1) {
3725
console.log("not one");
26+
} else {
27+
console.log("two");
3828
}
3929
}
4030

4131
function constrainedAsDict(dict) {
42-
let match = dict.one;
43-
if (match === 1) {
44-
console.log("one");
45-
} else {
32+
if (dict.one !== 1) {
4633
console.log("not one");
34+
} else {
35+
console.log("one");
4736
}
4837
}
4938

0 commit comments

Comments
 (0)