Skip to content

Commit ee3be10

Browse files
committed
Fix modes in build_apply for partial applications
1 parent fe73656 commit ee3be10

12 files changed

+469
-325
lines changed

lambda/translcore.ml

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,15 @@ let extract_float = function
8484
Const_base(Const_float f) -> f
8585
| _ -> fatal_error "Translcore.extract_float"
8686

87-
let transl_value_mode mode : Lambda.alloc_mode =
88-
let alloc_mode = Types.Value_mode.regional_to_global_alloc mode in
87+
let transl_alloc_mode alloc_mode : Lambda.alloc_mode =
8988
match Types.Alloc_mode.constrain_lower alloc_mode with
9089
| Global -> Alloc_heap
9190
| Local -> Alloc_local
9291

92+
let transl_value_mode mode =
93+
let alloc_mode = Types.Value_mode.regional_to_global_alloc mode in
94+
transl_alloc_mode alloc_mode
95+
9396
let join_mode a b =
9497
match a, b with
9598
| Alloc_local, _ | _, Alloc_local -> Alloc_local
@@ -245,6 +248,10 @@ let maybe_region parent_mode (children : Lambda.alloc_mode list) e =
245248
else
246249
e
247250

251+
let is_omitted = function
252+
| Arg _ -> false
253+
| Omitted _ -> true
254+
248255
let rec transl_exp ~scopes e =
249256
transl_exp1 ~scopes ~in_new_scope:false e
250257

@@ -284,10 +291,10 @@ and transl_exp0 ~in_new_scope ~scopes e =
284291
| Texp_apply({ exp_desc = Texp_ident(path, _, {val_kind = Val_prim p});
285292
exp_type = prim_type } as funct, oargs)
286293
when List.length oargs >= p.prim_arity
287-
&& List.for_all (fun (_, arg) -> arg <> None) oargs ->
294+
&& List.for_all (fun (_, arg) -> not (is_omitted arg)) oargs ->
288295
let argl, extra_args = cut p.prim_arity oargs in
289296
let arg_exps =
290-
List.map (function _, Some x -> x | _ -> assert false) argl
297+
List.map (function _, Arg x -> x | _ -> assert false) argl
291298
in
292299
let args = transl_list ~scopes arg_exps in
293300
let prim_exp = if extra_args = [] then Some e else None in
@@ -733,8 +740,9 @@ and transl_apply ~scopes
733740
=
734741
let bound_modes =
735742
List.map (function
736-
| (_,Some e) -> transl_value_mode e.exp_mode
737-
| (_,None) -> Alloc_heap) sargs in
743+
| (_,Arg e) -> transl_value_mode e.exp_mode
744+
| (_,Omitted _) -> Alloc_heap) sargs
745+
in
738746
let lapply funct args =
739747
match funct with
740748
Lsend(k, lmet, lobj, largs, _) ->
@@ -754,7 +762,7 @@ and transl_apply ~scopes
754762
}
755763
in
756764
let rec build_apply lam args = function
757-
(None, optional) :: l ->
765+
(Omitted { mode_closure; mode_arg; mode_ret }, optional) :: l ->
758766
let defs = ref [] in
759767
let protect name lam =
760768
match lam with
@@ -769,31 +777,48 @@ and transl_apply ~scopes
769777
in
770778
let handle = protect "func" lam in
771779
let l =
772-
List.map (fun (arg, opt) -> Option.map (protect "arg") arg, opt) l
780+
List.map
781+
(fun (arg, opt) ->
782+
match arg with
783+
| Omitted _ -> arg, opt
784+
| Arg arg -> Arg (protect "arg" arg), opt)
785+
l
773786
in
774787
let id_arg = Ident.create_local "param" in
775-
(* FIXME modes / Curried nlocals are completely wrong here *)
776788
let body =
777789
let body = build_apply handle [Lvar id_arg, optional] l in
778-
Lfunction{kind = Curried {nlocal=0}; params = [id_arg, Pgenval];
779-
return = Pgenval; body; mode=Alloc_heap;
780-
ret_mode=Alloc_heap; attr = default_stub_attribute;
781-
loc = loc}
790+
let mode = transl_alloc_mode mode_closure in
791+
let arg_mode = transl_alloc_mode mode_arg in
792+
let ret_mode = transl_alloc_mode mode_ret in
793+
let nlocal =
794+
match join_mode mode (join_mode arg_mode ret_mode) with
795+
| Alloc_local -> 1
796+
| Alloc_heap -> 0
797+
in
798+
Lfunction{kind = Curried {nlocal}; params = [id_arg, Pgenval];
799+
return = Pgenval; body; mode; ret_mode;
800+
attr = default_stub_attribute; loc = loc}
782801
in
783802
List.fold_right
784803
(fun (id, lam) body -> Llet(Strict, Pgenval, id, lam, body))
785804
!defs body
786-
| (Some arg, optional) :: l ->
805+
| (Arg arg, optional) :: l ->
787806
build_apply lam ((arg, optional) :: args) l
788807
| [] ->
789808
lapply lam (List.rev_map fst args)
790809
in
791-
let lam =
792-
build_apply lam [] (List.map (fun (l, x) ->
793-
Option.map (transl_exp ~scopes) x,
794-
Btype.is_optional l)
795-
sargs)
810+
let args =
811+
List.map
812+
(fun (l, arg) ->
813+
let arg =
814+
match arg with
815+
| Omitted _ as arg -> arg
816+
| Arg exp -> Arg (transl_exp ~scopes exp)
817+
in
818+
arg, Btype.is_optional l)
819+
sargs
796820
in
821+
let lam = build_apply lam [] args in
797822
maybe_region mode bound_modes lam
798823

