Skip to content

Commit dc6f1d6

Browse files
committed
Fix uncurried function type handling in FFI and type system
Fix uncurried function type handling in FFI and type system This commit improves handling of uncurried function types, particularly in FFI and the type system: - Add arity information to @obj externals by returning arity from process_obj - Fix filter_arrow to properly handle arity in type unification - Remove invalid assert false in ast_uncurried.ml - Update type_function and type_application to properly handle arity information - Pass arity through to is_ignore function for consistent type checking These changes help ensure proper type checking and arity handling for uncurried functions, especially in FFI bindings using @obj.
1 parent 0c439eb commit dc6f1d6

File tree

5 files changed

+25
-20
lines changed

5 files changed

+25
-20
lines changed

compiler/frontend/ast_external_process.ml

+10-5
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,8 @@ type response = {
426426

427427
let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
428428
(arg_types_ty : Ast_core_type.param_type list)
429-
(result_type : Ast_core_type.t) : Parsetree.core_type * External_ffi_types.t
430-
=
429+
(result_type : Ast_core_type.t) :
430+
int * Parsetree.core_type * External_ffi_types.t =
431431
match st with
432432
| {
433433
val_name = None;
@@ -610,7 +610,9 @@ let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
610610
(* TODO: do we need do some error checking here *)
611611
(* result type can not be labeled *)
612612
in
613-
( Ast_core_type.mk_fn_type new_arg_types_ty result,
613+
614+
( List.length new_arg_types_ty,
615+
Ast_core_type.mk_fn_type new_arg_types_ty result,
614616
External_ffi_types.ffi_obj_create arg_kinds )
615617
| _ -> Location.raise_errorf ~loc "Attribute found that conflicts with %@obj"
616618

@@ -961,10 +963,13 @@ let handle_attributes (loc : Bs_loc.t) (type_annotation : Parsetree.core_type)
961963
in
962964
if external_desc.mk_obj then
963965
(* warn unused attributes here ? *)
964-
let new_type, spec =
966+
let arity, new_type, spec =
965967
process_obj loc external_desc prim_name arg_types_ty result_type
966968
in
967-
(build_uncurried_type ~arity:None new_type, spec, unused_attrs, false)
969+
( build_uncurried_type ~arity:(Some arity) new_type,
970+
spec,
971+
unused_attrs,
972+
false )
968973
else
969974
let splice = external_desc.splice in
970975
let arg_type_specs, new_arg_types_ty, arg_type_specs_length =

compiler/ml/ast_uncurried.ml

-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ let make_uncurried_type ~env ~arity (t : Types.type_expr) =
9696
let t =
9797
match t.desc with
9898
| Tarrow (l, t1, t2, c, _) ->
99-
let _ = assert false in
10099
{t with desc = Tarrow (l, t1, t2, c, Some arity)}
101100
| Tconstr _ -> assert false
102101
| Tvar _ -> t

compiler/ml/ctype.ml

+2-4
Original file line numberDiff line numberDiff line change
@@ -2758,15 +2758,13 @@ let expand_head_trace env t =
27582758
(2) the original label is not optional
27592759
*)
27602760

2761-
let filter_arrow env t l =
2761+
let filter_arrow ~env ~arity t l =
27622762
let t = expand_head_trace env t in
27632763
match t.desc with
27642764
| Tvar _ ->
2765-
let _ = assert false in
2766-
(* TODO: need the arity from the function definition *)
27672765
let lv = t.level in
27682766
let t1 = newvar2 lv and t2 = newvar2 lv in
2769-
let t' = newty2 lv (Tarrow (l, t1, t2, Cok, None)) in
2767+
let t' = newty2 lv (Tarrow (l, t1, t2, Cok, arity)) in
27702768
link_type t t';
27712769
(t1, t2)
27722770
| Tarrow (l', t1, t2, _, _) when Asttypes.same_arg_label l l' -> (t1, t2)

compiler/ml/ctype.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ val unify_var : Env.t -> type_expr -> type_expr -> unit
203203
val with_passive_variants : ('a -> 'b) -> 'a -> 'b
204204
(* Call [f] in passive_variants mode, for exhaustiveness check. *)
205205

206-
val filter_arrow : Env.t -> type_expr -> arg_label -> type_expr * type_expr
206+
val filter_arrow :
207+
env:Env.t -> arity:arity -> type_expr -> arg_label -> type_expr * type_expr
207208
(* A special case of unification (with l:'a -> 'b). *)
208209

209210
val filter_method : Env.t -> string -> private_flag -> type_expr -> type_expr

compiler/ml/typecore.ml

+11-9
Original file line numberDiff line numberDiff line change
@@ -2225,12 +2225,12 @@ let unify_exp ?type_clash_context env exp expected_ty =
22252225
let loc = proper_exp_loc exp in
22262226
unify_exp_types ?type_clash_context loc env exp.exp_type expected_ty
22272227
2228-
let is_ignore funct env =
2228+
let is_ignore ~env ~arity funct =
22292229
match funct.exp_desc with
22302230
| Texp_ident (_, _, {val_kind = Val_prim {Primitive.prim_name = "%ignore"}})
22312231
-> (
22322232
try
2233-
ignore (filter_arrow env (instance env funct.exp_type) Nolabel);
2233+
ignore (filter_arrow ~env ~arity (instance env funct.exp_type) Nolabel);
22342234
true
22352235
with Unify _ -> false)
22362236
| _ -> false
@@ -3281,7 +3281,7 @@ and type_function ?in_function ~arity loc attrs env ty_expected_ l caselist =
32813281
let separate = Env.has_local_constraints env in
32823282
if separate then begin_def ();
32833283
let ty_arg, ty_res =
3284-
try filter_arrow env (instance env ty_expected) l
3284+
try filter_arrow ~env ~arity (instance env ty_expected) l
32853285
with Unify _ -> (
32863286
match expand_head env ty_expected with
32873287
| {desc = Tarrow _} as ty ->
@@ -3310,7 +3310,9 @@ and type_function ?in_function ~arity loc attrs env ty_expected_ l caselist =
33103310
Location.prerr_warning case.c_lhs.pat_loc
33113311
Warnings.Unerasable_optional_argument;
33123312
let param = name_pattern "param" cases in
3313-
let exp_type = instance env (newgenty (Tarrow (l, ty_arg, ty_res, Cok, assert false))) in
3313+
let exp_type =
3314+
instance env (newgenty (Tarrow (l, ty_arg, ty_res, Cok, arity)))
3315+
in
33143316
let exp_type =
33153317
match arity with
33163318
| None -> exp_type
@@ -3718,11 +3720,14 @@ and type_application ?type_clash_context uncurried env funct (sargs : sargs) :
37183720
(List.map Printtyp.string_of_label
37193721
(Ext_list.filter labels (fun x -> x <> Nolabel))) ))
37203722
in
3723+
if uncurried then force_uncurried_type funct;
3724+
let ty, max_arity = extract_uncurried_type funct.exp_type in
3725+
let top_arity = if uncurried then Some max_arity else None in
37213726
match sargs with
37223727
(* Special case for ignore: avoid discarding warning *)
3723-
| [(Nolabel, sarg)] when is_ignore funct env ->
3728+
| [(Nolabel, sarg)] when is_ignore ~env ~arity:top_arity funct ->
37243729
let ty_arg, ty_res =
3725-
filter_arrow env (instance env funct.exp_type) Nolabel
3730+
filter_arrow ~env ~arity:top_arity (instance env funct.exp_type) Nolabel
37263731
in
37273732
let exp = type_expect env sarg ty_arg in
37283733
(match (expand_head env exp.exp_type).desc with
@@ -3734,9 +3739,6 @@ and type_application ?type_clash_context uncurried env funct (sargs : sargs) :
37343739
| _ -> ());
37353740
([(Nolabel, Some exp)], ty_res, false)
37363741
| _ ->
3737-
if uncurried then force_uncurried_type funct;
3738-
let ty, max_arity = extract_uncurried_type funct.exp_type in
3739-
let top_arity = if uncurried then Some max_arity else None in
37403742
let targs, ret_t =
37413743
type_args ?type_clash_context max_arity [] [] ~ty_fun:ty (instance env ty)
37423744
~sargs ~top_arity

0 commit comments

Comments
 (0)