Skip to content

Commit 422e348

Browse files
authored
Allow explicit binders for type variables (ocaml#10437) (#1757)
Update the parser with ocaml/ocaml#10437
1 parent fa802db commit 422e348

File tree

13 files changed

+153
-89
lines changed

13 files changed

+153
-89
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
+ Handle punned labelled arguments with type constraint in function applications.
2626
For example, function application of the form `foo ~(x:int)` instead of the explicit `foo ~x:(x:int)`. (ocaml#10434) (#1756, @gpetiot)
2727

28+
+ Allow explicit binders for type variables (ocaml#10437) (#1757, @gpetiot)
29+
2830
### 0.19.0 (2021-07-16)
2931

3032
#### Bug fixes

lib/Ast.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ end = struct
932932
in
933933
let check_ext {pext_kind; _} =
934934
match pext_kind with
935-
| Pext_decl (cstr, t0) -> check_cstr cstr || Option.exists t0 ~f
935+
| Pext_decl (_, cstr, t0) -> check_cstr cstr || Option.exists t0 ~f
936936
| _ -> false
937937
in
938938
let check_typext {ptyext_params; ptyext_constructors; _} =
@@ -1597,7 +1597,7 @@ end = struct
15971597
| _ -> false
15981598
in
15991599
let is_tuple_lvl1_in_ext_constructor ty = function
1600-
| {pext_kind= Pext_decl (Pcstr_tuple t1N, _); _} ->
1600+
| {pext_kind= Pext_decl (_, Pcstr_tuple t1N, _); _} ->
16011601
List.exists t1N ~f:(phys_equal ty)
16021602
| _ -> false
16031603
in
@@ -1869,14 +1869,14 @@ end = struct
18691869
{ pstr_desc=
18701870
Pstr_exception
18711871
{ ptyexn_constructor=
1872-
{pext_kind= Pext_decl (Pcstr_tuple t, _); _}
1872+
{pext_kind= Pext_decl (_, Pcstr_tuple t, _); _}
18731873
; _ }
18741874
; _ }
18751875
| Sig
18761876
{ psig_desc=
18771877
Psig_exception
18781878
{ ptyexn_constructor=
1879-
{pext_kind= Pext_decl (Pcstr_tuple t, _); _}
1879+
{pext_kind= Pext_decl (_, Pcstr_tuple t, _); _}
18801880
; _ }
18811881
; _ } ) }
18821882
when List.exists t ~f:(phys_equal typ) ->

lib/Exposed.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ module Right = struct
5050
| {pext_kind; _} -> (
5151
match pext_kind with
5252
| Pext_rebind _ -> false
53-
| Pext_decl (_, Some _result) -> false
54-
| Pext_decl (args, None) -> constructor_arguments args )
53+
| Pext_decl (_, _, Some _result) -> false
54+
| Pext_decl (_, args, None) -> constructor_arguments args )
5555

5656
let constructor_declaration = function
5757
| {pcd_attributes= _ :: _; _} -> false

lib/Fmt_ast.ml

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,7 +3273,12 @@ and fmt_label_declaration c ctx ?(last = false) decl =
32733273

32743274
and fmt_constructor_declaration c ctx ~max_len_name ~first ~last:_ cstr_decl
32753275
=
3276-
let {pcd_name= {txt; loc}; pcd_args; pcd_res; pcd_attributes; pcd_loc} =
3276+
let { pcd_name= {txt; loc}
3277+
; pcd_vars
3278+
; pcd_args
3279+
; pcd_res
3280+
; pcd_attributes
3281+
; pcd_loc } =
32773282
cstr_decl
32783283
in
32793284
update_config_maybe_disabled c pcd_loc pcd_attributes
@@ -3311,16 +3316,17 @@ and fmt_constructor_declaration c ctx ~max_len_name ~first ~last:_ cstr_decl
33113316
( Cmts.fmt c loc
33123317
(wrap_if (String_id.is_symbol txt) "( " " )" (str txt))
33133318
$ fmt_padding
3314-
$ fmt_constructor_arguments_result c ctx pcd_args pcd_res )
3319+
$ fmt_constructor_arguments_result c ctx pcd_vars pcd_args
3320+
pcd_res )
33153321
$ fmt_attributes c ~pre:(Break (1, 0)) ~key:"@" atrs
33163322
$ fmt_docstring_padded c doc )
33173323
$ Cmts.fmt_after c ~pro:(fmt_or c.conf.wrap_comments "@ " " ") pcd_loc
33183324
)
33193325

