Skip to content

Commit e759c61

Browse files
committed
Fix issue with typing application and polymorphic types.
Fixes #7323 When typing application there's a special treatment for polymorphic types, where the arity and kinds of arguments are inferred. For example: `f => f(~lbl1, ~lbl2)` assigns a polymorphic type `'a` to `f` initially which is then instantated to `(~lbl1:t1, ~lbl2:t2) => t3`. That same mechanism currently applies when a function is annotated to return a polymorphic type such as `(string, ~wrongLabelName: int=?) => 'a`, where the `'a` is further instantiated to extend the function type with additional arguments. This mechanism is OK for curried function, but incorrect for uncurried functions: while e.g. `'a => 'b` with curried function designates any function where the first argument is unlabeled, with uncurried function it only designates functions of arity 1. So when processing application, `'b` should not be expanded further. Two examples of problematic code that now gives type error: ```res let r: (string, ~wrongLabelName: int=?) => 'a = (_s, ~wrongLabelName=3) => { let _ = wrongLabelName assert(false) } let tst1 = r("", ~initialValue=2) let tst2 = r("")(~initialValue=2) ``` and ```res let f = (_, ~def=3) => assert(false) let g1 = f(1,2) let g2 = f(1)(2) ```
1 parent 2a358eb commit e759c61

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

compiler/ml/typecore.ml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3449,6 +3449,7 @@ and translate_unified_ops (env : Env.t) (funct : Typedtree.expression)
34493449
34503450
and type_application ?type_clash_context total_app env funct (sargs : sargs) :
34513451
targs * Types.type_expr * bool =
3452+
(* Printf.eprintf "type_application: #args:%d\n" (List.length sargs); *)
34523453
let result_type omitted ty_fun =
34533454
List.fold_left
34543455
(fun ty_fun (l, ty, lv) -> newty2 lv (Tarrow (l, ty, ty_fun, Cok, None)))
@@ -3465,6 +3466,7 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
34653466
| Tvar _ when total_app -> true
34663467
| _ -> false
34673468
in
3469+
(* Printf.eprintf "force_tvar:%b\n" force_tvar; *)
34683470
let has_arity funct =
34693471
let t = funct.exp_type in
34703472
if force_tvar then Some (List.length sargs)
@@ -3550,11 +3552,15 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
35503552
type_unknown_args max_arity ~args ~top_arity:None omitted ty_fun []
35513553
| (l1, sarg1) :: sargl ->
35523554
let l1 = to_noloc l1 in
3555+
(* let lbl_name = label_name l1 in
3556+
Printf.eprintf " type_unknown_args: lbl_name:%s\n" lbl_name; *)
35533557
let ty1, ty2 =
35543558
let ty_fun = expand_head env ty_fun in
35553559
let arity_ok = List.length args < max_arity in
35563560
match ty_fun.desc with
3557-
| Tvar _ ->
3561+
| Tvar _ when (* l1 = Nolabel || *) force_tvar ->
3562+
(* This is a total application when the toplevel type is a polymorphic variable,
3563+
so the function type including arity can be inferred. *)
35583564
let t1 = newvar () and t2 = newvar () in
35593565
if ty_fun.level >= t1.level && not_identity funct.exp_desc then
35603566
Location.prerr_warning sarg1.pexp_loc Warnings.Unused_argument;
@@ -3605,9 +3611,11 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
36053611
when sargs <> [] && commu_repr com = Cok && List.length args < max_arity
36063612
->
36073613
let name = label_name l and optional = is_optional l in
3614+
(* Printf.eprintf " type_args: name:%s, optional:%b\n" name optional; *)
36083615
let sargs, omitted, arg =
36093616
match extract_label name sargs with
36103617
| None ->
3618+
(* Printf.eprintf " extract_label: None\n"; *)
36113619
if optional && (total_app || label_assoc Nolabel sargs) then (
36123620
ignored := (l, ty, lv) :: !ignored;
36133621
( sargs,
@@ -3640,8 +3648,14 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
36403648
sargs (* This is the hot path for non-labeled function*)
36413649
in
36423650
if total_app then force_uncurried_type funct;
3651+
(* Printf.eprintf "total_app:%b\n" total_app; *)
36433652
let max_arity = get_max_arity funct in
3653+
(* Printf.eprintf "max_arity:%d\n" max_arity; *)
36443654
let top_arity = if total_app then Some max_arity else None in
3655+
(* Printf.eprintf "top_arity:%s\n"
3656+
(match top_arity with
3657+
| Some _ -> "Some"
3658+
| None -> "None"); *)
36453659
match sargs with
36463660
(* Special case for ignore: avoid discarding warning *)
36473661
| [(Nolabel, sarg)] when is_ignore ~env ~arity:top_arity funct ->

0 commit comments

Comments
 (0)