Skip to content

Commit 233db91

Browse files
committed
Extend Texp_function with arity information.
1 parent a1b27d5 commit 233db91

File tree

5 files changed

+19
-123
lines changed

5 files changed

+19
-123
lines changed

compiler/ml/tast_mapper.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ let expr sub x =
199199
| Texp_let (rec_flag, list, exp) ->
200200
let rec_flag, list = sub.value_bindings sub (rec_flag, list) in
201201
Texp_let (rec_flag, list, sub.expr sub exp)
202-
| Texp_function {arg_label; param; case; partial} ->
203-
Texp_function {arg_label; param; case = sub.case sub case; partial}
202+
| Texp_function {arg_label; arity; param; case; partial} ->
203+
Texp_function {arg_label; arity; param; case = sub.case sub case; partial}
204204
| Texp_apply (exp, list) ->
205205
Texp_apply
206206
(sub.expr sub exp, List.map (tuple2 id (opt (sub.expr sub))) list)

compiler/ml/translcore.ml

+6-2
Original file line numberDiff line numberDiff line change
@@ -554,15 +554,19 @@ let rec push_defaults loc bindings case partial =
554554
| {
555555
c_lhs = pat;
556556
c_guard = None;
557-
c_rhs = {exp_desc = Texp_function {arg_label; param; case; partial}} as exp;
557+
c_rhs =
558+
{exp_desc = Texp_function {arg_label; arity; param; case; partial}} as exp;
558559
} ->
559560
let case = push_defaults exp.exp_loc bindings case partial in
560561

