diff --git a/CHANGES.md b/CHANGES.md index cafd075db0..6cb5bf928b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - Support for OxCaml modalities (@art-w, #1420) - Support OxCaml 5.2.0minus39 (@jonludlam, #1469) - Support for OxCaml modes (@art-w, #1454) +- Fix OxCaml with-bounds for arbitrary types (@art-w, #1466) ### Fixed - Remove requirement for ppx_expect in tests (@jonludlam, #1445) diff --git a/src/loader/cmi.ml b/src/loader/cmi.ml index b0cf333675..5a91f648c4 100644 --- a/src/loader/cmi.ml +++ b/src/loader/cmi.ml @@ -489,22 +489,141 @@ let mark_class_declaration cld = mark_class_type cld.cty_params cld.cty_type #if defined OXCAML -let read_parsetree_core_type (ct : Parsetree.core_type) = +let rec read_longident_module (l : Longident.t) : Paths.Path.Module.t = + match l with + | Longident.Lident s -> `Root (ModuleName.make_std s) + | Longident.Ldot (p, s) -> `Dot (read_longident_module p, ModuleName.make_std s) + | Longident.Lapply (p, arg) -> + `Apply (read_longident_module p, read_longident_module arg) + +let read_longident_type (l : Longident.t) : Paths.Path.Type.t = + match l with + | Longident.Lident s -> `Resolved (`CoreType (TypeName.make_std s)) + | Longident.Ldot (p, s) -> `DotT (read_longident_module p, TypeName.make_std s) + | Longident.Lapply _ -> `Resolved (`CoreType (TypeName.make_std "_")) + +let read_longident_class_type (l : Longident.t) : Paths.Path.ClassType.t = + match l with + | Longident.Ldot (p, s) -> `DotT (read_longident_module p, TypeName.make_std s) + | Longident.Lident s -> + `DotT (`Root (ModuleName.make_std "*"), TypeName.make_std s) + | Longident.Lapply _ -> + `DotT (`Root (ModuleName.make_std "*"), TypeName.make_std "_") + +let read_longident_module_type (l : Longident.t) : Paths.Path.ModuleType.t = + match l with + | Longident.Ldot (p, s) -> + `DotMT (read_longident_module p, ModuleTypeName.make_std s) + | Longident.Lident s -> + `DotMT (`Root (ModuleName.make_std "_"), ModuleTypeName.make_std s) + | Longident.Lapply _ -> + `DotMT (`Root (ModuleName.make_std "_"), ModuleTypeName.make_std "_") + +let read_parsetree_modes (modes : Parsetree.modes) = + List.map (fun (m : Parsetree.mode Location.loc) -> + let (Parsetree.Mode s) = m.txt in s) + modes + +let rec read_parsetree_core_type (ct : Parsetree.core_type) = let open TypeExpr in match ct.ptyp_desc with | Ptyp_var (s, _) -> Var s | Ptyp_any _ -> Any - | _ -> failwith "invalid core type" - -let rec read_jkind_annotation (jk : Parsetree.jkind_annotation) = + | Ptyp_constr (lid, args) -> + Constr (read_longident_type lid.txt, List.map read_parsetree_core_type args) + | Ptyp_class (lid, args) -> + Class + (read_longident_class_type lid.txt, List.map read_parsetree_core_type args) + | Ptyp_tuple ts -> + Tuple (List.map (fun (lbl, t) -> (lbl, read_parsetree_core_type t)) ts) + | Ptyp_unboxed_tuple ts -> + Unboxed_tuple (List.map (fun (lbl, t) -> (lbl, read_parsetree_core_type t)) ts) + | Ptyp_arrow (lbl, arg, res, arg_modes, res_modes) -> + let lbl = + match lbl with + | Asttypes.Nolabel -> None + | Asttypes.Labelled s -> Some (Label s) + | Asttypes.Optional s -> Some (Optional s) + in + Arrow + ( lbl, + (read_parsetree_core_type arg, read_parsetree_modes arg_modes), + (read_parsetree_core_type res, read_parsetree_modes res_modes) ) + | Ptyp_variant (fields, closed, labels) -> + let open TypeExpr.Polymorphic_variant in + let elements = + List.map + (fun (field : Parsetree.row_field) -> + match field.prf_desc with + | Rtag (name, constant, args) -> + Constructor + { + name = name.txt; + constant; + arguments = List.map read_parsetree_core_type args; + doc = + { Odoc_model.Comment.elements = []; warnings_tag = None }; + } + | Rinherit ct -> Type (read_parsetree_core_type ct)) + fields + in + let kind = + match (closed, labels) with + | Asttypes.Open, _ -> Open + | Asttypes.Closed, None -> Fixed + | Asttypes.Closed, Some ls -> Closed ls + in + Polymorphic_variant { kind; elements } + | Ptyp_object (fields, closed) -> + let open TypeExpr.Object in + let fields = + List.map + (fun (field : Parsetree.object_field) -> + match field.pof_desc with + | Otag (name, ct) -> + Method { name = name.txt; type_ = read_parsetree_core_type ct } + | Oinherit ct -> Inherit (read_parsetree_core_type ct)) + fields + in + Object { fields; open_ = (closed = Asttypes.Open) } + | Ptyp_alias (ct, None, _) -> read_parsetree_core_type ct + | Ptyp_alias (ct, Some name, _) -> Alias (read_parsetree_core_type ct, name.txt) + | Ptyp_poly (vars, ct) -> + let vars = + List.map + (fun (name, jk) -> + let kind = + match jk with None -> Kind.Default | Some jk -> read_jkind_annotation jk + in + (name.txt, kind)) + vars + in + Poly (vars, read_parsetree_core_type ct) + | Ptyp_package (lid, substs) -> + let path = read_longident_module_type lid.txt in + let substitutions = + List.map + (fun (frag, ct) -> + (Env.Fragment.read_type frag.txt, read_parsetree_core_type ct)) + substs + in + Package { path; substitutions } + | Ptyp_quote ct -> Quote (read_parsetree_core_type ct) + | Ptyp_splice ct -> Splice (read_parsetree_core_type ct) + (* TODO: no good representation available atm *) + | Ptyp_of_kind _ | Ptyp_repr _ | Ptyp_extension _ -> Any + | Ptyp_open (_, ct) -> read_parsetree_core_type ct + | Ptyp_newlayout (_, ct) -> + (* layout-variable binder; odoc currently ignores the layout vars *) + read_parsetree_core_type ct + +and read_jkind_annotation (jk : Parsetree.jkind_annotation) = let open Kind in match jk.pjka_desc with | Pjk_default -> Default | Pjk_abbreviation (s, _) -> Abbreviation (Env.Fragment.read_type s.txt) | Pjk_mod (jk', modes) -> - let modes = List.map (fun (m : Parsetree.mode Location.loc) -> - let (Parsetree.Mode s) = m.txt in s) modes in - Mod (read_jkind_annotation jk', modes) + Mod (read_jkind_annotation jk', read_parsetree_modes modes) | Pjk_with (jk', cty, modalities) -> let ty = read_parsetree_core_type cty in let modalities = List.map (fun (m : Parsetree.modality Location.loc) -> diff --git a/test/generators/cases/oxcaml.mli b/test/generators/cases/oxcaml.mli index 8b5ccd0938..3947f4e83a 100644 --- a/test/generators/cases/oxcaml.mli +++ b/test/generators/cases/oxcaml.mli @@ -88,6 +88,57 @@ type 'a t_with : immediate with 'a type 'a t_with_modalities : immutable_data with 'a @@ portable contended (** Kind annotation with a [with] constraint and modalities. *) +type ('k, 'cmp) comparator +(** Helper used in the [with] constraints below. *) + +type ('k, 'v, 'cmp) t_with_constr + : immutable_data with 'k with 'v with ('k, 'cmp) comparator +(** A [with] constraint whose right-hand side is a parameterized type + constructor (as found in [base]'s [Map] module). *) + +type 'a t_with_app : immutable_data with 'a list +(** A [with] constraint whose right-hand side applies a type constructor. *) + +type 'a t_with_arrow : immutable_data with ('a -> 'a) +(** A [with] constraint whose right-hand side is an arrow type. *) + +type 'a t_with_arrow_modes : immutable_data with ('a -> 'a @ local) +(** A [with] constraint whose right-hand side is an arrow type carrying a + mode. *) + +type 'a t_with_tuple : immutable_data with ('a * int) +(** A [with] constraint whose right-hand side is a tuple type. *) + +module M_with : sig + type 'a t : immutable_data +end +(** Helper module used in the [with] constraint below. *) + +type 'a t_with_dot : immutable_data with 'a M_with.t +(** A [with] constraint referring to a type through a module path + ([M.t]). *) + +module type Arg_with = sig + type s +end + +module F_with (X : Arg_with) : sig + type 'a t : immutable_data +end +(** Helper functor used in the [with] constraint below. *) + +module X_with : Arg_with + +type 'a t_with_functor : immutable_data with 'a F_with(X_with).t +(** A [with] constraint referring to a type through a functor application + ([F(X).t]). *) + +type 'a t_with_variant : immutable_data with [ `Foo of 'a | `Bar ] +(** A [with] constraint whose right-hand side is a polymorphic variant. *) + +type 'a t_with_object : immutable_data with < foo : 'a > +(** A [with] constraint whose right-hand side is an object type. *) + (** {1 Kind annotations on type aliases} *) type t_alias : immediate = int diff --git a/test/generators/html/Oxcaml-F_with-argument-1-X.html b/test/generators/html/Oxcaml-F_with-argument-1-X.html new file mode 100644 index 0000000000..3a24cab11a --- /dev/null +++ b/test/generators/html/Oxcaml-F_with-argument-1-X.html @@ -0,0 +1,27 @@ + + + X (Oxcaml.F_with.X) + + + + + + + + +
+

Parameter F_with.X

+
+
+
+
+ + type s +
+
+
+ + diff --git a/test/generators/html/Oxcaml-F_with.html b/test/generators/html/Oxcaml-F_with.html new file mode 100644 index 0000000000..0ab541e33b --- /dev/null +++ b/test/generators/html/Oxcaml-F_with.html @@ -0,0 +1,51 @@ + + + F_with (Oxcaml.F_with) + + + + + + + + +
+

Module Oxcaml.F_with

+

Helper functor used in the with constraint below.

+
+
+ +
+
+

Parameters +

+
+
+ + module + X + : Arg_with + +
+
+

Signature

+
+
+ + + type 'a t : + immutable_data + + +
+
+
+ + diff --git a/test/generators/html/Oxcaml-M_with.html b/test/generators/html/Oxcaml-M_with.html new file mode 100644 index 0000000000..0e394cfe34 --- /dev/null +++ b/test/generators/html/Oxcaml-M_with.html @@ -0,0 +1,32 @@ + + + M_with (Oxcaml.M_with) + + + + + + + + +
+

Module Oxcaml.M_with

+

Helper module used in the with constraint below.

+
+
+
+
+ + + type 'a t : + immutable_data + + +
+
+
+ + diff --git a/test/generators/html/Oxcaml-X_with.html b/test/generators/html/Oxcaml-X_with.html new file mode 100644 index 0000000000..5747085624 --- /dev/null +++ b/test/generators/html/Oxcaml-X_with.html @@ -0,0 +1,27 @@ + + + X_with (Oxcaml.X_with) + + + + + + + + +
+

Module Oxcaml.X_with

+
+
+
+
+ + type s +
+
+
+ + diff --git a/test/generators/html/Oxcaml-module-type-Arg_with.html b/test/generators/html/Oxcaml-module-type-Arg_with.html new file mode 100644 index 0000000000..050de3f1a5 --- /dev/null +++ b/test/generators/html/Oxcaml-module-type-Arg_with.html @@ -0,0 +1,27 @@ + + + Arg_with (Oxcaml.Arg_with) + + + + + + + + +
+

Module type Oxcaml.Arg_with

+
+
+
+
+ + type s +
+
+
+ + diff --git a/test/generators/html/Oxcaml.html b/test/generators/html/Oxcaml.html index b4a4a676ee..91cd5aaf5e 100644 --- a/test/generators/html/Oxcaml.html +++ b/test/generators/html/Oxcaml.html @@ -403,6 +403,245 @@

+
+
+ + + type + ('k, 'cmp) comparator + + +
+
+

Helper used in the with constraints below.

+
+
+
+
+ + + type + ('k, 'v, 'cmp) + t_with_constr + : + ( + (immutable_data with + 'k) + with + 'v) + with + + ('k, + 'cmp) + comparator + + + +
+
+

A with constraint whose right-hand side is a + parameterized type constructor (as found in base's + Map module). +

+
+
+
+
+ + + type 'a t_with_app + : immutable_data with + 'a list + + +
+
+

A with constraint whose right-hand side applies + a type constructor. +

+
+
+
+
+ + + type 'a t_with_arrow + : immutable_data with + 'a + -> + 'a + + +
+
+

A with constraint whose right-hand side is an arrow + type. +

+
+
+
+
+ + + type + 'a t_with_arrow_modes : immutable_data + with + 'a + -> + 'a @ local + + +
+
+

A with constraint whose right-hand side is an arrow + type carrying a mode. +

+
+
+
+
+ + + type 'a t_with_tuple + : immutable_data with + 'a * int + + +
+
+

A with constraint whose right-hand side is a tuple type. +

+
+
+
+
+ + + module + M_with + + : sig ... + end + + +
+
+

Helper module used in the with constraint below.

+
+
+
+
+ + + type 'a t_with_dot + : immutable_data with + 'a + M_with.t + + + +
+
+

A with constraint referring to a type through a + module path (M.t). +

+
+
+
+
+ + + module + type + Arg_with + + = sig ... + end + + +
+
+
+
+ + + module + F_with + + (X : + Arg_with) : + sig ... end + + +
+
+

Helper functor used in the with constraint below.

+
+
+
+
+ + + module + X_with + + : Arg_with + +
+
+
+
+ + + type 'a t_with_functor + : immutable_data with + 'a + F_with( + X_with).t + + + +
+
+

A with constraint referring to a type through a + functor application (F(X).t). +

+
+
+
+
+ + + type 'a t_with_variant + : immutable_data with + [ `Foo of 'a + | `Bar ] + + + +
+
+

A with constraint whose right-hand side is a polymorphic + variant. +

+
+
+
+
+ + + type 'a t_with_object + : immutable_data with + < foo : 'a > + + +
+
+

A with constraint whose right-hand side is an object + type. +

+
+

Kind annotations on type aliases diff --git a/test/generators/html/oxcaml.targets b/test/generators/html/oxcaml.targets index 77bc5f1da0..5d69622d32 100644 --- a/test/generators/html/oxcaml.targets +++ b/test/generators/html/oxcaml.targets @@ -1,4 +1,9 @@ Oxcaml.html +Oxcaml-M_with.html +Oxcaml-module-type-Arg_with.html +Oxcaml-F_with.html +Oxcaml-F_with-argument-1-X.html +Oxcaml-X_with.html Oxcaml-module-type-S.html Oxcaml-M1.html Oxcaml-M2.html diff --git a/test/generators/latex/Oxcaml.F_with.tex b/test/generators/latex/Oxcaml.F_with.tex new file mode 100644 index 0000000000..dae8c85542 --- /dev/null +++ b/test/generators/latex/Oxcaml.F_with.tex @@ -0,0 +1,11 @@ +\section{Module \ocamlinlinecode{Oxcaml.\allowbreak{}F\_\allowbreak{}with}}\label{Oxcaml-F_with}% +Helper functor used in the \ocamlinlinecode{with} constraint below. + +\subsection{Parameters\label{Oxcaml-F_with--parameters}}% +\label{Oxcaml-F_with--argument-1-X}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-F_with-argument-1-X]{\ocamlinlinecode{X}}}\label{Oxcaml-F_with-argument-1-X}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Oxcaml-F_with-argument-1-X--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\\ +\subsection{Signature\label{Oxcaml-F_with--signature}}% +\label{Oxcaml-F_with--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t : immutable\_\allowbreak{}data}\\ + + diff --git a/test/generators/latex/Oxcaml.X_with.tex b/test/generators/latex/Oxcaml.X_with.tex new file mode 100644 index 0000000000..1421d27a13 --- /dev/null +++ b/test/generators/latex/Oxcaml.X_with.tex @@ -0,0 +1,4 @@ +\section{Module \ocamlinlinecode{Oxcaml.\allowbreak{}X\_\allowbreak{}with}}\label{Oxcaml-X_with}% +\label{Oxcaml-X_with--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s}\\ + + diff --git a/test/generators/latex/Oxcaml.tex b/test/generators/latex/Oxcaml.tex index e3b29d5158..2fd47c8b7f 100644 --- a/test/generators/latex/Oxcaml.tex +++ b/test/generators/latex/Oxcaml.tex @@ -68,6 +68,37 @@ \subsection{Kind annotations with \ocamlinlinecode{with} constraints\label{Oxcam \medbreak \label{Oxcaml--type-t_with_modalities}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}modalities : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} @@ portable contended}\begin{ocamlindent}Kind annotation with a \ocamlinlinecode{with} constraint and modalities.\end{ocamlindent}% \medbreak +\label{Oxcaml--type-comparator}\ocamlcodefragment{\ocamltag{keyword}{type} ('k,\allowbreak{} 'cmp) comparator}\begin{ocamlindent}Helper used in the \ocamlinlinecode{with} constraints below.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_constr}\ocamlcodefragment{\ocamltag{keyword}{type} ('k,\allowbreak{} 'v,\allowbreak{} 'cmp) + t\_\allowbreak{}with\_\allowbreak{}constr : ((immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'k}) \ocamltag{keyword}{with} \ocamltag{type-var}{'v}) \ocamltag{keyword}{with} (\ocamltag{type-var}{'k},\allowbreak{} \ocamltag{type-var}{'cmp}) comparator}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side is a parameterized type constructor (as found in \ocamlinlinecode{base}'s \ocamlinlinecode{Map} module).\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_app}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}app : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} list}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side applies a type constructor.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_arrow}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}arrow : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side is an arrow type.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_arrow_modes}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}arrow\_\allowbreak{}modes : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a} @ local}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side is an arrow type carrying a mode.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_tuple}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}tuple : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} * int}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side is a tuple type.\end{ocamlindent}% +\medbreak +\label{Oxcaml--module-M_with}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-M_with]{\ocamlinlinecode{M\_\allowbreak{}with}}}\label{Oxcaml-M_with}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Oxcaml-M_with--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t : immutable\_\allowbreak{}data}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\begin{ocamlindent}Helper module used in the \ocamlinlinecode{with} constraint below.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_dot}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}dot : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} \hyperref[xref-unresolved]{\ocamlinlinecode{M\_\allowbreak{}with}}.\allowbreak{}t}\begin{ocamlindent}A \ocamlinlinecode{with} constraint referring to a type through a module path (\ocamlinlinecode{M.\allowbreak{}t}).\end{ocamlindent}% +\medbreak +\label{Oxcaml--module-type-Arg_with}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[Oxcaml-module-type-Arg_with]{\ocamlinlinecode{Arg\_\allowbreak{}with}}}\label{Oxcaml-module-type-Arg_with}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Oxcaml-module-type-Arg_with--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\\ +\label{Oxcaml--module-F_with}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-F_with]{\ocamlinlinecode{F\_\allowbreak{}with}}}\ocamlcodefragment{ (\hyperref[Oxcaml-F_with-argument-1-X]{\ocamlinlinecode{X}} : \hyperref[Oxcaml-module-type-Arg_with]{\ocamlinlinecode{Arg\_\allowbreak{}with}}) : \ocamltag{keyword}{sig} .\allowbreak{}.\allowbreak{}.\allowbreak{} \ocamltag{keyword}{end}}\begin{ocamlindent}Helper functor used in the \ocamlinlinecode{with} constraint below.\end{ocamlindent}% +\medbreak +\label{Oxcaml--module-X_with}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-X_with]{\ocamlinlinecode{X\_\allowbreak{}with}}}\ocamlcodefragment{ : \hyperref[Oxcaml-module-type-Arg_with]{\ocamlinlinecode{Arg\_\allowbreak{}with}}}\\ +\label{Oxcaml--type-t_with_functor}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}functor : immutable\_\allowbreak{}data \ocamltag{keyword}{with} \ocamltag{type-var}{'a} \hyperref[xref-unresolved]{\ocamlinlinecode{F\_\allowbreak{}with}}(\hyperref[xref-unresolved]{\ocamlinlinecode{X\_\allowbreak{}with}}).\allowbreak{}t}\begin{ocamlindent}A \ocamlinlinecode{with} constraint referring to a type through a functor application (\ocamlinlinecode{F(X).\allowbreak{}t}).\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_variant}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}variant : immutable\_\allowbreak{}data \ocamltag{keyword}{with} [ `Foo of \ocamltag{type-var}{'a} | `Bar ]}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side is a polymorphic variant.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_with_object}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with\_\allowbreak{}object : immutable\_\allowbreak{}data \ocamltag{keyword}{with} < foo : \ocamltag{type-var}{'a} >}\begin{ocamlindent}A \ocamlinlinecode{with} constraint whose right-hand side is an object type.\end{ocamlindent}% +\medbreak \subsection{Kind annotations on type aliases\label{Oxcaml--kind-annotations-on-type-aliases}}% \label{Oxcaml--type-t_alias}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}alias : immediate = int}\begin{ocamlindent}Has both a kind annotation and a manifest.\end{ocamlindent}% \medbreak @@ -364,4 +395,6 @@ \subsubsection{Modes in type definitions\label{Oxcaml--modes-in-type-definitions \end{ocamltabular}% \\ +\input{Oxcaml.F_with.tex} +\input{Oxcaml.X_with.tex} \input{Oxcaml.M1.tex} diff --git a/test/generators/latex/oxcaml.targets b/test/generators/latex/oxcaml.targets index 7f76144fb3..d2d076e435 100644 --- a/test/generators/latex/oxcaml.targets +++ b/test/generators/latex/oxcaml.targets @@ -1,2 +1,4 @@ Oxcaml.tex +Oxcaml.F_with.tex +Oxcaml.X_with.tex Oxcaml.M1.tex diff --git a/test/generators/link.dune.inc b/test/generators/link.dune.inc index 5efe5a1677..52ec09429d 100644 --- a/test/generators/link.dune.inc +++ b/test/generators/link.dune.inc @@ -11948,6 +11948,11 @@ (rule (targets Oxcaml.html.gen + Oxcaml-M_with.html.gen + Oxcaml-module-type-Arg_with.html.gen + Oxcaml-F_with.html.gen + Oxcaml-F_with-argument-1-X.html.gen + Oxcaml-X_with.html.gen Oxcaml-module-type-S.html.gen Oxcaml-M1.html.gen Oxcaml-M2.html.gen @@ -11971,6 +11976,38 @@ (action (diff Oxcaml.html Oxcaml.html.gen)) (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M_with.html Oxcaml-M_with.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff + Oxcaml-module-type-Arg_with.html + Oxcaml-module-type-Arg_with.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-F_with.html Oxcaml-F_with.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-F_with-argument-1-X.html Oxcaml-F_with-argument-1-X.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-X_with.html Oxcaml-X_with.html.gen)) + (enabled_if %{ocaml-config:ox})) (rule (alias runtest) (package odoc) @@ -12016,7 +12053,11 @@ (subdir latex (rule - (targets Oxcaml.tex.gen Oxcaml.M1.tex.gen) + (targets + Oxcaml.tex.gen + Oxcaml.F_with.tex.gen + Oxcaml.X_with.tex.gen + Oxcaml.M1.tex.gen) (package odoc) (action (run odoc latex-generate -o . --extra-suffix gen %{dep:../oxcaml.odocl})) @@ -12027,6 +12068,18 @@ (action (diff Oxcaml.tex Oxcaml.tex.gen)) (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.F_with.tex Oxcaml.F_with.tex.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.X_with.tex Oxcaml.X_with.tex.gen)) + (enabled_if %{ocaml-config:ox})) (rule (alias runtest) (package odoc) @@ -12054,7 +12107,14 @@ (subdir man (rule - (targets Oxcaml.3o.gen Oxcaml.M1.3o.gen Oxcaml.M2.3o.gen Oxcaml.M3.3o.gen) + (targets + Oxcaml.3o.gen + Oxcaml.M_with.3o.gen + Oxcaml.F_with.3o.gen + Oxcaml.X_with.3o.gen + Oxcaml.M1.3o.gen + Oxcaml.M2.3o.gen + Oxcaml.M3.3o.gen) (package odoc) (action (run odoc man-generate -o . --extra-suffix gen %{dep:../oxcaml.odocl})) @@ -12065,6 +12125,24 @@ (action (diff Oxcaml.3o Oxcaml.3o.gen)) (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.M_with.3o Oxcaml.M_with.3o.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.F_with.3o Oxcaml.F_with.3o.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.X_with.3o Oxcaml.X_with.3o.gen)) + (enabled_if %{ocaml-config:ox})) (rule (alias runtest) (package odoc) @@ -12106,6 +12184,11 @@ (rule (targets Oxcaml.md.gen + Oxcaml-M_with.md.gen + Oxcaml-module-type-Arg_with.md.gen + Oxcaml-F_with.md.gen + Oxcaml-F_with-argument-1-X.md.gen + Oxcaml-X_with.md.gen Oxcaml-module-type-S.md.gen Oxcaml-M1.md.gen Oxcaml-M2.md.gen @@ -12127,6 +12210,36 @@ (action (diff Oxcaml.md Oxcaml.md.gen)) (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M_with.md Oxcaml-M_with.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-module-type-Arg_with.md Oxcaml-module-type-Arg_with.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-F_with.md Oxcaml-F_with.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-F_with-argument-1-X.md Oxcaml-F_with-argument-1-X.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-X_with.md Oxcaml-X_with.md.gen)) + (enabled_if %{ocaml-config:ox})) (rule (alias runtest) (package odoc) diff --git a/test/generators/man/Oxcaml.3o b/test/generators/man/Oxcaml.3o index 9290c04198..29463c801c 100644 --- a/test/generators/man/Oxcaml.3o +++ b/test/generators/man/Oxcaml.3o @@ -230,6 +230,100 @@ Kind annotation with a with constraint\. Kind annotation with a with constraint and modalities\. .nf .sp +\f[CB]type\fR ('k, 'cmp) comparator +.fi +.br +.ti +2 +Helper used in the with constraints below\. +.nf +.sp +\f[CB]type\fR ('k, 'v, 'cmp) + t_with_constr : ((immutable_data \f[CB]with\fR \f[CB]'k\fR) \f[CB]with\fR \f[CB]'v\fR) \f[CB]with\fR (\f[CB]'k\fR, \f[CB]'cmp\fR) comparator +.fi +.br +.ti +2 +A with constraint whose right-hand side is a parameterized type constructor (as found in base's Map module)\. +.nf +.sp +\f[CB]type\fR 'a t_with_app : immutable_data \f[CB]with\fR \f[CB]'a\fR list +.fi +.br +.ti +2 +A with constraint whose right-hand side applies a type constructor\. +.nf +.sp +\f[CB]type\fR 'a t_with_arrow : immutable_data \f[CB]with\fR \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +.fi +.br +.ti +2 +A with constraint whose right-hand side is an arrow type\. +.nf +.sp +\f[CB]type\fR 'a t_with_arrow_modes : immutable_data \f[CB]with\fR \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR @ local +.fi +.br +.ti +2 +A with constraint whose right-hand side is an arrow type carrying a mode\. +.nf +.sp +\f[CB]type\fR 'a t_with_tuple : immutable_data \f[CB]with\fR \f[CB]'a\fR * int +.fi +.br +.ti +2 +A with constraint whose right-hand side is a tuple type\. +.nf +.sp +\f[CB]module\fR M_with : \f[CB]sig\fR \.\.\. \f[CB]end\fR +.fi +.br +.ti +2 +Helper module used in the with constraint below\. +.nf +.sp +\f[CB]type\fR 'a t_with_dot : immutable_data \f[CB]with\fR \f[CB]'a\fR M_with\.t +.fi +.br +.ti +2 +A with constraint referring to a type through a module path (M\.t)\. +.nf +.sp +\f[CB]module\fR \f[CB]type\fR Arg_with = \f[CB]sig\fR +.br +.ti +2 +\f[CB]type\fR s +.br +\f[CB]end\fR +.sp +\f[CB]module\fR F_with (X : Arg_with) : \f[CB]sig\fR \.\.\. \f[CB]end\fR +.fi +.br +.ti +2 +Helper functor used in the with constraint below\. +.nf +.sp +\f[CB]module\fR X_with : Arg_with +.sp +\f[CB]type\fR 'a t_with_functor : immutable_data \f[CB]with\fR \f[CB]'a\fR F_with(X_with)\.t +.fi +.br +.ti +2 +A with constraint referring to a type through a functor application (F(X)\.t)\. +.nf +.sp +\f[CB]type\fR 'a t_with_variant : immutable_data \f[CB]with\fR [ `Foo of \f[CB]'a\fR | `Bar ] +.fi +.br +.ti +2 +A with constraint whose right-hand side is a polymorphic variant\. +.nf +.sp +\f[CB]type\fR 'a t_with_object : immutable_data \f[CB]with\fR < foo : \f[CB]'a\fR > +.fi +.br +.ti +2 +A with constraint whose right-hand side is an object type\. +.nf +.sp .in 3 \fB6 Kind annotations on type aliases\fR .in diff --git a/test/generators/man/Oxcaml.F_with.3o b/test/generators/man/Oxcaml.F_with.3o new file mode 100644 index 0000000000..8cd2eb7699 --- /dev/null +++ b/test/generators/man/Oxcaml.F_with.3o @@ -0,0 +1,33 @@ + +.TH F_with 3 "" "Odoc" "OCaml Library" +.SH Name +Oxcaml\.F_with +.SH Synopsis +.sp +.in 2 +\fBModule Oxcaml\.F_with\fR +.in +.sp +.fi +Helper functor used in the with constraint below\. +.nf +.SH Documentation +.sp +.nf +.sp +.in 3 +\fB1 Parameters\fR +.in +.sp +\f[CB]module\fR X : \f[CB]sig\fR +.br +.ti +2 +\f[CB]type\fR s +.br +\f[CB]end\fR +.sp +.in 3 +\fB2 Signature\fR +.in +.sp +\f[CB]type\fR 'a t : immutable_data diff --git a/test/generators/man/Oxcaml.M_with.3o b/test/generators/man/Oxcaml.M_with.3o new file mode 100644 index 0000000000..5d8fe49142 --- /dev/null +++ b/test/generators/man/Oxcaml.M_with.3o @@ -0,0 +1,17 @@ + +.TH M_with 3 "" "Odoc" "OCaml Library" +.SH Name +Oxcaml\.M_with +.SH Synopsis +.sp +.in 2 +\fBModule Oxcaml\.M_with\fR +.in +.sp +.fi +Helper module used in the with constraint below\. +.nf +.SH Documentation +.sp +.nf +\f[CB]type\fR 'a t : immutable_data diff --git a/test/generators/man/Oxcaml.X_with.3o b/test/generators/man/Oxcaml.X_with.3o new file mode 100644 index 0000000000..40921be59a --- /dev/null +++ b/test/generators/man/Oxcaml.X_with.3o @@ -0,0 +1,14 @@ + +.TH X_with 3 "" "Odoc" "OCaml Library" +.SH Name +Oxcaml\.X_with +.SH Synopsis +.sp +.in 2 +\fBModule Oxcaml\.X_with\fR +.in +.sp +.SH Documentation +.sp +.nf +\f[CB]type\fR s diff --git a/test/generators/man/oxcaml.targets b/test/generators/man/oxcaml.targets index 3d3984495e..4ed49cfa3b 100644 --- a/test/generators/man/oxcaml.targets +++ b/test/generators/man/oxcaml.targets @@ -1,4 +1,7 @@ Oxcaml.3o +Oxcaml.M_with.3o +Oxcaml.F_with.3o +Oxcaml.X_with.3o Oxcaml.M1.3o Oxcaml.M2.3o Oxcaml.M3.3o diff --git a/test/generators/markdown/Oxcaml-F_with-argument-1-X.md b/test/generators/markdown/Oxcaml-F_with-argument-1-X.md new file mode 100644 index 0000000000..92a764b143 --- /dev/null +++ b/test/generators/markdown/Oxcaml-F_with-argument-1-X.md @@ -0,0 +1,6 @@ + +# Parameter `F_with.X` + +```ocaml +type s +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-F_with.md b/test/generators/markdown/Oxcaml-F_with.md new file mode 100644 index 0000000000..09431e9e41 --- /dev/null +++ b/test/generators/markdown/Oxcaml-F_with.md @@ -0,0 +1,17 @@ + +# Module `Oxcaml.F_with` + +Helper functor used in the `with` constraint below. + + +## Parameters + +```ocaml +module X : Arg_with +``` + +## Signature + +```ocaml +type 'a t : immutable_data +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-M_with.md b/test/generators/markdown/Oxcaml-M_with.md new file mode 100644 index 0000000000..5ef9c6966d --- /dev/null +++ b/test/generators/markdown/Oxcaml-M_with.md @@ -0,0 +1,8 @@ + +# Module `Oxcaml.M_with` + +Helper module used in the `with` constraint below. + +```ocaml +type 'a t : immutable_data +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-X_with.md b/test/generators/markdown/Oxcaml-X_with.md new file mode 100644 index 0000000000..b5dba01c15 --- /dev/null +++ b/test/generators/markdown/Oxcaml-X_with.md @@ -0,0 +1,6 @@ + +# Module `Oxcaml.X_with` + +```ocaml +type s +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-module-type-Arg_with.md b/test/generators/markdown/Oxcaml-module-type-Arg_with.md new file mode 100644 index 0000000000..85d97df386 --- /dev/null +++ b/test/generators/markdown/Oxcaml-module-type-Arg_with.md @@ -0,0 +1,6 @@ + +# Module type `Oxcaml.Arg_with` + +```ocaml +type s +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml.md b/test/generators/markdown/Oxcaml.md index 132cd6b4c6..0dfa5474f6 100644 --- a/test/generators/markdown/Oxcaml.md +++ b/test/generators/markdown/Oxcaml.md @@ -155,6 +155,73 @@ type 'a t_with_modalities : immutable_data with 'a @@ portable contended ``` Kind annotation with a `with` constraint and modalities. +```ocaml +type ('k, 'cmp) comparator +``` +Helper used in the `with` constraints below. + +```ocaml +type ('k, 'v, 'cmp) + t_with_constr : ((immutable_data with 'k) with 'v) with ('k, 'cmp) comparator +``` +A `with` constraint whose right-hand side is a parameterized type constructor (as found in `base`'s `Map` module). + +```ocaml +type 'a t_with_app : immutable_data with 'a list +``` +A `with` constraint whose right-hand side applies a type constructor. + +```ocaml +type 'a t_with_arrow : immutable_data with 'a -> 'a +``` +A `with` constraint whose right-hand side is an arrow type. + +```ocaml +type 'a t_with_arrow_modes : immutable_data with 'a -> 'a @ local +``` +A `with` constraint whose right-hand side is an arrow type carrying a mode. + +```ocaml +type 'a t_with_tuple : immutable_data with 'a * int +``` +A `with` constraint whose right-hand side is a tuple type. + +```ocaml +module M_with : sig ... end +``` +Helper module used in the `with` constraint below. + +```ocaml +type 'a t_with_dot : immutable_data with 'a M_with.t +``` +A `with` constraint referring to a type through a module path (`M.t`). + +```ocaml +module type Arg_with = sig ... end +``` +```ocaml +module F_with (X : Arg_with) : sig ... end +``` +Helper functor used in the `with` constraint below. + +```ocaml +module X_with : Arg_with +``` +```ocaml +type 'a t_with_functor : immutable_data with 'a F_with(X_with).t +``` +A `with` constraint referring to a type through a functor application (`F(X).t`). + +```ocaml +type 'a t_with_variant : immutable_data with [ `Foo of 'a | `Bar ] +``` +A `with` constraint whose right-hand side is a polymorphic variant. + +```ocaml +type 'a t_with_object : immutable_data with < foo : 'a > +``` +A `with` constraint whose right-hand side is an object type. + ## Kind annotations on type aliases diff --git a/test/generators/markdown/oxcaml.targets b/test/generators/markdown/oxcaml.targets index 03016b8b2f..c557e07cc6 100644 --- a/test/generators/markdown/oxcaml.targets +++ b/test/generators/markdown/oxcaml.targets @@ -1,4 +1,9 @@ Oxcaml.md +Oxcaml-M_with.md +Oxcaml-module-type-Arg_with.md +Oxcaml-F_with.md +Oxcaml-F_with-argument-1-X.md +Oxcaml-X_with.md Oxcaml-module-type-S.md Oxcaml-M1.md Oxcaml-M2.md