Skip to content

Commit 0a75e31

Browse files
Fix exception record field regression (#8319)
* Fix exception record field regression * Format
1 parent 55a50a9 commit 0a75e31

3 files changed

Lines changed: 64 additions & 29 deletions

File tree

compiler/ml/typedecl.ml

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,24 @@ let transl_constructor_arguments env closed = function
312312
let cty = transl_simple_type env closed obj_ty in
313313
(Types.Cstr_tuple [cty.ctyp_type], Cstr_tuple [cty])))))
314314

315+
let rewrite_optional_inline_record_fields = function
316+
| Pcstr_tuple _ as args -> args
317+
| Pcstr_record lds ->
318+
Pcstr_record
319+
(Ext_list.map lds (fun ld ->
320+
if ld.pld_optional then
321+
let typ = ld.pld_type in
322+
let typ =
323+
{
324+
typ with
325+
ptyp_desc =
326+
Ptyp_constr
327+
({txt = Lident "option"; loc = typ.ptyp_loc}, [typ]);
328+
}
329+
in
330+
{ld with pld_type = typ}
331+
else ld))
332+
315333
let make_constructor env type_path type_params sargs sret_type =
316334
match sret_type with
317335
| None ->
@@ -440,28 +458,10 @@ let transl_declaration ~type_record_as_object ~untagged_wfc env sdecl id =
440458
Location.prerr_warning loc Warnings.Constraint_on_gadt);
441459
let scstrs =
442460
Ext_list.map scstrs (fun ({pcd_args} as cstr) ->
443-
match pcd_args with
444-
| Pcstr_tuple _ -> cstr
445-
| Pcstr_record lds ->
446-
{
447-
cstr with
448-
pcd_args =
449-
Pcstr_record
450-
(Ext_list.map lds (fun ld ->
451-
if ld.pld_optional then
452-
let typ = ld.pld_type in
453-
let typ =
454-
{
455-
typ with
456-
ptyp_desc =
457-
Ptyp_constr
458-
( {txt = Lident "option"; loc = typ.ptyp_loc},
459-
[typ] );
460-
}
461-
in
462-
{ld with pld_type = typ}
463-
else ld));
464-
})
461+
{
462+
cstr with
463+
pcd_args = rewrite_optional_inline_record_fields pcd_args;
464+
})
465465
in
466466
let all_constrs = ref StringSet.empty in
467467
List.iter
@@ -1627,6 +1627,7 @@ let transl_extension_constructor env type_path type_params typext_params priv
16271627
let args, ret_type, kind =
16281628
match sext.pext_kind with
16291629
| Pext_decl (sargs, sret_type) ->
1630+
let sargs = rewrite_optional_inline_record_fields sargs in
16301631
let targs, tret_type, args, ret_type, _ =
16311632
make_constructor env type_path typext_params sargs sret_type
16321633
in

tests/tests/src/record_extension_test.mjs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,48 +77,76 @@ let B = /* @__PURE__ */Primitive_exceptions.create("Record_extension_test.B");
7777

7878
let C = /* @__PURE__ */Primitive_exceptions.create("Record_extension_test.C");
7979

80+
let D = /* @__PURE__ */Primitive_exceptions.create("Record_extension_test.D");
81+
8082
function u(f) {
8183
try {
8284
return f();
8385
} catch (raw_x) {
8486
let x = Primitive_exceptions.internalToException(raw_x);
8587
if (x.RE_EXN_ID === A) {
8688
return x.name + x.x | 0;
87-
} else if (x.RE_EXN_ID === B) {
89+
}
90+
if (x.RE_EXN_ID === B) {
8891
return x._1 + x._2 | 0;
89-
} else if (x.RE_EXN_ID === C) {
92+
}
93+
if (x.RE_EXN_ID === C) {
9094
return x.name;
91-
} else {
95+
}
96+
if (x.RE_EXN_ID !== D) {
9297
return -1;
9398
}
99+
let message = x.message;
100+
let code = x.code;
101+
if (message !== undefined) {
102+
return code + message.length | 0;
103+
} else {
104+
return code;
105+
}
94106
}
95107
}
96108

97-
Mocha.describe("File \"record_extension_test.res\", line 68, characters 9-16", () => {
109+
Mocha.describe("File \"record_extension_test.res\", line 71, characters 9-16", () => {
98110
Mocha.test("record extension with exceptions", () => {
99-
Test_utils.eq("File \"record_extension_test.res\", line 70, characters 7-14", u(() => {
111+
Test_utils.eq("File \"record_extension_test.res\", line 73, characters 7-14", u(() => {
100112
throw {
101113
RE_EXN_ID: A,
102114
name: 1,
103115
x: 1,
104116
Error: new Error()
105117
};
106118
}), 2);
107-
Test_utils.eq("File \"record_extension_test.res\", line 71, characters 7-14", u(() => {
119+
Test_utils.eq("File \"record_extension_test.res\", line 74, characters 7-14", u(() => {
108120
throw {
109121
RE_EXN_ID: B,
110122
_1: 1,
111123
_2: 2,
112124
Error: new Error()
113125
};
114126
}), 3);
115-
Test_utils.eq("File \"record_extension_test.res\", line 72, characters 7-14", u(() => {
127+
Test_utils.eq("File \"record_extension_test.res\", line 75, characters 7-14", u(() => {
116128
throw {
117129
RE_EXN_ID: C,
118130
name: 4,
119131
Error: new Error()
120132
};
121133
}), 4);
134+
Test_utils.eq("File \"record_extension_test.res\", line 76, characters 7-14", u(() => {
135+
throw {
136+
RE_EXN_ID: D,
137+
code: 1,
138+
message: "A",
139+
Error: new Error()
140+
};
141+
}), 2);
142+
Test_utils.eq("File \"record_extension_test.res\", line 77, characters 7-14", u(() => {
143+
throw {
144+
RE_EXN_ID: D,
145+
code: 3,
146+
message: undefined,
147+
Error: new Error()
148+
};
149+
}), 3);
122150
});
123151
});
124152

@@ -132,6 +160,7 @@ export {
132160
A,
133161
B,
134162
C,
163+
D,
135164
u,
136165
}
137166
/* Not a pure module */

tests/tests/src/record_extension_test.res

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,15 @@ let f2_with = x =>
5656
exception A({name: int, x: int})
5757
exception B(int, int)
5858
exception C({name: int})
59+
exception D({code: int, message?: string})
5960

6061
let u = f =>
6162
try f() catch {
6263
| A({name, x}) => name + x
6364
| B(a, b) => a + b
6465
| C(x) => x.name
66+
| D({code, message}) => code + String.length(message)
67+
| D({code}) => code
6568
| _ => -1
6669
}
6770

@@ -70,5 +73,7 @@ describe(__LOC__, () => {
7073
eq(__LOC__, u(() => throw(A({name: 1, x: 1}))), 2)
7174
eq(__LOC__, u(() => throw(B(1, 2))), 3)
7275
eq(__LOC__, u(() => throw(C({name: 4}))), 4)
76+
eq(__LOC__, u(() => throw(D({code: 1, message: "A"}))), 2)
77+
eq(__LOC__, u(() => throw(D({code: 3}))), 3)
7378
})
7479
})

0 commit comments

Comments
 (0)