561562
{
562563
c_lhs = pat;
563564
c_guard = None;
564565
c_rhs =
565-
{exp with exp_desc = Texp_function {arg_label; param; case; partial}};
566+
{
567+
exp with
568+
exp_desc = Texp_function {arg_label; arity; param; case; partial};
569+
};
566570
}
567571
| {
568572
c_lhs = pat;

compiler/ml/typecore.ml

+9-119
Original file line numberDiff line numberDiff line change
@@ -2371,7 +2371,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
23712371
exp_attributes = sexp.pexp_attributes;
23722372
exp_env = env;
23732373
}
2374-
| Pexp_fun (l, Some default, spat, sbody, _arity) ->
2374+
| Pexp_fun (l, Some default, spat, sbody, arity) ->
23752375
assert (is_optional l);
23762376
(* default allowed only with optional argument *)
23772377
let open Ast_helper in
@@ -2409,10 +2409,10 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
24092409
[Vb.mk spat smatch]
24102410
sbody
24112411
in
2412-
type_function ?in_function loc sexp.pexp_attributes env ty_expected l
2412+
type_function ?in_function ~arity loc sexp.pexp_attributes env ty_expected l
24132413
[Exp.case pat body]
2414-
| Pexp_fun (l, None, spat, sbody, _arity) ->
2415-
type_function ?in_function loc sexp.pexp_attributes env ty_expected l
2414+
| Pexp_fun (l, None, spat, sbody, arity) ->
2415+
type_function ?in_function ~arity loc sexp.pexp_attributes env ty_expected l
24162416
[Ast_helper.Exp.case spat sbody]
24172417
| Pexp_apply (sfunct, sargs) ->
24182418
assert (sargs <> []);
@@ -3273,7 +3273,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
32733273
| Pexp_extension ext ->
32743274
raise (Error_forward (Builtin_attributes.error_of_extension ext))
32753275
3276-
and type_function ?in_function loc attrs env ty_expected l caselist =
3276+
and type_function ?in_function ~arity loc attrs env ty_expected l caselist =
32773277
let loc_fun, ty_fun =
32783278
match in_function with
32793279
| Some p -> p
@@ -3313,7 +3313,7 @@ and type_function ?in_function loc attrs env ty_expected l caselist =
33133313
let param = name_pattern "param" cases in
33143314
re
33153315
{
3316-
exp_desc = Texp_function {arg_label = l; param; case; partial};
3316+
exp_desc = Texp_function {arg_label = l; arity; param; case; partial};
33173317
exp_loc = loc;
33183318
exp_extra = [];
33193319
exp_type = instance env (newgenty (Tarrow (l, ty_arg, ty_res, Cok)));
@@ -3404,119 +3404,9 @@ and type_label_exp ?type_clash_context create env loc ty_expected
34043404
34053405
and type_argument ?type_clash_context ?recarg env sarg ty_expected' ty_expected
34063406
=
3407-
(* ty_expected' may be generic *)
3408-
let no_labels ty =
3409-
let ls, tvar = list_labels env ty in
3410-
(not tvar) && List.for_all (fun x -> x = Nolabel) ls
3411-
in
3412-
let rec is_inferred sexp =
3413-
match sexp.pexp_desc with
3414-
| Pexp_ident _ | Pexp_apply _ | Pexp_field _ | Pexp_constraint _
3415-
| Pexp_coerce _ | Pexp_send _ | Pexp_new _ ->
3416-
true
3417-
| Pexp_sequence (_, e) | Pexp_open (_, _, e) -> is_inferred e
3418-
| Pexp_ifthenelse (_, e1, Some e2) -> is_inferred e1 && is_inferred e2
3419-
| _ -> false
3420-
in
3421-
match expand_head env ty_expected' with
3422-
| {desc = Tarrow (Nolabel, ty_arg, ty_res, _); level = _}
3423-
when is_inferred sarg ->
3424-
(* apply optional arguments when expected type is "" *)
3425-
(* we must be very careful about not breaking the semantics *)
3426-
let texp = type_exp env sarg in
3427-
let rec make_args args ty_fun =
3428-
match (expand_head env ty_fun).desc with
3429-
| Tarrow (l, ty_arg, ty_fun, _) when is_optional l ->
3430-
let ty = option_none (instance env ty_arg) sarg.pexp_loc in
3431-
make_args ((l, Some ty) :: args) ty_fun
3432-
| Tarrow (Nolabel, _, ty_res', _) ->
3433-
(List.rev args, ty_fun, no_labels ty_res')
3434-
| Tvar _ -> (List.rev args, ty_fun, false)
3435-
| _ -> ([], texp.exp_type, false)
3436-
in
3437-
let args, ty_fun', simple_res = make_args [] texp.exp_type in
3438-
let texp = {texp with exp_type = instance env texp.exp_type}
3439-
and ty_fun = instance env ty_fun' in
3440-
if not (simple_res || no_labels ty_res) then (
3441-
unify_exp env texp ty_expected;
3442-
texp)
3443-
else (
3444-
unify_exp env {texp with exp_type = ty_fun} ty_expected;
3445-
if args = [] then texp
3446-
else
3447-
(* eta-expand to avoid side effects *)
3448-
let var_pair name ty =
3449-
let id = Ident.create name in
3450-
( {
3451-
pat_desc = Tpat_var (id, mknoloc name);
3452-
pat_type = ty;
3453-
pat_extra = [];
3454-
pat_attributes = [];
3455-
pat_loc = Location.none;
3456-
pat_env = env;
3457-
},
3458-
{
3459-
exp_type = ty;
3460-
exp_loc = Location.none;
3461-
exp_env = env;
3462-
exp_extra = [];
3463-
exp_attributes = [];
3464-
exp_desc =
3465-
Texp_ident
3466-
( Path.Pident id,
3467-
mknoloc (Longident.Lident name),
3468-
{
3469-
val_type = ty;
3470-
val_kind = Val_reg;
3471-
val_attributes = [];
3472-
Types.val_loc = Location.none;
3473-
} );
3474-
} )
3475-
in
3476-
let eta_pat, eta_var = var_pair "eta" ty_arg in
3477-
let func texp =
3478-
let e =
3479-
{
3480-
texp with
3481-
exp_type = ty_res;
3482-
exp_desc = Texp_apply (texp, args @ [(Nolabel, Some eta_var)]);
3483-
}
3484-
in
3485-
let case = case eta_pat e in
3486-
let param = name_pattern "param" [case] in
3487-
{
3488-
texp with
3489-
exp_type = ty_fun;
3490-
exp_desc =
3491-
Texp_function {arg_label = Nolabel; param; case; partial = Total};
3492-
}
3493-
in
3494-
Location.prerr_warning texp.exp_loc
3495-
(Warnings.Eliminated_optional_arguments
3496-
(List.map (fun (l, _) -> Printtyp.string_of_label l) args));
3497-
(* let-expand to have side effects *)
3498-
let let_pat, let_var = var_pair "arg" texp.exp_type in
3499-
re
3500-
{
3501-
texp with
3502-
exp_type = ty_fun;
3503-
exp_desc =
3504-
Texp_let
3505-
( Nonrecursive,
3506-
[
3507-
{
3508-
vb_pat = let_pat;
3509-
vb_expr = texp;
3510-
vb_attributes = [];
3511-
vb_loc = Location.none;
3512-
};
3513-
],
3514-
func let_var );
3515-
})
3516-
| _ ->
3517-
let texp = type_expect ?type_clash_context ?recarg env sarg ty_expected' in
3518-
unify_exp ?type_clash_context env texp ty_expected;
3519-
texp
3407+
let texp = type_expect ?type_clash_context ?recarg env sarg ty_expected' in
3408+
unify_exp ?type_clash_context env texp ty_expected;
3409+
texp
35203410
35213411
and is_automatic_curried_application env funct =
35223412
(* When a curried function is used with uncurried application, treat it as a curried application *)

compiler/ml/typedtree.ml

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ and expression_desc =
7878
| Texp_let of rec_flag * value_binding list * expression
7979
| Texp_function of {
8080
arg_label: arg_label;
81+
arity: int option;
8182
param: Ident.t;
8283
case: case;
8384
partial: partial;

compiler/ml/typedtree.mli

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ and expression_desc =
132132
*)
133133
| Texp_function of {
134134
arg_label: arg_label;
135+
arity: int option;
135136
param: Ident.t;
136137
case: case;
137138
partial: partial;

0 commit comments

Comments
 (0)