Skip to content

Pattern matching for @nullable records. #5453

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

Merged
merged 5 commits into from
Jun 22, 2022
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
13 changes: 11 additions & 2 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@

**Compiler**

- Added support for `@new @variadic` (see https://github.com/rescript-lang/rescript-compiler/pull/5364)
- Added support for `@optional` fields in records (see https://github.com/rescript-lang/rescript-compiler/pull/5423)
- Add support for `@new @variadic` (see https://github.com/rescript-lang/rescript-compiler/pull/5364)
- New records with `@optional` fields [#5423](https://github.com/rescript-lang/rescript-compiler/pull/5423) [#5452](https://github.com/rescript-lang/rescript-compiler/issues/5452)

**Syntax**

- Fix printing for inline nullary functor types [#477](https://github.com/rescript-lang/syntax/pull/477)
- Fix stripping of quotes for empty poly variants [#474](https://github.com/rescript-lang/syntax/pull/474)
- Implement syntax for arity zero vs arity one in uncurried application in [#139](https://github.com/rescript-lang/syntax/pull/139)
- Fix parsing of first class module exprs as part of binary/ternary expr in [#256](https://github.com/rescript-lang/syntax/pull/256)

**Libraries**

- Several Belt libraries are now converted to ReScript syntax, with corresponding comments in Markdown format suitable for hovering.

**Playground**

- Added `jsoo_playground_main.ml` as the rescript-lang.org playground bundle entrypoint
Expand Down
24 changes: 22 additions & 2 deletions jscomp/ml/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,26 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
Some (p0, p), expected_ty
with Not_found -> None, newvar ()
in
let label_is_optional ld =
match ld.lbl_repres with
| Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
| _ -> false in
let process_optional_label (ld, pat) =
let exp_optional_attr =
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
in
let isFromPamatch = match pat.ppat_desc with
| Ppat_construct ({txt = Lident s}, _) ->
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
| _ -> false
in
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
else pat
in
let type_label_pat (label_lid, label, sarg) k =
let sarg = process_optional_label (label, sarg) in
begin_def ();
let (vars, ty_arg, ty_res) = instance_label false label in
if vars = [] then end_def ();
Expand Down Expand Up @@ -1865,8 +1884,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
Ext_list.exists e.pexp_attributes (fun ({txt },_) -> txt = "optional")
in
if label_is_optional ld && not exp_optional_attr then
let pexp_desc = Pexp_construct ({id with txt = Longident.Lident "Some"}, Some e)
in (id, ld, {e with pexp_desc})
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
let e = Ast_helper.Exp.construct ~loc:e.pexp_loc lid (Some e)
in (id, ld, e)
else (id, ld, e)
in
match sexp.pexp_desc with
Expand Down
10 changes: 10 additions & 0 deletions jscomp/test/res_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ var newrecord = Caml_obj.obj_dup(v0);

newrecord.x = 3;

function testMatch(v) {
var y = v.y;
if (y !== undefined) {
return y;
} else {
return 42;
}
}

var v2 = newrecord;

var v1 = {
Expand All @@ -30,6 +39,7 @@ exports.f = f;
exports.v0 = v0;
exports.v2 = v2;
exports.v1 = v1;
exports.testMatch = testMatch;
exports.h = h;
exports.hey = hey;
/* Not a pure module */
6 changes: 6 additions & 0 deletions jscomp/test/res_debug.res
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ let v1 : r = { x : 3
, z : 3
}

let testMatch = v =>
switch v {
| {y} => y
| {y: @optional None} => 42
}

let h = '😊'
let hey = "hello, 世界"
// failed to type check
24 changes: 22 additions & 2 deletions lib/4.06.1/unstable/js_compiler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -40052,7 +40052,26 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
Some (p0, p), expected_ty
with Not_found -> None, newvar ()
in
let label_is_optional ld =
match ld.lbl_repres with
| Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
| _ -> false in
let process_optional_label (ld, pat) =
let exp_optional_attr =
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
in
let isFromPamatch = match pat.ppat_desc with
| Ppat_construct ({txt = Lident s}, _) ->
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
| _ -> false
in
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
else pat
in
let type_label_pat (label_lid, label, sarg) k =
let sarg = process_optional_label (label, sarg) in
begin_def ();
let (vars, ty_arg, ty_res) = instance_label false label in
if vars = [] then end_def ();
Expand Down Expand Up @@ -40768,8 +40787,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
Ext_list.exists e.pexp_attributes (fun ({txt },_) -> txt = "optional")
in
if label_is_optional ld && not exp_optional_attr then
let pexp_desc = Pexp_construct ({id with txt = Longident.Lident "Some"}, Some e)
in (id, ld, {e with pexp_desc})
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
let e = Ast_helper.Exp.construct ~loc:e.pexp_loc lid (Some e)
in (id, ld, e)
else (id, ld, e)
in
match sexp.pexp_desc with
Expand Down
24 changes: 22 additions & 2 deletions lib/4.06.1/unstable/js_playground_compiler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -40052,7 +40052,26 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
Some (p0, p), expected_ty
with Not_found -> None, newvar ()
in
let label_is_optional ld =
match ld.lbl_repres with
| Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
| _ -> false in
let process_optional_label (ld, pat) =
let exp_optional_attr =
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
in
let isFromPamatch = match pat.ppat_desc with
| Ppat_construct ({txt = Lident s}, _) ->
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
| _ -> false
in
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
else pat
in
let type_label_pat (label_lid, label, sarg) k =
let sarg = process_optional_label (label, sarg) in
begin_def ();
let (vars, ty_arg, ty_res) = instance_label false label in
if vars = [] then end_def ();
Expand Down Expand Up @@ -40768,8 +40787,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
Ext_list.exists e.pexp_attributes (fun ({txt },_) -> txt = "optional")
in
if label_is_optional ld && not exp_optional_attr then
let pexp_desc = Pexp_construct ({id with txt = Longident.Lident "Some"}, Some e)
in (id, ld, {e with pexp_desc})
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
let e = Ast_helper.Exp.construct ~loc:e.pexp_loc lid (Some e)
in (id, ld, e)
else (id, ld, e)
in
match sexp.pexp_desc with
Expand Down
24 changes: 22 additions & 2 deletions lib/4.06.1/whole_compiler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -214583,7 +214583,26 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
Some (p0, p), expected_ty
with Not_found -> None, newvar ()
in
let label_is_optional ld =
match ld.lbl_repres with
| Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
| _ -> false in
let process_optional_label (ld, pat) =
let exp_optional_attr =
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
in
let isFromPamatch = match pat.ppat_desc with
| Ppat_construct ({txt = Lident s}, _) ->
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
| _ -> false
in
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
else pat
in
let type_label_pat (label_lid, label, sarg) k =
let sarg = process_optional_label (label, sarg) in
begin_def ();
let (vars, ty_arg, ty_res) = instance_label false label in
if vars = [] then end_def ();
Expand Down Expand Up @@ -215299,8 +215318,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
Ext_list.exists e.pexp_attributes (fun ({txt },_) -> txt = "optional")
in
if label_is_optional ld && not exp_optional_attr then
let pexp_desc = Pexp_construct ({id with txt = Longident.Lident "Some"}, Some e)
in (id, ld, {e with pexp_desc})
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
let e = Ast_helper.Exp.construct ~loc:e.pexp_loc lid (Some e)
in (id, ld, e)
else (id, ld, e)
in
match sexp.pexp_desc with
Expand Down