@@ -361,11 +361,18 @@ and transl_exp0 ~in_new_scope ~scopes e =
361
361
body_layout (event_before ~scopes body (transl_exp ~scopes body))
362
362
| Texp_function { arg_label = _; param; cases; partial;
363
363
region; curry; warnings; arg_mode; alloc_mode } ->
364
+ (* CR ncourant: it would be better if we had [arg_layout] here *)
365
+ let arg_layout =
366
+ match is_function_type e.exp_env e.exp_type with
367
+ | None -> Misc. fatal_error " Translcore.transl_exp0: Type of a function is not a function type"
368
+ | Some (arg_type , _ ) ->
369
+ Typeopt. layout e.exp_env arg_type
370
+ in
364
371
let scopes =
365
372
if in_new_scope then scopes
366
373
else enter_anonymous_function ~scopes
367
374
in
368
- transl_function ~scopes e alloc_mode param arg_mode cases partial warnings region curry
375
+ transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial warnings region curry
369
376
| Texp_apply ({ exp_desc = Texp_ident (path, _, {val_kind = Val_prim p},
370
377
Id_prim pmode);
371
378
exp_type = prim_type; } as funct, oargs, pos, alloc_mode)
@@ -1072,10 +1079,10 @@ and transl_apply ~scopes
1072
1079
1073
1080
and transl_curried_function
1074
1081
~scopes loc return
1075
- repr ~region ~curry partial warnings (param :Ident.t ) cases =
1082
+ repr ~region ~curry partial warnings (param :Ident.t ) arg_layout cases =
1076
1083
let max_arity = Lambda. max_arity () in
1077
1084
let rec loop ~scopes loc return ~arity ~region ~curry
1078
- partial warnings (param :Ident.t ) cases =
1085
+ partial warnings (param :Ident.t ) arg_layout cases =
1079
1086
match curry, cases with
1080
1087
More_args {partial_mode} ,
1081
1088
[{c_lhs= pat; c_guard= None ;
@@ -1091,12 +1098,18 @@ and transl_curried_function
1091
1098
if Parmatch. inactive ~partial pat
1092
1099
then
1093
1100
let partial_mode = transl_alloc_mode partial_mode in
1094
- let layout = layout pat.pat_env pat.pat_type in
1095
1101
let return_layout = function_return_layout exp_env exp_type in
1102
+ let arg_layout' =
1103
+ match is_function_type exp_env exp_type with
1104
+ | None ->
1105
+ Misc. fatal_error " Translcore.transl_curried_function: \
1106
+ Type of Texp_function is not function"
1107
+ | Some (lhs , _ ) -> layout exp_env lhs
1108
+ in
1096
1109
let ((fnkind, params, return, region), body) =
1097
1110
loop ~scopes exp_loc return_layout
1098
1111
~arity: (arity + 1 ) ~region: region' ~curry: curry'
1099
- partial' warnings' param' cases'
1112
+ partial' warnings' param' arg_layout' cases'
1100
1113
in
1101
1114
let fnkind =
1102
1115
match partial_mode, fnkind with
@@ -1109,8 +1122,8 @@ and transl_curried_function
1109
1122
assert (nlocal = List. length params);
1110
1123
Curried {nlocal = nlocal + 1 }
1111
1124
in
1112
- ((fnkind, (param, layout ) :: params, return, region),
1113
- Matching. for_function ~scopes return_layout loc None (Lvar param, layout )
1125
+ ((fnkind, (param, arg_layout ) :: params, return, region),
1126
+ Matching. for_function ~scopes return_layout loc None (Lvar param, arg_layout )
1114
1127
[pat, body] partial)
1115
1128
else begin
1116
1129
begin match partial with
@@ -1123,18 +1136,18 @@ and transl_curried_function
1123
1136
| Partial -> ()
1124
1137
end ;
1125
1138
transl_tupled_function ~scopes ~arity ~region ~curry
1126
- loc return repr partial param cases
1139
+ loc return repr partial param arg_layout cases
1127
1140
end
1128
1141
| curry , cases ->
1129
1142
transl_tupled_function ~scopes ~arity ~region ~curry
1130
- loc return repr partial param cases
1143
+ loc return repr partial param arg_layout cases
1131
1144
in
1132
1145
loop ~scopes loc return ~arity: 1 ~region ~curry
1133
- partial warnings param cases
1146
+ partial warnings param arg_layout cases
1134
1147
1135
1148
and transl_tupled_function
1136
1149
~scopes ~arity ~region ~curry loc return
1137
- repr partial (param :Ident.t ) cases =
1150
+ repr partial (param :Ident.t ) arg_layout cases =
1138
1151
let partial_mode =
1139
1152
match curry with
1140
1153
| More_args {partial_mode} | Final_arg {partial_mode} ->
@@ -1153,21 +1166,13 @@ and transl_tupled_function
1153
1166
(Matching. flatten_pattern size c_lhs, c_guard, c_rhs))
1154
1167
cases in
1155
1168
let kinds =
1156
- (* All the patterns might not share the same types. We must take the
1157
- union of the patterns types *)
1158
- match pats_expr_list with
1159
- | [] -> assert false
1160
- | (pats , _ , _ ) :: cases ->
1161
- let first_case_layouts =
1162
- List. map (fun pat -> layout pat.pat_env pat.pat_type) pats
1163
- in
1164
- List. fold_left
1165
- (fun kinds (pats , _ , _ ) ->
1166
- List. map2 (fun kind pat ->
1167
- layout_union kind
1168
- (layout pat.pat_env pat.pat_type))
1169
- kinds pats)
1170
- first_case_layouts cases
1169
+ match arg_layout with
1170
+ | Pvalue (Pvariant { consts = [] ; non_consts = [0 , kinds] } ) ->
1171
+ List. map (fun vk -> Pvalue vk) kinds
1172
+ | _ ->
1173
+ Misc. fatal_error
1174
+ " Translcore.transl_tupled_function: \
1175
+ Argument should be a tuple, but couldn't get the kinds"
1171
1176
in
1172
1177
let tparams =
1173
1178
List. map (fun kind -> Ident. create_local " param" , kind) kinds
@@ -1181,29 +1186,16 @@ and transl_tupled_function
1181
1186
((Tupled , tparams, return, region), body)
1182
1187
with Matching. Cannot_flatten ->
1183
1188
transl_function0 ~scopes loc ~region ~partial_mode
1184
- return repr partial param cases
1189
+ return repr partial param arg_layout cases
1185
1190
end
1186
1191
| _ -> transl_function0 ~scopes loc ~region ~partial_mode
1187
- return repr partial param cases
1192
+ return repr partial param arg_layout cases
1188
1193
1189
1194
and transl_function0
1190
1195
~scopes loc ~region ~partial_mode return
1191
- repr partial (param :Ident.t ) cases =
1192
- let layout =
1193
- match cases with
1194
- | [] ->
1195
- (* With Camlp4, a pattern matching might be empty *)
1196
- Lambda. layout_bottom
1197
- | {c_lhs =pat } :: other_cases ->
1198
- (* All the patterns might not share the same types. We must take the
1199
- union of the patterns types *)
1200
- List. fold_left (fun ly {c_lhs =pat } ->
1201
- Typeopt. layout_union ly
1202
- (layout pat.pat_env pat.pat_type))
1203
- (layout pat.pat_env pat.pat_type) other_cases
1204
- in
1196
+ repr partial (param :Ident.t ) arg_layout cases =
1205
1197
let body =
1206
- Matching. for_function ~scopes return loc repr (Lvar param, layout )
1198
+ Matching. for_function ~scopes return loc repr (Lvar param, arg_layout )
1207
1199
(transl_cases ~scopes cases) partial
1208
1200
in
1209
1201
let region = region || not (may_allocate_in_region body) in
@@ -1213,17 +1205,17 @@ and transl_function0
1213
1205
| Alloc_local -> 1
1214
1206
| Alloc_heap -> 0
1215
1207
in
1216
- ((Curried {nlocal}, [param, layout ], return, region), body)
1208
+ ((Curried {nlocal}, [param, arg_layout ], return, region), body)
1217
1209
1218
- and transl_function ~scopes e alloc_mode param arg_mode cases partial warnings region curry =
1210
+ and transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial warnings region curry =
1219
1211
let mode = transl_alloc_mode alloc_mode in
1220
1212
let ((kind, params, return, region), body) =
1221
1213
event_function ~scopes e
1222
1214
(function repr ->
1223
1215
let pl = push_defaults e.exp_loc arg_mode cases partial warnings in
1224
1216
let return_layout = function_return_layout e.exp_env e.exp_type in
1225
1217
transl_curried_function ~scopes e.exp_loc return_layout
1226
- repr ~region ~curry partial warnings param pl)
1218
+ repr ~region ~curry partial warnings param arg_layout pl)
1227
1219
in
1228
1220
let attr = default_function_attribute in
1229
1221
let loc = of_location ~scopes e.exp_loc in
@@ -1570,13 +1562,31 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings =
1570
1562
in
1571
1563
let exp = loop (layout let_.bop_exp.exp_env let_.bop_exp.exp_type) (transl_exp ~scopes let_.bop_exp) ands in
1572
1564
let func =
1565
+ let arg_layout =
1566
+ match Typeopt. is_function_type env let_.bop_op_type with
1567
+ | None ->
1568
+ Misc. fatal_error
1569
+ " Translcore.transl_letop: letop should be a function"
1570
+ | Some (_ , rhs ) ->
1571
+ match Typeopt. is_function_type env rhs with
1572
+ | None ->
1573
+ Misc. fatal_error
1574
+ " Translcore.transl_letop: letop should have at least two arguments"
1575
+ | Some (lhs , _ ) ->
1576
+ match Typeopt. is_function_type env lhs with
1577
+ | None ->
1578
+ Misc. fatal_error
1579
+ " Translcore.transl_letop: letop second argument should be a function"
1580
+ | Some (arg_type , _ ) ->
1581
+ Typeopt. layout env arg_type
1582
+ in
1573
1583
let return_layout = layout case.c_rhs.exp_env case.c_rhs.exp_type in
1574
1584
let curry = More_args { partial_mode = Alloc_mode. global } in
1575
1585
let (kind, params, return, _region), body =
1576
1586
event_function ~scopes case.c_rhs
1577
1587
(function repr ->
1578
1588
transl_curried_function ~scopes case.c_rhs.exp_loc return_layout
1579
- repr ~region: true ~curry partial warnings param [case])
1589
+ repr ~region: true ~curry partial warnings param arg_layout [case])
1580
1590
in
1581
1591
let attr = default_function_attribute in
1582
1592
let loc = of_location ~scopes case.c_rhs.exp_loc in
0 commit comments