Skip to content

Commit 69e6ee4

Browse files
authored
5.5 support: Modular explicits (#2781)
Backport modular explicits syntax. The test code is taken from the compiler's testsuite. * Factorize the formatting of package types This removes code with seamingly no regressions.
1 parent 5582edd commit 69e6ee4

40 files changed

Lines changed: 4922 additions & 49 deletions

CHANGES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ profile. This started with version 0.26.0.
88

99
### Highlight
1010

11-
- \* Support OCaml 5.5 syntax (#2772, #2774, #2775, #2777, #2780, @Julow)
11+
- \* Support OCaml 5.5 syntax (#2772, #2774, #2775, #2777, #2780, #2781, @Julow)
1212
The update brings several tiny changes, they are listed below.
1313

1414
- \* Update Odoc's parser to 3.0 (#2757, @Julow)

lib/Ast.ml

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ end = struct
966966
| Pconstraint t -> f t
967967
| Pcoerce (t1, t2) -> Option.exists t1 ~f || f t2
968968
in
969+
let check_package_type ptyp = List.exists ptyp.ppt_cstrs ~f:snd_f in
969970
match ctx with
970971
| Pld (PTyp t1) -> assert (typ == t1)
971972
| Pld _ -> assert false
@@ -985,13 +986,15 @@ end = struct
985986
| {prf_desc= Rtag (_, _, t1N); _} -> List.exists t1N ~f
986987
| {prf_desc= Rinherit t1; _} -> typ == t1 ) )
987988
| Ptyp_open (_, t1) -> assert (t1 == typ)
988-
| Ptyp_package ptyp -> assert (List.exists ptyp.ppt_cstrs ~f:snd_f)
989+
| Ptyp_package ptyp -> assert (check_package_type ptyp)
989990
| Ptyp_object (fields, _) ->
990991
assert (
991992
List.exists fields ~f:(function
992993
| {pof_desc= Otag (_, t1); _} -> typ == t1
993994
| {pof_desc= Oinherit t1; _} -> typ == t1 ) )
994-
| Ptyp_class (_, l) -> assert (List.exists l ~f) )
995+
| Ptyp_class (_, l) -> assert (List.exists l ~f)
996+
| Ptyp_functor (_, _, ptyp, rhs) ->
997+
assert (rhs == typ || check_package_type ptyp) )
995998
| Td {ptype_params; ptype_cstrs; ptype_kind; ptype_manifest; _} ->
996999
assert (
9971000
List.exists ptype_params ~f:fst_f
@@ -1018,8 +1021,7 @@ end = struct
10181021
match ctx.ppat_desc with
10191022
| Ppat_constraint (_, t1) -> assert (typ == t1)
10201023
| Ppat_extension (_, PTyp t) -> assert (typ == t)
1021-
| Ppat_unpack (_, Some ptyp) ->
1022-
assert (List.exists ptyp.ppt_cstrs ~f:(fun (_, t) -> typ == t))
1024+
| Ppat_unpack (_, Some ptyp) -> assert (check_package_type ptyp)
10231025
| Ppat_record (l, _) ->
10241026
assert (List.exists l ~f:(fun (_, t, _) -> Option.exists t ~f))
10251027
| Ppat_tuple (l, _) ->
@@ -1030,8 +1032,7 @@ end = struct
10301032
| _ -> assert false )
10311033
| Exp ctx -> (
10321034
match ctx.pexp_desc with
1033-
| Pexp_pack (_, Some ptyp, _) ->
1034-
assert (List.exists ptyp.ppt_cstrs ~f:snd_f)
1035+
| Pexp_pack (_, Some ptyp, _) -> assert (check_package_type ptyp)
10351036
| Pexp_constraint (_, t1)
10361037
|Pexp_coerce (_, None, t1)
10371038
|Pexp_extension (_, PTyp t1) ->
@@ -1079,8 +1080,9 @@ end = struct
10791080
| Mod ctx -> (
10801081
match ctx.pmod_desc with
10811082
| Pmod_unpack (_, ty1, ty2) ->
1082-
let f ptyp = List.exists ptyp.ppt_cstrs ~f:snd_f in
1083-
assert (Option.exists ty1 ~f || Option.exists ty2 ~f)
1083+
assert (
1084+
Option.exists ty1 ~f:check_package_type
1085+
|| Option.exists ty2 ~f:check_package_type )
10841086
| _ -> assert false )
10851087
| Sig ctx -> (
10861088
match ctx.psig_desc with
@@ -1583,16 +1585,18 @@ end = struct
15831585
| _ -> false
15841586
in
15851587
let constructor_cxt_prec_of_inner = function
1586-
| {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _; _} -> Some (Apply, Non)
1588+
| {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _; _} ->
1589+
Some (Apply, Non)
15871590
| {ptyp_desc= Ptyp_tuple _; _} -> Some (InfixOp3, Non)
15881591
| _ -> None
15891592
in
15901593
match ctx with
15911594
| { ctx= Td {ptype_kind= Ptype_variant v; _}
15921595
; ast=
15931596
Typ
1594-
({ptyp_desc= Ptyp_arrow _ | Ptyp_poly _ | Ptyp_tuple _; _} as typ)
1595-
}
1597+
( { ptyp_desc=
1598+
Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _ | Ptyp_tuple _
1599+
; _ } as typ ) }
15961600
when List.exists v ~f:(is_tuple_lvl1_in_constructor typ) ->
15971601
constructor_cxt_prec_of_inner typ
15981602
| { ctx=
@@ -1601,7 +1605,9 @@ end = struct
16011605
| Sig {psig_desc= Psig_typext {ptyext_constructors= l; _}; _} )
16021606
; ast=
16031607
Typ
1604-
({ptyp_desc= Ptyp_arrow _ | Ptyp_poly _ | Ptyp_tuple _; _} as typ)
1608+
( { ptyp_desc=
1609+
Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _ | Ptyp_tuple _
1610+
; _ } as typ )
16051611
; _ }
16061612
when List.exists l ~f:(is_tuple_lvl1_in_ext_constructor typ) ->
16071613
constructor_cxt_prec_of_inner typ
@@ -1621,8 +1627,9 @@ end = struct
16211627
; _ } )
16221628
; ast=
16231629
Typ
1624-
({ptyp_desc= Ptyp_tuple _ | Ptyp_arrow _ | Ptyp_poly _; _} as typ)
1625-
}
1630+
( { ptyp_desc=
1631+
Ptyp_tuple _ | Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _
1632+
; _ } as typ ) }
16261633
when is_tuple_lvl1_in_ext_constructor typ constr ->
16271634
constructor_cxt_prec_of_inner typ
16281635
| {ctx= Str _ | Str_exp _; ast= Typ _; _} -> None
@@ -1634,7 +1641,7 @@ end = struct
16341641
else Right
16351642
in
16361643
Some (MinusGreater, assoc)
1637-
| Ptyp_poly _ -> Some (MinusGreater, Right)
1644+
| Ptyp_poly _ | Ptyp_functor _ -> Some (MinusGreater, Right)
16381645
| Ptyp_tuple _ -> Some (InfixOp3, Non)
16391646
| Ptyp_alias _ -> Some (As, Non)
16401647
| Ptyp_constr (_, _ :: _ :: _) -> Some (Comma, Non)
@@ -1770,7 +1777,7 @@ end = struct
17701777
| Typ {ptyp_desc; _} -> (
17711778
match ptyp_desc with
17721779
| Ptyp_package _ -> Some Low
1773-
| Ptyp_arrow _ | Ptyp_poly _ -> Some MinusGreater
1780+
| Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _ -> Some MinusGreater
17741781
| Ptyp_tuple _ -> Some InfixOp3
17751782
| Ptyp_alias _ -> Some As
17761783
| Ptyp_any | Ptyp_var _ | Ptyp_constr _ | Ptyp_object _
@@ -1869,7 +1876,10 @@ end = struct
18691876
match xtyp with
18701877
| {ast= {ptyp_desc= Ptyp_package _; _}; _} -> true
18711878
| {ast= {ptyp_desc= Ptyp_alias _; _}; ctx= Typ _} -> true
1872-
| { ast= {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _ | Ptyp_tuple _; _}
1879+
| { ast=
1880+
{ ptyp_desc=
1881+
Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _ | Ptyp_tuple _
1882+
; _ }
18731883
; ctx= Typ {ptyp_desc= Ptyp_class _; _} } ->
18741884
true
18751885
| { ast= {ptyp_desc= Ptyp_alias _; _}
@@ -1887,15 +1897,17 @@ end = struct
18871897
true
18881898
| { ast=
18891899
{ ptyp_desc=
1890-
Ptyp_alias _ | Ptyp_arrow _ | Ptyp_poly _ | Ptyp_tuple _
1900+
( Ptyp_alias _ | Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _
1901+
| Ptyp_tuple _ )
18911902
; _ }
18921903
; ctx=
18931904
( Str {pstr_desc= Pstr_exception _; _}
18941905
| Str_exp {pstr_desc= Pstr_exception _; _}
18951906
| Sig {psig_desc= Psig_exception _; _} ) } ->
18961907
true
18971908
| { ast= {ptyp_desc= Ptyp_tuple ({lte_label= Some _; _} :: _); _}
1898-
; ctx= Typ {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _; _} } ->
1909+
; ctx= Typ {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _; _}
1910+
} ->
18991911
true
19001912
| _ -> (
19011913
match ambig_prec (sub_ast ~ctx (Typ typ)) with

lib/Fmt_ast.ml

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ let fmt_extension_suffix ?epi c ext =
547547
opt ext (fun name -> str "%" $ fmt_str_loc c name $ fmt_opt epi)
548548

549549
let is_arrow_or_poly = function
550-
| {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _; _} -> true
550+
| {ptyp_desc= Ptyp_arrow _ | Ptyp_poly _ | Ptyp_functor _; _} -> true
551551
| _ -> false
552552

553553
let fmt_assign_arrow c =
@@ -938,13 +938,9 @@ and fmt_core_type c ?(box = true) ?pro ?(pro_space = true) ?constraint_ctx
938938
$ space_break $ fmt_longident_loc c lid )
939939
| Ptyp_extension ext ->
940940
hvbox c.conf.fmt_opts.extension_indent.v (fmt_extension c ctx ext)
941-
| Ptyp_package {ppt_path= id; ppt_cstrs= cnstrs; ppt_attrs= attrs; ppt_loc}
942-
->
943-
Cmts.fmt c ppt_loc
944-
@@ hvbox 2
945-
( hovbox 0 (str "module" $ space_break $ fmt_longident_loc c id)
946-
$ fmt_package_type c ctx cnstrs
947-
$ fmt_attributes c attrs )
941+
| Ptyp_package ptyp ->
942+
let pro = str "module" $ space_break in
943+
fmt_package_type c ctx ~parens:false ~pro ptyp
948944
| Ptyp_open (lid, typ) ->
949945
hvbox 2
950946
( hvbox 0 (fmt_longident_loc c lid $ str ".(")
@@ -1074,8 +1070,25 @@ and fmt_core_type c ?(box = true) ?pro ?(pro_space = true) ?constraint_ctx
10741070
(sub_typ ~ctx >> fmt_core_type c) )
10751071
$ space_break
10761072
$ fmt_longident_loc c ~pre:"#" lid
1073+
| Ptyp_functor (lbl, lid, ptyp, rhs) ->
1074+
let fmt_lbl =
1075+
match lbl with
1076+
| Nolabel -> noop
1077+
| Labelled l -> fmt_str_loc c l $ str ":" $ cut_break
1078+
| Optional _ -> assert false (* Not produced by the parser *)
1079+
in
1080+
hovbox_if box 0
1081+
( (let pro =
1082+
hvbox 2
1083+
( fmt_lbl $ str "(" $ str "module" $ space_break
1084+
$ fmt_str_loc c lid $ str " :" )
1085+
$ break 1 2
1086+
in
1087+
fmt_package_type c ctx ~parens:false ~pro ptyp $ str ")" )
1088+
$ arrow_sep c ~parens
1089+
$ fmt_core_type c ~pro_space:false (sub_typ ~ctx rhs) )
10771090

1078-
and fmt_package_type c ctx cnstrs =
1091+
and fmt_package_type_cnstrs c ctx cnstrs =
10791092
let fmt_cstr ~first ~last:_ (lid, typ) =
10801093
fmt_or first (break 1 0) (break 1 1)
10811094
$ hvbox 2
@@ -1085,6 +1098,15 @@ and fmt_package_type c ctx cnstrs =
10851098
in
10861099
list_fl cnstrs fmt_cstr
10871100

1101+
and fmt_package_type c ctx ~parens ~pro ptyp =
1102+
let {ppt_path; ppt_cstrs; ppt_attrs; ppt_loc} = ptyp in
1103+
Cmts.fmt c ppt_loc
1104+
(hvbox 2
1105+
(Params.parens_if parens c.conf
1106+
( hovbox 0 (pro $ fmt_longident_loc c ppt_path)
1107+
$ fmt_package_type_cnstrs c ctx ppt_cstrs
1108+
$ fmt_attributes c ppt_attrs ) ) )
1109+
10881110
and fmt_row_field c ctx {prf_desc; prf_attributes; prf_loc} =
10891111
let c = update_config c prf_attributes in
10901112
let row =
@@ -1354,17 +1376,9 @@ and fmt_pattern ?ext c ?pro ?parens ?(box = false)
13541376
| Ppat_unpack (name, pt) ->
13551377
let fmt_constraint_opt pt k =
13561378
match pt with
1357-
| Some {ppt_path= id; ppt_cstrs= cnstrs; ppt_attrs= attrs; ppt_loc}
1358-
->
1359-
Cmts.fmt c ppt_loc
1360-
@@ hovbox 0
1361-
(Params.parens_if parens c.conf
1362-
(hvbox 1
1363-
( hovbox 0
1364-
( k $ space_break $ str ": "
1365-
$ fmt_longident_loc c id )
1366-
$ fmt_package_type c ctx cnstrs
1367-
$ fmt_attributes c attrs ) ) )
1379+
| Some pt ->
1380+
let pro = k $ space_break $ str ": " in
1381+
fmt_package_type c ctx ~parens ~pro pt
13681382
| None -> wrap_fits_breaks_if ~space:false c.conf parens "(" ")" k
13691383
in
13701384
fmt_constraint_opt pt
@@ -2725,14 +2739,9 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens
27252739
and epi = cls_paren in
27262740
let fmt_mod m =
27272741
match pt with
2728-
| Some {ppt_path= id; ppt_cstrs= cnstrs; ppt_attrs= attrs; ppt_loc}
2729-
->
2730-
Cmts.fmt c ppt_loc
2731-
@@ hvbox 2
2732-
( hovbox 0
2733-
(m $ space_break $ str ": " $ fmt_longident_loc c id)
2734-
$ fmt_package_type c ctx cnstrs
2735-
$ fmt_attributes c attrs )
2742+
| Some pt ->
2743+
let pro = m $ space_break $ str ": " in
2744+
fmt_package_type c ctx ~parens:false ~pro pt
27362745
| None -> m
27372746
in
27382747
outer_pro
@@ -4541,12 +4550,13 @@ and fmt_module_expr ?(dock_struct = true) c ({ast= m; ctx= ctx0} as xmod) =
45414550
| Pmod_unpack (e, ty1, ty2) ->
45424551
let package_type sep
45434552
{ppt_path= lid; ppt_cstrs= cstrs; ppt_attrs= attrs; ppt_loc} =
4553+
(* TODO: Use [fmt_package_type]. *)
45444554
break 1 (Params.Indent.mod_unpack_annot c.conf)
45454555
$ hovbox 0
45464556
( hovbox 0
45474557
( str sep $ Cmts.fmt_before c ppt_loc
45484558
$ fmt_longident_loc c lid )
4549-
$ fmt_package_type c ctx cstrs
4559+
$ fmt_package_type_cnstrs c ctx cstrs
45504560
$ fmt_attributes c attrs $ Cmts.fmt_after c ppt_loc )
45514561
in
45524562
{ empty with

test/passing/gen/dune.inc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4032,6 +4032,24 @@
40324032
(package ocamlformat)
40334033
(action (diff mod_type_subst.ml.err mod_type_subst.ml.stderr)))
40344034

4035+
(rule
4036+
(deps .ocamlformat)
4037+
(package ocamlformat)
4038+
(action
4039+
(with-stdout-to modular_explicits.ml.stdout
4040+
(with-stderr-to modular_explicits.ml.stderr
4041+
(run %{bin:ocamlformat} --name modular_explicits.ml --margin-check %{dep:../tests/modular_explicits.ml})))))
4042+
4043+
(rule
4044+
(alias runtest)
4045+
(package ocamlformat)
4046+
(action (diff modular_explicits.ml.ref modular_explicits.ml.stdout)))
4047+
4048+
(rule
4049+
(alias runtest)
4050+
(package ocamlformat)
4051+
(action (diff modular_explicits.ml.err modular_explicits.ml.stderr)))
4052+
40354053
(rule
40364054
(deps .ocamlformat)
40374055
(package ocamlformat)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Warning: break_colon-before.ml:116 exceeds the margin

test/passing/refs.ahrefs/break_colon-before.ml.ref

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,28 @@ let to_clambda_function (id, (function_decl : Flambda.function_declaration))
9292
closed set of closures, is the substitutions for variables bound to the
9393
various closures in the set. Such closures will always be ... *)
9494
x
95+
96+
let f
97+
: (module M : S
98+
with type foo = foooooooooooooooooooooooooooooooooooooo
99+
and type foo = foooooooooooooooooooooooooooooooooooooo) -> fooo =
100+
f
101+
102+
let f
103+
: fooooooooooooooooooooooooooooooooooooo ->
104+
(module M : S
105+
with type foo = foooooooooooooooooooooooooooooooooooooo
106+
and type foo = foooooooooooooooooooooooooooooooooooooo) -> fooo =
107+
f
108+
109+
let f
110+
: fooooooooooooooooooooooooooooooooooooo ->
111+
(module Foooooooooooooooooooooooooooooooooooooo :
112+
Foooooooooooooooooooooooooooooooooooooo) -> fooo =
113+
f
114+
115+
let f
116+
: (module
117+
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo :
118+
S) -> fooo =
119+
f
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Warning: break_colon.ml:116 exceeds the margin

test/passing/refs.ahrefs/break_colon.ml.ref

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,28 @@ let to_clambda_function (id, (function_decl : Flambda.function_declaration)) :
9292
closed set of closures, is the substitutions for variables bound to the
9393
various closures in the set. Such closures will always be ... *)
9494
x
95+
96+
let f :
97+
(module M : S
98+
with type foo = foooooooooooooooooooooooooooooooooooooo
99+
and type foo = foooooooooooooooooooooooooooooooooooooo) -> fooo =
100+
f
101+
102+
let f :
103+
fooooooooooooooooooooooooooooooooooooo ->
104+
(module M : S
105+
with type foo = foooooooooooooooooooooooooooooooooooooo
106+
and type foo = foooooooooooooooooooooooooooooooooooooo) -> fooo =
107+
f
108+
109+
let f :
110+
fooooooooooooooooooooooooooooooooooooo ->
111+
(module Foooooooooooooooooooooooooooooooooooooo :
112+
Foooooooooooooooooooooooooooooooooooooo) -> fooo =
113+
f
114+
115+
let f :
116+
(module
117+
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo :
118+
S) -> fooo =
119+
f

test/passing/refs.ahrefs/first_class_module.ml.ref

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,21 @@ let _ =
135135
let module MS = struct module type S = sig end end in
136136
(fun _ -> ()) (fun (module M1 : MS.S) ((module M2) : (module MS.S)) ->
137137
((module M1) : (module MS.S)), ((module M2) : (module MS.S)))
138+
139+
let f :
140+
(* a *)
141+
(module (* a *) M (* a *) : (* a *) S) ->
142+
(* a *)
143+
(* a *)
144+
fooo =
145+
f
146+
147+
let f :
148+
(* a *)
149+
(module (* a *) Foooooooooooooooooooooooooooooooooooooo (* a *) :
150+
(* a *)
151+
Foooooooooooooooooooooooooooooooooooooo) ->
152+
(* a *)
153+
(* a *)
154+
fooo =
155+
f
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Warning: modular_explicits.ml:753 exceeds the margin

0 commit comments

Comments
 (0)