File tree 17 files changed +1210
-835
lines changed
17 files changed +1210
-835
lines changed Original file line number Diff line number Diff line change @@ -48,6 +48,12 @@ These are only breaking changes for unformatted code.
48
48
- Syntax: process uncurried function declarations explicitly in the parser/printer https://github.com/rescript-lang/rescript-compiler/pull/5794
49
49
- PPX V4: allow uncurried ` make ` function and treat it like a curried one [ #5802 ] ( https://github.com/rescript-lang/rescript-compiler/pull/5802 ) [ #5808 ] ( https://github.com/rescript-lang/rescript-compiler/pull/5808 ) [ #5812 ] ( https://github.com/rescript-lang/rescript-compiler/pull/5812 )
50
50
51
+ # 10.1.0-rc.6
52
+
53
+ #### :bug : Bug Fix
54
+
55
+ - Fix issue where optional fields in inline records were not supported and would cause type errors https://github.com/rescript-lang/rescript-compiler/pull/5827
56
+
51
57
# 10.1.0-rc.5
52
58
53
59
#### :bug : Bug Fix
Original file line number Diff line number Diff line change @@ -757,6 +757,20 @@ and expression_desc cxt ~(level : int) f x : cxt =
757
757
(if ! Js_config. debug then [ (name_symbol, E. str p.name) ] else [] )
758
758
(fun i -> Js_op. Lit i)
759
759
in
760
+ let is_optional (pname : Js_op.property_name ) =
761
+ match pname with
762
+ | Lit n -> Ext_list. mem_string p.optional_labels n
763
+ | Symbol_name -> false
764
+ in
765
+ let tails =
766
+ match p.optional_labels with
767
+ | [] -> tails
768
+ | _ ->
769
+ Ext_list. filter_map tails (fun (f , x ) ->
770
+ match x.expression_desc with
771
+ | Undefined when is_optional f -> None
772
+ | _ -> Some (f, x))
773
+ in
760
774
if p.num_nonconst = 1 then tails
761
775
else
762
776
( Js_op. Lit L. tag,
Load Diff Large diffs are not rendered by default.
Original file line number Diff line number Diff line change @@ -113,6 +113,7 @@ let constructor_descrs ty_path decl cstrs =
113
113
if cd_args = Cstr_tuple [] then incr num_consts else incr num_nonconsts;
114
114
if cd_res = None then incr num_normal)
115
115
cstrs;
116
+ let has_optional attrs = Ext_list. exists attrs (fun ({txt } ,_ ) -> txt = " ns.optional" ) in
116
117
let rec describe_constructors idx_const idx_nonconst = function
117
118
[] -> []
118
119
| {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem ->
@@ -131,11 +132,17 @@ let constructor_descrs ty_path decl cstrs =
131
132
| _ -> (Cstr_block idx_nonconst,
132
133
describe_constructors idx_const (idx_nonconst+ 1 ) rem) in
133
134
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
134
141
let existentials, cstr_args, cstr_inlined =
135
142
let representation =
136
143
if decl.type_unboxed.unboxed
137
144
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 }
139
146
in
140
147
constructor_args decl.type_private cd_args cd_res
141
148
(Path. Pdot (ty_path, cstr_name, Path. nopos)) representation
Original file line number Diff line number Diff line change @@ -40,7 +40,7 @@ type record_repr =
40
40
41
41
type tag_info =
42
42
| Blk_constructor of {name : string ; num_nonconst : int ; tag : int }
43
- | Blk_record_inlined of { name : string ; num_nonconst : int ; tag : int ; fields : string array ; mutable_flag : Asttypes .mutable_flag }
43
+ | Blk_record_inlined of { name : string ; num_nonconst : int ; tag : int ; optional_labels : string list ; fields : string array ; mutable_flag : Asttypes .mutable_flag }
44
44
| Blk_tuple
45
45
| Blk_poly_var of string
46
46
| Blk_record of {fields : string array ; mutable_flag : Asttypes .mutable_flag ; record_repr : record_repr }
@@ -96,9 +96,9 @@ let blk_record_ext = ref (fun fields mutable_flag ->
96
96
Blk_record_ext {fields = all_labels_info; mutable_flag }
97
97
)
98
98
99
- let blk_record_inlined = ref (fun fields name num_nonconst ~tag mutable_flag ->
99
+ let blk_record_inlined = ref (fun fields name num_nonconst optional_labels ~tag mutable_flag ->
100
100
let fields = fields |> Array. map (fun (x ,_ ) -> x.Types. lbl_name) in
101
- Blk_record_inlined {fields; name; num_nonconst; tag; mutable_flag}
101
+ Blk_record_inlined {fields; name; num_nonconst; tag; mutable_flag; optional_labels }
102
102
)
103
103
104
104
let ref_tag_info : tag_info =
Original file line number Diff line number Diff line change @@ -40,7 +40,7 @@ type record_repr =
40
40
41
41
type tag_info =
42
42
| Blk_constructor of {name : string ; num_nonconst : int ; tag : int }
43
- | Blk_record_inlined of { name : string ; num_nonconst : int ; tag : int ; fields : string array ; mutable_flag : mutable_flag }
43
+ | Blk_record_inlined of { name : string ; num_nonconst : int ; tag : int ; optional_labels : string list ; fields : string array ; mutable_flag : mutable_flag }
44
44
| Blk_tuple
45
45
| Blk_poly_var of string
46
46
| Blk_record of {fields : string array ; mutable_flag : mutable_flag ; record_repr : record_repr }
@@ -85,6 +85,7 @@ val blk_record_inlined :
85
85
(Types .label_description * Typedtree .record_label_definition ) array ->
86
86
string ->
87
87
int ->
88
+ string list ->
88
89
tag :int ->
89
90
mutable_flag ->
90
91
tag_info
Original file line number Diff line number Diff line change @@ -1138,10 +1138,10 @@ and transl_record loc env fields repres opt_init_expr =
1138
1138
| Record_optional_labels _ ->
1139
1139
Lconst
1140
1140
(Const_block (! Lambda. blk_record fields mut Record_optional , cl))
1141
- | Record_inlined { tag; name; num_nonconsts } ->
1141
+ | Record_inlined { tag; name; num_nonconsts; optional_labels } ->
1142
1142
Lconst
1143
1143
(Const_block
1144
- ( ! Lambda. blk_record_inlined fields name num_nonconsts ~tag
1144
+ ( ! Lambda. blk_record_inlined fields name num_nonconsts optional_labels ~tag
1145
1145
mut,
1146
1146
cl ))
1147
1147
| Record_unboxed _ ->
@@ -1160,10 +1160,10 @@ and transl_record loc env fields repres opt_init_expr =
1160
1160
ll,
1161
1161
loc )
1162
1162
| Record_float_unused -> assert false
1163
- | Record_inlined { tag; name; num_nonconsts } ->
1163
+ | Record_inlined { tag; name; num_nonconsts; optional_labels } ->
1164
1164
Lprim
1165
1165
( Pmakeblock
1166
- (! Lambda. blk_record_inlined fields name num_nonconsts ~tag
1166
+ (! Lambda. blk_record_inlined fields name num_nonconsts optional_labels ~tag
1167
1167
mut),
1168
1168
ll,
1169
1169
loc )
Original file line number Diff line number Diff line change @@ -1153,6 +1153,7 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
1153
1153
let label_is_optional ld =
1154
1154
match ld.lbl_repres with
1155
1155
| Record_optional_labels lbls -> Ext_list. mem_string lbls ld.lbl_name
1156
+ | Record_inlined {optional_labels} -> Ext_list. mem_string optional_labels ld.lbl_name
1156
1157
| _ -> false in
1157
1158
let process_optional_label (ld , pat ) =
1158
1159
let exp_optional_attr =
@@ -1879,6 +1880,7 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
1879
1880
let label_is_optional ld =
1880
1881
match ld.lbl_repres with
1881
1882
| Record_optional_labels lbls -> Ext_list. mem_string lbls ld.lbl_name
1883
+ | Record_inlined {optional_labels} -> Ext_list. mem_string optional_labels ld.lbl_name
1882
1884
| _ -> false in
1883
1885
let process_optional_label (id , ld , e ) =
1884
1886
let exp_optional_attr =
Original file line number Diff line number Diff line change @@ -358,6 +358,20 @@ let transl_declaration env sdecl id =
358
358
| (_ ,_ ,loc )::_ ->
359
359
Location. prerr_warning loc Warnings. Constraint_on_gadt
360
360
end ;
361
+ let has_optional attrs = Ext_list. exists attrs (fun ({txt } ,_ ) -> txt = " ns.optional" ) in
362
+ let scstrs =
363
+ Ext_list. map scstrs (fun ({pcd_args} as cstr ) ->
364
+ match pcd_args with
365
+ | Pcstr_tuple _ -> cstr
366
+ | Pcstr_record lds ->
367
+ {cstr with pcd_args = Pcstr_record (Ext_list. map lds (fun ld ->
368
+ if has_optional ld.pld_attributes then
369
+ let typ = ld.pld_type in
370
+ let typ = {typ with ptyp_desc = Ptyp_constr ({txt = Lident " option" ; loc= typ.ptyp_loc}, [typ])} in
371
+ {ld with pld_type = typ}
372
+ else ld
373
+ ))}
374
+ ) in
361
375
let all_constrs = ref StringSet. empty in
362
376
List. iter
363
377
(fun {pcd_name = {txt = name } } ->
Original file line number Diff line number Diff line change @@ -154,7 +154,7 @@ and record_representation =
154
154
| Record_float_unused (* Was: all fields are floats. Now: unused *)
155
155
| Record_unboxed of bool (* Unboxed single-field record, inlined or not *)
156
156
| 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 }
158
158
| Record_extension (* Inlined record under extension *)
159
159
| Record_optional_labels of string list (* List of optional labels *)
160
160
@@ -348,10 +348,10 @@ let same_record_representation x y =
348
348
match y with
349
349
| Record_optional_labels lbls2 -> lbls = lbls2
350
350
| _ -> false )
351
- | Record_inlined {tag; name; num_nonconsts} -> (
351
+ | Record_inlined {tag; name; num_nonconsts; optional_labels } -> (
352
352
match y with
353
353
| 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
355
355
| _ -> false )
356
356
| Record_extension -> y = Record_extension
357
357
| Record_unboxed x -> ( match y with Record_unboxed y -> x = y | _ -> false )
Original file line number Diff line number Diff line change @@ -301,7 +301,7 @@ and record_representation =
301
301
| Record_float_unused (* Was: all fields are floats. Now: unused *)
302
302
| Record_unboxed of bool (* Unboxed single-field record, inlined or not *)
303
303
| 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 }
305
305
| Record_extension (* Inlined record under extension *)
306
306
| Record_optional_labels of string list (* List of optional labels *)
307
307
Original file line number Diff line number Diff line change @@ -60,6 +60,183 @@ function setAA(ao) {
60
60
} ;
61
61
}
62
62
63
+ var ir0 = {
64
+ TAG : /* V0 */ 0 ,
65
+ x0 : "v0" ,
66
+ x3 : 3
67
+ } ;
68
+
69
+ var ir1 = {
70
+ TAG : /* V0 */ 0 ,
71
+ x0 : "v0" ,
72
+ x1 : "v1" ,
73
+ x3 : 3
74
+ } ;
75
+
76
+ var ir2 = {
77
+ TAG : /* V0 */ 0 ,
78
+ x0 : "v0" ,
79
+ x1 : "v1" ,
80
+ x2 : 2 ,
81
+ x3 : 3
82
+ } ;
83
+
84
+ var ir3 = {
85
+ TAG : /* V1 */ 1 ,
86
+ y0 : "v0" ,
87
+ y1 : 1
88
+ } ;
89
+
90
+ var pm0 ;
91
+
92
+ pm0 = ir0 . TAG === /* V0 */ 0 ? [
93
+ "v0" ,
94
+ 3
95
+ ] : [
96
+ "v0" ,
97
+ undefined
98
+ ] ;
99
+
100
+ var pm1 ;
101
+
102
+ if ( ir1 . TAG === /* V0 */ 0 ) {
103
+ var x1 = "v1" ;
104
+ var x0 = "v0" ;
105
+ pm1 = x1 !== undefined ? [
106
+ x0 ,
107
+ x1 ,
108
+ 3
109
+ ] : [
110
+ x0 ,
111
+ "n/a" ,
112
+ 3
113
+ ] ;
114
+ } else {
115
+ pm1 = [
116
+ "v0" ,
117
+ "n/a" ,
118
+ "v1"
119
+ ] ;
120
+ }
121
+
122
+ var pm2 ;
123
+
124
+ if ( ir2 . TAG === /* V0 */ 0 ) {
125
+ var x1$1 = "v1" ;
126
+ var x0$1 = "v0" ;
127
+ if ( x1$1 !== undefined ) {
128
+ var x2 = 2 ;
129
+ pm2 = x2 !== undefined ? [
130
+ x0$1 ,
131
+ x1$1 ,
132
+ x2 ,
133
+ 3
134
+ ] : [
135
+ x0$1 ,
136
+ x1$1 ,
137
+ 0 ,
138
+ 3
139
+ ] ;
140
+ } else {
141
+ var x2$1 = 2 ;
142
+ pm2 = x2$1 !== undefined ? [
143
+ x0$1 ,
144
+ "n/a" ,
145
+ x2$1 ,
146
+ 3
147
+ ] : [
148
+ x0$1 ,
149
+ "n/a" ,
150
+ 0 ,
151
+ 3
152
+ ] ;
153
+ }
154
+ } else {
155
+ pm2 = [
156
+ "v0" ,
157
+ "n/a" ,
158
+ 0 ,
159
+ "v1"
160
+ ] ;
161
+ }
162
+
163
+ function inlinedRecord ( ir ) {
164
+ if ( ir . TAG !== /* V0 */ 0 ) {
165
+ return [
166
+ ir . y0 ,
167
+ "n/a" ,
168
+ 0 ,
169
+ ir . y1
170
+ ] ;
171
+ }
172
+ var x1 = ir . x1 ;
173
+ var x0 = ir . x0 ;
174
+ if ( x1 !== undefined ) {
175
+ switch ( x1 ) {
176
+ case "x1" :
177
+ var x2 = ir . x2 ;
178
+ if ( x2 !== undefined ) {
179
+ return [
180
+ x0 ,
181
+ "x1" ,
182
+ x2 ,
183
+ ir . x3
184
+ ] ;
185
+ }
186
+ break ;
187
+ case "xx1" :
188
+ var x2$1 = ir . x2 ;
189
+ if ( x2$1 !== undefined ) {
190
+ return [
191
+ x0 ,
192
+ "xx1" ,
193
+ x2$1 ,
194
+ ir . x3
195
+ ] ;
196
+ }
197
+ break ;
198
+ default :
199
+
200
+ }
201
+ var x2$2 = ir . x2 ;
202
+ if ( x2$2 !== undefined ) {
203
+ return [
204
+ x0 ,
205
+ x1 ,
206
+ x2$2 ,
207
+ ir . x3
208
+ ] ;
209
+ } else {
210
+ return [
211
+ x0 ,
212
+ x1 ,
213
+ 0 ,
214
+ ir . x3
215
+ ] ;
216
+ }
217
+ }
218
+ var x2$3 = ir . x2 ;
219
+ if ( x2$3 !== undefined ) {
220
+ return [
221
+ x0 ,
222
+ "n/a" ,
223
+ x2$3 ,
224
+ ir . x3
225
+ ] ;
226
+ } else {
227
+ return [
228
+ x0 ,
229
+ "n/a" ,
230
+ 0 ,
231
+ ir . x3
232
+ ] ;
233
+ }
234
+ }
235
+
236
+ var pm3 = inlinedRecord ( ir2 ) ;
237
+
238
+ var pm4 = inlinedRecord ( ir3 ) ;
239
+
63
240
var f2 = {
64
241
x : 3 ,
65
242
y : 3 ,
@@ -93,4 +270,14 @@ exports.h10 = h10;
93
270
exports . h11 = h11 ;
94
271
exports . po = po ;
95
272
exports . setAA = setAA ;
273
+ exports . ir0 = ir0 ;
274
+ exports . ir1 = ir1 ;
275
+ exports . ir2 = ir2 ;
276
+ exports . ir3 = ir3 ;
277
+ exports . pm0 = pm0 ;
278
+ exports . pm1 = pm1 ;
279
+ exports . pm2 = pm2 ;
280
+ exports . inlinedRecord = inlinedRecord ;
281
+ exports . pm3 = pm3 ;
282
+ exports . pm4 = pm4 ;
96
283
/* Not a pure module */
You can’t perform that action at this time.
0 commit comments