3320-
and fmt_constructor_arguments c ctx ~pre = function
3326+
and fmt_constructor_arguments ?vars c ctx ~pre = function
33213327
| Pcstr_tuple [] -> noop
33223328
| Pcstr_tuple typs ->
3323-
pre $ fmt "@ "
3329+
pre $ fmt "@ " $ fmt_opt vars
33243330
$ hvbox 0 (list typs "@ * " (sub_typ ~ctx >> fmt_core_type c))
33253331
| Pcstr_record lds ->
33263332
let p = Params.get_record_type c.conf in
@@ -3336,13 +3342,20 @@ and fmt_constructor_arguments c ctx ~pre = function
33363342
$ p.box_record (list_fl lds fmt_ld)
33373343
$ p.break_after $ p.docked_after
33383344

3339-
and fmt_constructor_arguments_result c ctx args res =
3345+
and fmt_constructor_arguments_result c ctx vars args res =
33403346
let pre = fmt_or (Option.is_none res) " of" " :" in
33413347
let before_type = match args with Pcstr_tuple [] -> ": " | _ -> "-> " in
33423348
let fmt_type typ =
33433349
fmt "@ " $ str before_type $ fmt_core_type c (sub_typ ~ctx typ)
33443350
in
3345-
fmt_constructor_arguments c ctx ~pre args $ opt res fmt_type
3351+
let fmt_vars =
3352+
match vars with
3353+
| [] -> noop
3354+
| _ ->
3355+
hvbox 0 (list vars "@ " (fun {txt; _} -> fmt_type_var txt))
3356+
$ fmt ".@ "
3357+
in
3358+
fmt_constructor_arguments c ctx ~pre ~vars:fmt_vars args $ opt res fmt_type
33463359

33473360
and fmt_type_extension ?ext c ctx
33483361
{ ptyext_attributes
@@ -3356,8 +3369,8 @@ and fmt_type_extension ?ext c ctx
33563369
let fmt_ctor ctor =
33573370
let sep =
33583371
match ctor.pext_kind with
3359-
| Pext_decl (_, Some _) -> fmt " :@ "
3360-
| Pext_decl (_, None) | Pext_rebind _ -> fmt " of@ "
3372+
| Pext_decl (_, _, Some _) -> fmt " :@ "
3373+
| Pext_decl (_, _, None) | Pext_rebind _ -> fmt " of@ "
33613374
in
33623375
hvbox 0 (fmt_extension_constructor c sep ctx ctor)
33633376
in
@@ -3406,20 +3419,20 @@ and fmt_extension_constructor c sep ctx ec =
34063419
let doc, atrs = doc_atrs pext_attributes in
34073420
let suf =
34083421
match pext_kind with
3409-
| Pext_decl (_, None) | Pext_rebind _ -> None
3410-
| Pext_decl (_, Some _) -> Some " "
3422+
| Pext_decl (_, _, None) | Pext_rebind _ -> None
3423+
| Pext_decl (_, _, Some _) -> Some " "
34113424
in
34123425
Cmts.fmt c pext_loc
34133426
@@ hvbox 4
34143427
( hvbox 2
34153428
( fmt_str_loc c pext_name
34163429
$
34173430
match pext_kind with
3418-
| Pext_decl ((Pcstr_tuple [] | Pcstr_record []), None) -> noop
3419-
| Pext_decl ((Pcstr_tuple [] | Pcstr_record []), Some res) ->
3431+
| Pext_decl (_, (Pcstr_tuple [] | Pcstr_record []), None) -> noop
3432+
| Pext_decl (_, (Pcstr_tuple [] | Pcstr_record []), Some res) ->
34203433
sep $ fmt_core_type c (sub_typ ~ctx res)
3421-
| Pext_decl (args, res) ->
3422-
fmt_constructor_arguments_result c ctx args res
3434+
| Pext_decl (vars, args, res) ->
3435+
fmt_constructor_arguments_result c ctx vars args res
34233436
| Pext_rebind lid -> str " = " $ fmt_longident_loc c lid )
34243437
$ fmt_attributes c ~pre:(Break (1, 0)) ~key:"@" atrs ?suf
34253438
$ fmt_docstring_padded c doc )

test/passing/dune.inc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,18 @@
155155
(package ocamlformat)
156156
(action (diff tests/attributes.mli.ref attributes.mli.output)))
157157