799824
and transl_curried_function

lambda/translcore.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ val transl_apply: scopes:scopes
2929
-> ?inlined:inline_attribute
3030
-> ?specialised:specialise_attribute
3131
-> lambda -> ?mode:Lambda.alloc_mode
32-
-> (arg_label * expression option) list
32+
-> (arg_label * apply_arg) list
3333
-> scoped_location -> lambda
3434
val transl_let: scopes:scopes -> ?in_structure:bool ->
3535
?mode:Lambda.alloc_mode -> rec_flag

ocamldoc/odoc_ast.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ module Analyser =
765765
in
766766
(parameter :: params, k)
767767

768-
| (Parsetree.Pcl_apply (p_class_expr2, _), Tcl_apply (tt_class_expr2, exp_opt_optional_list)) ->
768+
| (Parsetree.Pcl_apply (p_class_expr2, _), Tcl_apply (tt_class_expr2, arg_list)) ->
769769
let applied_name =
770770
(* we want an ident, or else the class applied will appear in the form object ... end,
771771
because if the class applied has no name, the code is kinda ugly, isn't it ? *)
@@ -781,12 +781,12 @@ module Analyser =
781781
Odoc_messages.object_end
782782
in
783783
let param_exps = List.fold_left
784-
(fun acc -> fun (_, exp_opt) ->
785-
match exp_opt with
786-
None -> acc
787-
| Some e -> acc @ [e])
784+
(fun acc -> fun (_, arg) ->
785+
match arg with
786+
| Omitted _ -> acc
787+
| Arg e -> acc @ [e])
788788
[]
789-
exp_opt_optional_list
789+
arg_list
790790
in
791791
let param_types = List.map (fun e -> e.Typedtree.exp_type) param_exps in
792792
let params_code =

typing/printtyped.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ and expression i ppf x =
334334
| Texp_apply (e, l) ->
335335
line i ppf "Texp_apply\n";
336336
expression i ppf e;
337-
list i label_x_expression ppf l;
337+
list i label_x_apply_arg ppf l;
338338
| Texp_match (e, l, _partial) ->
339339
line i ppf "Texp_match\n";
340340
expression i ppf e;
@@ -611,7 +611,7 @@ and class_expr i ppf x =
611611
| Tcl_apply (ce, l) ->
612612
line i ppf "Tcl_apply\n";
613613
class_expr i ppf ce;
614-
list i label_x_expression ppf l;
614+
list i label_x_apply_arg ppf l;
615615
| Tcl_let (rf, l1, l2, ce) ->
616616
line i ppf "Tcl_let %a\n" fmt_rec_flag rf;
617617
list i value_binding ppf l1;
@@ -923,10 +923,10 @@ and record_field i ppf = function
923923
| _, Kept _ ->
924924
line i ppf "<kept>"
925925

926-
and label_x_expression i ppf (l, e) =
926+
and label_x_apply_arg i ppf (l, e) =
927927
line i ppf "<arg>\n";
928928
arg_label (i+1) ppf l;
929-
(match e with None -> () | Some e -> expression (i+1) ppf e)
929+
(match e with Omitted _ -> () | Arg e -> expression (i+1) ppf e)
930930

931931
and ident_x_expression_def i ppf (l, e) =
932932
line i ppf "<def> \"%a\"\n" fmt_ident l;

typing/rec_check.ml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ let is_ref : Types.value_description -> bool = function
117117

118118
(* See the note on abstracted arguments in the documentation for
119119
Typedtree.Texp_apply *)
120-
let is_abstracted_arg : arg_label * expression option -> bool = function
121-
| (_, None) -> true
122-
| (_, Some _) -> false
120+
let is_abstracted_arg : arg_label * apply_arg -> bool = function
121+
| (_, Omitted _) -> true
122+
| (_, Arg _) -> false
123123

124124
let classify_expression : Typedtree.expression -> sd =
125125
(* We need to keep track of the size of expressions
@@ -564,7 +564,7 @@ let rec expression : Typedtree.expression -> term_judg =
564564
path pth << Dereference
565565
| Texp_instvar (self_path, pth, _inst_var) ->
566566
join [path self_path << Dereference; path pth]
567-
| Texp_apply ({exp_desc = Texp_ident (_, _, vd)}, [_, Some arg])
567+
| Texp_apply ({exp_desc = Texp_ident (_, _, vd)}, [_, Arg arg])
568568
when is_ref vd ->
569569
(*
570570
G |- e: m[Guard]
@@ -573,7 +573,11 @@ let rec expression : Typedtree.expression -> term_judg =
573573
*)
574574
expression arg << Guard
575575
| Texp_apply (e, args) ->
576-
let arg (_, eo) = option expression eo in
576+
let arg (_, arg) =
577+
match arg with
578+
| Omitted _ -> empty
579+
| Arg e -> expression e
580+
in
577581
let app_mode = if List.exists is_abstracted_arg args
578582
then (* see the comment on Texp_apply in typedtree.mli;
579583
the non-abstracted arguments are bound to local
@@ -1033,7 +1037,11 @@ and class_expr : Typedtree.class_expr -> term_judg =
10331037
let ids = List.map fst args in
10341038
remove_ids ids (class_expr ce << Delay)
10351039
| Tcl_apply (ce, args) ->
1036-
let arg (_label, eo) = option expression eo in
1040+
let arg (_, arg) =
1041+
match arg with
1042+
| Omitted _ -> empty
1043+
| Arg e -> expression e
1044+
in
10371045
join [
10381046
class_expr ce << Dereference;
10391047
list arg args << Dereference;

typing/tast_iterator.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,10 @@ let expr sub {exp_extra; exp_desc; exp_env; _} =
197197
List.iter (sub.case sub) cases
198198
| Texp_apply (exp, list) ->
199199
sub.expr sub exp;
200-
List.iter (fun (_, o) -> Option.iter (sub.expr sub) o) list
200+
List.iter (function
201+
| (_, Arg exp) -> sub.expr sub exp
202+
| (_, Omitted _) -> ())
203+
list
201204
| Texp_match (exp, cases, _) ->
202205
sub.expr sub exp;
203206
List.iter (sub.case sub) cases
@@ -370,7 +373,10 @@ let class_expr sub {cl_desc; cl_env; _} =
370373
sub.class_expr sub cl
371374
| Tcl_apply (cl, args) ->
372375
sub.class_expr sub cl;
373-
List.iter (fun (_, e) -> Option.iter (sub.expr sub) e) args
376+
List.iter (function
377+
| (_, Arg exp) -> sub.expr sub exp
378+
| (_, Omitted _) -> ())
379+
args
374380
| Tcl_let (rec_flag, value_bindings, ivars, cl) ->
375381
sub.value_bindings sub (rec_flag, value_bindings);
376382
List.iter (fun (_, e) -> sub.expr sub e) ivars;

typing/tast_mapper.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,10 @@ let expr sub x =
253253
| Texp_apply (exp, list) ->
254254
Texp_apply (
255255
sub.expr sub exp,
256-
List.map (tuple2 id (Option.map (sub.expr sub))) list
256+
List.map (function
257+
| (lbl, Arg exp) -> (lbl, Arg (sub.expr sub exp))
258+
| (lbl, Omitted o) -> (lbl, Omitted o))
259+
list
257260
)
258261
| Texp_match (exp, cases, p) ->
259262
Texp_match (
@@ -543,7 +546,10 @@ let class_expr sub x =
543546
| Tcl_apply (cl, args) ->
544547
Tcl_apply (
545548
sub.class_expr sub cl,
546-
List.map (tuple2 id (Option.map (sub.expr sub))) args
549+
List.map (function
550+
| (lbl, Arg exp) -> (lbl, Arg (sub.expr sub exp))
551+
| (lbl, Omitted o) -> (lbl, Omitted o))
552+
args
547553
)
548554
| Tcl_let (rec_flag, value_bindings, ivars, cl) ->
549555
let (rec_flag, value_bindings) =

typing/typeclass.ml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ and class_expr_aux cl_num val_env met_env scl =
11201120
let name = Btype.label_name l
11211121
and optional = Btype.is_optional l in
11221122
let use_arg sarg l' =
1123-
Some (
1123+
Arg (
11241124
if not optional || Btype.is_optional l' then
11251125
type_argument val_env sarg ty ty0
11261126
else
@@ -1131,7 +1131,7 @@ and class_expr_aux cl_num val_env met_env scl =
11311131
)
11321132
in
11331133
let eliminate_optional_arg () =
1134-
Some (option_none val_env ty0 Value_mode.global Location.none)
1134+
Arg (option_none val_env ty0 Value_mode.global Location.none)
11351135
in
11361136
let remaining_sargs, arg =
11371137
if ignore_labels then begin
@@ -1162,10 +1162,18 @@ and class_expr_aux cl_num val_env met_env scl =
11621162
sargs,
11631163
if Btype.is_optional l && List.mem_assoc Nolabel sargs then
11641164
eliminate_optional_arg ()
1165-
else
1166-
None
1165+
else begin
1166+
let mode_closure = Alloc_mode.global in
1167+
let mode_arg = Alloc_mode.global in
1168+
let mode_ret = Alloc_mode.global in
1169+
Omitted { mode_closure; mode_arg; mode_ret }
1170+
end
1171+
in
1172+
let omitted =
1173+
match arg with
1174+
| Omitted _ -> (l,ty0) :: omitted
1175+
| Arg _ -> omitted
11671176
in
1168-
let omitted = if arg = None then (l,ty0) :: omitted else omitted in
11691177
type_args ((l,arg)::args) omitted ty_fun ty_fun0 remaining_sargs
11701178
| _ ->
11711179
match sargs with

0 commit comments

Comments
 (0)