Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code gen: improve pattern matching of optional fields. #7143

Merged
merged 2 commits into from
Nov 2, 2024
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
- Improve code generation or pattern matching of untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/7128
- Improve negation handling in combination with and/or to simplify generated code (especially coming out of pattern matching). https://github.com/rescript-lang/rescript-compiler/pull/7138
- optimize JavaScript code generation by using x == null checks and improving type-based optimizations for string/number literals. https://github.com/rescript-lang/rescript-compiler/pull/7141
- Improve pattern matching on optional fields. https://github.com/rescript-lang/rescript-compiler/pull/7143


#### :house: Internal
Expand Down
20 changes: 19 additions & 1 deletion compiler/ml/parmatch.ml
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,25 @@ let all_record_args lbls =
(fun lbl -> (mknoloc (Longident.Lident "?temp?"), lbl, omega))
lbl_all
in
List.iter (fun ((_, lbl, _) as x) -> t.(lbl.lbl_pos) <- x) lbls;
List.iter
(fun ((id, lbl, pat) as x) ->
let lbl_is_optional () =
match lbl.lbl_repres with
| Record_optional_labels labels -> List.mem lbl.lbl_name labels
| _ -> false
in
let x =
match pat.pat_desc with
| Tpat_construct
( {txt = Longident.Ldot (Longident.Lident "*predef*", "Some")},
_,
[({pat_desc = Tpat_constant _} as c)] )
when lbl_is_optional () ->
(id, lbl, c)
| _ -> x
in
t.(lbl.lbl_pos) <- x)
lbls;
Array.to_list t
| _ -> fatal_error "Parmatch.all_record_args"

Expand Down
29 changes: 9 additions & 20 deletions tests/tests/src/DictTests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,22 @@ let intDict = {
};

function inferDictByPattern(dict) {
let match = dict.one;
if (match === 1) {
let match$1 = dict.three;
if (match$1 === 3) {
let match$2 = dict.four;
if (match$2 === 4) {
dict["five"] = 5;
return;
}

}

if (dict.one === 1 && dict.three === 3 && dict.four === 4) {
dict["five"] = 5;
return;
}
let match$3 = dict.two;
if (match$3 === 1) {
console.log("two");
} else {
if (dict.two !== 1) {
console.log("not one");
} else {
console.log("two");
}
}

function constrainedAsDict(dict) {
let match = dict.one;
if (match === 1) {
console.log("one");
} else {
if (dict.one !== 1) {
console.log("not one");
} else {
console.log("one");
}
}

Expand Down
Loading