158+
(rule
159+
(deps tests/.ocamlformat )
160+
(package ocamlformat)
161+
(action
162+
(with-outputs-to binders.ml.output
163+
(run %{bin:ocamlformat} %{dep:tests/binders.ml}))))
164+
165+
(rule
166+
(alias runtest)
167+
(package ocamlformat)
168+
(action (diff tests/binders.ml binders.ml.output)))
169+
158170
(rule
159171
(deps tests/.ocamlformat )
160172
(package ocamlformat)

test/passing/tests/binders.ml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
external f : 'a -> 'a = "asdf"
2+
3+
external g :
4+
'aaaaaaa 'aaaaaaaaaaaaaaa 'aaaaaaaaaaaaaaaaaaaaaa 'aaaaaaaaaaaaaa 'aaaaaaa
5+
'fooooo_foooooo. 'a -> 'a -> 'a = "asdf"
6+
7+
type f = Foo : 'a -> t
8+
9+
type f = Foo : 'a -> 'a
10+
11+
type g = Foo : 'a. 'a -> t
12+
13+
type g =
14+
| Foo :
15+
'aaaaaaaaaaa 'bbbbbbbbbbbbbb 'ccccccccccccccc 'fooooo_fooooooo.
16+
'foo
17+
-> 'b

vendor/ocaml-4.13/ast_helper.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,9 +531,10 @@ module Type = struct
531531
}
532532

533533
let constructor ?(loc = !default_loc) ?(attrs = []) ?(info = empty_info)
534-
?(args = Pcstr_tuple []) ?res name =
534+
?(vars = []) ?(args = Pcstr_tuple []) ?res name =
535535
{
536536
pcd_name = name;
537+
pcd_vars = vars;
537538
pcd_args = args;
538539
pcd_res = res;
539540
pcd_loc = loc;
@@ -583,10 +584,10 @@ module Te = struct
583584
}
584585

585586
let decl ?(loc = !default_loc) ?(attrs = []) ?(docs = empty_docs)
586-
?(info = empty_info) ?(args = Pcstr_tuple []) ?res name =
587+
?(info = empty_info) ?(vars = []) ?(args = Pcstr_tuple []) ?res name =
587588
{
588589
pext_name = name;
589-
pext_kind = Pext_decl(args, res);
590+
pext_kind = Pext_decl(vars, args, res);
590591
pext_loc = loc;
591592
pext_attributes = add_docs_attrs docs (add_info_attrs info attrs);
592593
}

vendor/ocaml-4.13/ast_helper.mli

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ module Type:
212212
type_declaration
213213

214214
val constructor: ?loc:loc -> ?attrs:attrs -> ?info:info ->
215-
?args:constructor_arguments -> ?res:core_type -> str ->
215+
?vars:str list -> ?args:constructor_arguments -> ?res:core_type ->
216+
str ->
216217
constructor_declaration
217218
val field: ?loc:loc -> ?attrs:attrs -> ?info:info ->
218219
?mut:mutable_flag -> str -> core_type -> label_declaration
@@ -232,7 +233,8 @@ module Te:
232233
str -> extension_constructor_kind -> extension_constructor
233234

