Skip to content

Commit 25fffaa

Browse files
committed
Work around issue with fresh names from pattern matching.
A pattern is type checked twice. The second time for the exhaustive check coming from the pattern matcher. The second time constructors, such as optionals, have been replaced by fresh symbols starting with `#$`. Now recognize these symbols and do not apply the transformation which adds Some.
1 parent be42e77 commit 25fffaa

File tree

6 files changed

+38
-6
lines changed

6 files changed

+38
-6
lines changed

jscomp/ml/typecore.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,12 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
11571157
let exp_optional_attr =
11581158
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
11591159
in
1160-
if label_is_optional ld && not exp_optional_attr then
1160+
let isFromPamatch = match pat.ppat_desc with
1161+
| Ppat_construct ({txt = Lident s}, _) ->
1162+
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
1163+
| _ -> false
1164+
in
1165+
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
11611166
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
11621167
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
11631168
else pat

jscomp/test/res_debug.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,19 @@ var newrecord = Caml_obj.obj_dup(v0);
1616
newrecord.x = 3;
1717

1818
function testMatch(v) {
19-
return v.y;
19+
var y = v.y;
20+
if (y !== undefined) {
21+
return y;
22+
}
23+
throw {
24+
RE_EXN_ID: "Match_failure",
25+
_1: [
26+
"res_debug.res",
27+
50,
28+
2
29+
],
30+
Error: new Error()
31+
};
2032
}
2133

2234
var v2 = newrecord;

jscomp/test/res_debug.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ let v1 : r = { x : 3
4444
, z : 3
4545
}
4646

47-
//@@warning("-56") // Turn off match case unreachable
47+
@@warning("-8") // Turn off incomplete pattern match
4848

4949
let testMatch = v =>
5050
switch v {

lib/4.06.1/unstable/js_compiler.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40060,7 +40060,12 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
4006040060
let exp_optional_attr =
4006140061
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
4006240062
in
40063-
if label_is_optional ld && not exp_optional_attr then
40063+
let isFromPamatch = match pat.ppat_desc with
40064+
| Ppat_construct ({txt = Lident s}, _) ->
40065+
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
40066+
| _ -> false
40067+
in
40068+
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
4006440069
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
4006540070
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
4006640071
else pat

lib/4.06.1/unstable/js_playground_compiler.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40060,7 +40060,12 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
4006040060
let exp_optional_attr =
4006140061
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
4006240062
in
40063-
if label_is_optional ld && not exp_optional_attr then
40063+
let isFromPamatch = match pat.ppat_desc with
40064+
| Ppat_construct ({txt = Lident s}, _) ->
40065+
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
40066+
| _ -> false
40067+
in
40068+
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
4006440069
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
4006540070
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
4006640071
else pat

lib/4.06.1/whole_compiler.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214591,7 +214591,12 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
214591214591
let exp_optional_attr =
214592214592
Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "optional")
214593214593
in
214594-
if label_is_optional ld && not exp_optional_attr then
214594+
let isFromPamatch = match pat.ppat_desc with
214595+
| Ppat_construct ({txt = Lident s}, _) ->
214596+
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
214597+
| _ -> false
214598+
in
214599+
if label_is_optional ld && not exp_optional_attr && not isFromPamatch then
214595214600
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
214596214601
Ast_helper.Pat.construct ~loc:pat.ppat_loc lid (Some pat)
214597214602
else pat

0 commit comments

Comments
 (0)