Skip to content

Commit 91e6f7d

Browse files
committed
fix error variant cstr arg of optional field
1 parent c4d036e commit 91e6f7d

File tree

9 files changed

+796
-751
lines changed

9 files changed

+796
-751
lines changed

jscomp/ml/datarepr.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ let constructor_descrs ty_path decl cstrs =
113113
if cd_args = Cstr_tuple [] then incr num_consts else incr num_nonconsts;
114114
if cd_res = None then incr num_normal)
115115
cstrs;
116+
let has_optional attrs = Ext_list.exists attrs (fun ({txt },_) -> txt = "ns.optional") in
116117
let rec describe_constructors idx_const idx_nonconst = function
117118
[] -> []
118119
| {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem ->
@@ -131,11 +132,17 @@ let constructor_descrs ty_path decl cstrs =
131132
| _ -> (Cstr_block idx_nonconst,
132133
describe_constructors idx_const (idx_nonconst+1) rem) in
133134
let cstr_name = Ident.name cd_id in
135+
let optional_labels = match cd_args with
136+
| Cstr_tuple _ -> []
137+
| Cstr_record lbls ->
138+
Ext_list.filter_map lbls (fun ({ld_id;ld_attributes; _}) ->
139+
if has_optional ld_attributes then Some ld_id.name else None)
140+
in
134141
let existentials, cstr_args, cstr_inlined =
135142
let representation =
136143
if decl.type_unboxed.unboxed
137144
then Record_unboxed true
138-
else Record_inlined {tag = idx_nonconst; name = cstr_name; num_nonconsts = !num_nonconsts}
145+
else Record_inlined {tag = idx_nonconst; name = cstr_name; num_nonconsts = !num_nonconsts; optional_labels}
139146
in
140147
constructor_args decl.type_private cd_args cd_res
141148
(Path.Pdot (ty_path, cstr_name, Path.nopos)) representation

jscomp/ml/typecore.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,7 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
18791879
let label_is_optional ld =
18801880
match ld.lbl_repres with
18811881
| Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
1882+
| Record_inlined {optional_labels} -> Ext_list.mem_string optional_labels ld.lbl_name
18821883
| _ -> false in
18831884
let process_optional_label (id, ld, e) =
18841885
let exp_optional_attr =

jscomp/ml/types.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ and record_representation =
154154
| Record_float_unused (* Was: all fields are floats. Now: unused *)
155155
| Record_unboxed of bool (* Unboxed single-field record, inlined or not *)
156156
| Record_inlined of (* Inlined record *)
157-
{ tag : int ; name : string; num_nonconsts : int}
157+
{ tag : int ; name : string; num_nonconsts : int; optional_labels : string list}
158158
| Record_extension (* Inlined record under extension *)
159159
| Record_optional_labels of string list (* List of optional labels *)
160160

@@ -348,10 +348,10 @@ let same_record_representation x y =
348348
match y with
349349
| Record_optional_labels lbls2 -> lbls = lbls2
350350
| _ -> false)
351-
| Record_inlined {tag; name; num_nonconsts} -> (
351+
| Record_inlined {tag; name; num_nonconsts; optional_labels} -> (
352352
match y with
353353
| Record_inlined y ->
354-
tag = y.tag && name = y.name && num_nonconsts = y.num_nonconsts
354+
tag = y.tag && name = y.name && num_nonconsts = y.num_nonconsts && optional_labels = y.optional_labels
355355
| _ -> false)
356356
| Record_extension -> y = Record_extension
357357
| Record_unboxed x -> ( match y with Record_unboxed y -> x = y | _ -> false)

jscomp/ml/types.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ and record_representation =
301301
| Record_float_unused (* Was: all fields are floats. Now: unused *)
302302
| Record_unboxed of bool (* Unboxed single-field record, inlined or not *)
303303
| Record_inlined of (* Inlined record *)
304-
{ tag : int ; name : string; num_nonconsts : int}
304+
{ tag : int ; name : string; num_nonconsts : int; optional_labels : string list}
305305
| Record_extension (* Inlined record under extension *)
306306
| Record_optional_labels of string list (* List of optional labels *)
307307

jscomp/test/record_regression.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ var h = newrecord$2;
8080

8181
var h10 = newrecord$3;
8282

83+
var foo = /* Foo */{
84+
name: "foo",
85+
age: undefined
86+
};
87+
8388
exports.f1 = f1;
8489
exports.f2 = f2;
8590
exports.f3 = f3;
@@ -93,4 +98,5 @@ exports.h10 = h10;
9398
exports.h11 = h11;
9499
exports.po = po;
95100
exports.setAA = setAA;
101+
exports.foo = foo;
96102
/* Not a pure module */

lib/4.06.1/unstable/all_ounit_tests.ml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41403,7 +41403,7 @@ and record_representation =
4140341403
| Record_float_unused (* Was: all fields are floats. Now: unused *)
4140441404
| Record_unboxed of bool (* Unboxed single-field record, inlined or not *)
4140541405
| Record_inlined of (* Inlined record *)
41406-
{ tag : int ; name : string; num_nonconsts : int}
41406+
{ tag : int ; name : string; num_nonconsts : int; optional_labels : string list}
4140741407
| Record_extension (* Inlined record under extension *)
4140841408
| Record_optional_labels of string list (* List of optional labels *)
4140941409

@@ -41748,7 +41748,7 @@ and record_representation =
4174841748
| Record_float_unused (* Was: all fields are floats. Now: unused *)
4174941749
| Record_unboxed of bool (* Unboxed single-field record, inlined or not *)
4175041750
| Record_inlined of (* Inlined record *)
41751-
{ tag : int ; name : string; num_nonconsts : int}
41751+
{ tag : int ; name : string; num_nonconsts : int; optional_labels : string list}
4175241752
| Record_extension (* Inlined record under extension *)
4175341753
| Record_optional_labels of string list (* List of optional labels *)
4175441754

@@ -41942,10 +41942,10 @@ let same_record_representation x y =
4194241942
match y with
4194341943
| Record_optional_labels lbls2 -> lbls = lbls2
4194441944
| _ -> false)
41945-
| Record_inlined {tag; name; num_nonconsts} -> (
41945+
| Record_inlined {tag; name; num_nonconsts; optional_labels} -> (
4194641946
match y with
4194741947
| Record_inlined y ->
41948-
tag = y.tag && name = y.name && num_nonconsts = y.num_nonconsts
41948+
tag = y.tag && name = y.name && num_nonconsts = y.num_nonconsts && optional_labels = y.optional_labels
4194941949
| _ -> false)
4195041950
| Record_extension -> y = Record_extension
4195141951
| Record_unboxed x -> ( match y with Record_unboxed y -> x = y | _ -> false)
@@ -43434,6 +43434,7 @@ let constructor_descrs ty_path decl cstrs =
4343443434
if cd_args = Cstr_tuple [] then incr num_consts else incr num_nonconsts;
4343543435
if cd_res = None then incr num_normal)
4343643436
cstrs;
43437+
let has_optional attrs = Ext_list.exists attrs (fun ({txt },_) -> txt = "ns.optional") in
4343743438
let rec describe_constructors idx_const idx_nonconst = function
4343843439
[] -> []
4343943440
| {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem ->
@@ -43452,11 +43453,17 @@ let constructor_descrs ty_path decl cstrs =
4345243453
| _ -> (Cstr_block idx_nonconst,
4345343454
describe_constructors idx_const (idx_nonconst+1) rem) in
4345443455
let cstr_name = Ident.name cd_id in
43456+
let optional_labels = match cd_args with
43457+
| Cstr_tuple _ -> []
43458+
| Cstr_record lbls ->
43459+
Ext_list.filter_map lbls (fun ({ld_id;ld_attributes; _}) ->
43460+
if has_optional ld_attributes then Some ld_id.name else None)
43461+
in
4345543462
let existentials, cstr_args, cstr_inlined =
4345643463
let representation =
4345743464
if decl.type_unboxed.unboxed
4345843465
then Record_unboxed true
43459-
else Record_inlined {tag = idx_nonconst; name = cstr_name; num_nonconsts = !num_nonconsts}
43466+
else Record_inlined {tag = idx_nonconst; name = cstr_name; num_nonconsts = !num_nonconsts; optional_labels}
4346043467
in
4346143468
constructor_args decl.type_private cd_args cd_res
4346243469
(Path.Pdot (ty_path, cstr_name, Path.nopos)) representation

0 commit comments

Comments
 (0)