diff --git a/Changes.md b/Changes.md index d054daf0fd..aabe93b73c 100644 --- a/Changes.md +++ b/Changes.md @@ -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 diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index 72280eae0d..8815be4a88 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -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 (); @@ -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 diff --git a/jscomp/test/res_debug.js b/jscomp/test/res_debug.js index b116b6f307..e69bda1ade 100644 --- a/jscomp/test/res_debug.js +++ b/jscomp/test/res_debug.js @@ -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 = { @@ -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 */ diff --git a/jscomp/test/res_debug.res b/jscomp/test/res_debug.res index bc7e788ada..31d08a546d 100644 --- a/jscomp/test/res_debug.res +++ b/jscomp/test/res_debug.res @@ -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 diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 3b02b47df6..872c8e329c 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -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 (); @@ -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 diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index f83b4a3128..ff7b5c757a 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -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 (); @@ -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 diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 38dbf66325..fe84ca7730 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -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 (); @@ -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