234235
val decl: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?info:info ->
235-
?args:constructor_arguments -> ?res:core_type -> str ->
236+
?vars:str list -> ?args:constructor_arguments -> ?res:core_type ->
237+
str ->
236238
extension_constructor
237239
val rebind: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?info:info ->
238240
str -> lid -> extension_constructor

vendor/ocaml-4.13/ast_mapper.ml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,10 @@ module T = struct
206206
(sub.extension_constructor sub ptyexn_constructor)
207207

208208
let map_extension_constructor_kind sub = function
209-
Pext_decl(ctl, cto) ->
210-
Pext_decl(map_constructor_arguments sub ctl, map_opt (sub.typ sub) cto)
209+
Pext_decl(vars, ctl, cto) ->
210+
Pext_decl(List.map (map_loc sub) vars,
211+
map_constructor_arguments sub ctl,
212+
map_opt (sub.typ sub) cto)
211213
| Pext_rebind li ->
212214
Pext_rebind (map_loc sub li)
213215

@@ -701,9 +703,11 @@ let default_mapper =
701703

702704

703705
constructor_declaration =
704-
(fun this {pcd_name; pcd_args; pcd_res; pcd_loc; pcd_attributes} ->
706+
(fun this {pcd_name; pcd_vars; pcd_args;
707+
pcd_res; pcd_loc; pcd_attributes} ->
705708
Type.constructor
706709
(map_loc this pcd_name)
710+
~vars:(List.map (map_loc this) pcd_vars)
707711
~args:(T.map_constructor_arguments this pcd_args)
708712
?res:(map_opt (this.typ this) pcd_res)
709713
~loc:(this.location this pcd_loc)

vendor/ocaml-4.13/parser.mly

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,15 +2506,11 @@ let_binding_body_no_punning:
25062506
let patloc = ($startpos($1), $endpos($2)) in
25072507
(ghpat ~loc:patloc (Ppat_constraint(v, typ)),
25082508
mkexp_constraint ~loc:$sloc $4 $2) }
2509-
| let_ident COLON typevar_list DOT core_type EQUAL seq_expr
2510-
(* TODO: could replace [typevar_list DOT core_type]
2511-
with [mktyp(poly(core_type))]
2512-
and simplify the semantic action? *)
2513-
{ let typloc = ($startpos($3), $endpos($5)) in
2514-
let patloc = ($startpos($1), $endpos($5)) in
2509+
| let_ident COLON poly(core_type) EQUAL seq_expr
2510+
{ let patloc = ($startpos($1), $endpos($3)) in
25152511
(ghpat ~loc:patloc
2516-
(Ppat_constraint($1, ghtyp ~loc:typloc (Ptyp_poly($3,$5)))),
2517-
$7) }
2512+
(Ppat_constraint($1, ghtyp ~loc:($loc($3)) $3)),
2513+
$5) }
25182514
| let_ident COLON TYPE lident_list DOT core_type EQUAL seq_expr
25192515
{ let exp, poly =
25202516
wrap_type_annotation ~loc:$sloc $4 $6 $8 in
@@ -2877,7 +2873,7 @@ value_description:
28772873
attrs1 = attributes
28782874
id = mkrhs(val_ident)
28792875
COLON
2880-
ty = core_type
2876+
ty = possibly_poly(core_type)
28812877
attrs2 = post_item_attributes
28822878
{ let attrs = attrs1 @ attrs2 in
28832879
let loc = make_loc $sloc in
@@ -2894,7 +2890,7 @@ primitive_declaration:
28942890
attrs1 = attributes
28952891
id = mkrhs(val_ident)
28962892
COLON
2897-
ty = core_type
2893+
ty = possibly_poly(core_type)
28982894
EQUAL
28992895
prim = raw_string+
29002896
attrs2 = post_item_attributes
@@ -3072,20 +3068,20 @@ constructor_declarations:
30723068
generic_constructor_declaration(opening):
30733069
opening
30743070
cid = mkrhs(constr_ident)
3075-
args_res = generalized_constructor_arguments
3071+
vars_args_res = generalized_constructor_arguments
30763072
attrs = attributes
30773073
{
3078-
let args, res = args_res in
3074+
let vars, args, res = vars_args_res in
30793075
let info = symbol_info $endpos in
30803076
let loc = make_loc $sloc in
3081-
cid, args, res, attrs, loc, info
3077+
cid, vars, args, res, attrs, loc, info
30823078
}
30833079
;
30843080
%inline constructor_declaration(opening):
30853081
d = generic_constructor_declaration(opening)
30863082
{
3087-
let cid, args, res, attrs, loc, info = d in
3088-
Type.constructor cid ~args ?res ~attrs ~loc ~info
3083+
let cid, vars, args, res, attrs, loc, info = d in
3084+
Type.constructor cid ~vars ~args ?res ~attrs ~loc ~info
30893085
}
30903086
;
30913087
str_exception_declaration:
@@ -3110,28 +3106,33 @@ sig_exception_declaration:
31103106
ext = ext
31113107
attrs1 = attributes
31123108
id = mkrhs(constr_ident)
3113-
args_res = generalized_constructor_arguments
3109+
vars_args_res = generalized_constructor_arguments
31143110
attrs2 = attributes
31153111
attrs = post_item_attributes
3116-
{ let args, res = args_res in
3112+
{ let vars, args, res = vars_args_res in
31173113
let loc = make_loc ($startpos, $endpos(attrs2)) in
31183114
let docs = symbol_docs $sloc in
31193115
Te.mk_exception ~attrs
3120-
(Te.decl id ~args ?res ~attrs:(attrs1 @ attrs2) ~loc ~docs)
3116+
(Te.decl id ~vars ~args ?res ~attrs:(attrs1 @ attrs2) ~loc ~docs)
31213117
, ext }
31223118
;
31233119
%inline let_exception_declaration:
31243120
mkrhs(constr_ident) generalized_constructor_arguments attributes
3125-
{ let args, res = $2 in
3126-
Te.decl $1 ~args ?res ~attrs:$3 ~loc:(make_loc $sloc) }
3121+
{ let vars, args, res = $2 in
3122+
Te.decl $1 ~vars ~args ?res ~attrs:$3 ~loc:(make_loc $sloc) }
31273123
;
31283124
generalized_constructor_arguments:
3129-
/*empty*/ { (Pcstr_tuple [],None) }
3130-
| OF constructor_arguments { ($2,None) }
3125+
/*empty*/ { ([],Pcstr_tuple [],None) }
3126+
| OF constructor_arguments { ([],$2,None) }
31313127
| COLON constructor_arguments MINUSGREATER atomic_type %prec below_HASH
3132-
{ ($2,Some $4) }
3128+
{ ([],$2,Some $4) }
3129+
| COLON typevar_list DOT constructor_arguments MINUSGREATER atomic_type
3130+
%prec below_HASH
3131+
{ ($2,$4,Some $6) }
31333132
| COLON atomic_type %prec below_HASH
3134-
{ (Pcstr_tuple [],Some $2) }
3133+
{ ([],Pcstr_tuple [],Some $2) }
3134+
| COLON typevar_list DOT atomic_type %prec below_HASH
3135+
{ ($2,Pcstr_tuple [],Some $4) }
31353136
;
31363137

31373138
constructor_arguments:
@@ -3196,8 +3197,8 @@ label_declaration_semi:
31963197
%inline extension_constructor_declaration(opening):
31973198
d = generic_constructor_declaration(opening)
31983199
{
3199-
let cid, args, res, attrs, loc, info = d in
3200-
Te.decl cid ~args ?res ~attrs ~loc ~info
3200+
let cid, vars, args, res, attrs, loc, info = d in
3201+
Te.decl cid ~vars ~args ?res ~attrs ~loc ~info
32013202
}
32023203
;
32033204
extension_constructor_rebind(opening):

0 commit comments

Comments
 (0)