From f63c15d3a1d09fe4806a58cf09816a2325c5a323 Mon Sep 17 00:00:00 2001 From: Arthur Wendling Date: Tue, 14 Apr 2026 12:00:18 +0200 Subject: [PATCH 1/4] OxCaml: Add a test for kind annotations --- test/generators/cases/oxcaml.mli | 69 ++++++++ test/generators/html/Oxcaml.html | 246 +++++++++++++++++++++++++++++ test/generators/latex/Oxcaml.tex | 44 ++++++ test/generators/man/Oxcaml.3o | 154 ++++++++++++++++++ test/generators/markdown/Oxcaml.md | 110 +++++++++++++ 5 files changed, 623 insertions(+) diff --git a/test/generators/cases/oxcaml.mli b/test/generators/cases/oxcaml.mli index 9a60035c51..320ed24af0 100644 --- a/test/generators/cases/oxcaml.mli +++ b/test/generators/cases/oxcaml.mli @@ -1,2 +1,71 @@ val f : int -> ('a . 'a -> 'a) -> unit (** Polymorphic arguments require parentheses *) + +(** {1 Kind annotations on abstract types} + + These type declarations have kind annotations that constrain their layout. + Currently, odoc does not render the kind annotations. *) + +type t_immediate : immediate +(** Should be [type t_immediate : immediate] *) + +type t_value : value +(** Should be [type t_value : value] *) + +type t_any : any +(** Should be [type t_any : any] *) + +type t_float64 : float64 +(** Should be [type t_float64 : float64] *) + +type t_bits32 : bits32 +(** Should be [type t_bits32 : bits32] *) + +type t_bits64 : bits64 +(** Should be [type t_bits64 : bits64] *) + +type t_word : word +(** Should be [type t_word : word] *) + +type t_void : void +(** Should be [type t_void : void] *) + +(** {1 Kind annotations with modalities} *) + +type t_portable : value mod portable +(** Should be [type t_portable : value mod portable] *) + +type t_contended : value mod contended +(** Should be [type t_contended : value mod contended] *) + +type t_multi_mod : value mod portable contended +(** Should be [type t_multi_mod : value mod portable contended] *) + +(** {1 Kind annotations on parameterized types} *) + +type ('a : immediate) imm_param +(** The kind constraint on ['a] is not rendered. *) + +type ('a : float64) float_param +(** The kind constraint on ['a] is not rendered. *) + +type ('a : immediate, 'b : float64) multi_kind +(** Multiple kind-constrained parameters. *) + +(** {1 Kind annotations with [with] constraints} *) + +type 'a t_with : immediate with 'a +(** Should be [type 'a t_with : immediate with 'a] *) + +(** {1 Kind annotations on type aliases} *) + +type t_alias : immediate = int +(** Has both a kind annotation and a manifest. *) + +(** {1 Kind-constrained polymorphism in values} *) + +val poly_immediate : ('a : immediate). 'a -> 'a +(** The kind constraint on ['a] is not rendered. *) + +val poly_float64 : ('a : float64). 'a -> 'a +(** The kind constraint on ['a] is not rendered. *) diff --git a/test/generators/html/Oxcaml.html b/test/generators/html/Oxcaml.html index f6760c5410..ecd39e1b1f 100644 --- a/test/generators/html/Oxcaml.html +++ b/test/generators/html/Oxcaml.html @@ -14,6 +14,42 @@

Module Oxcaml

+
+ +
@@ -34,6 +70,216 @@

Module Oxcaml

Polymorphic arguments require parentheses

+

+ + Kind annotations on abstract types +

+

These type declarations have kind annotations that constrain their + layout. Currently, odoc does not render the kind annotations. +

+
+
+ + type t_immediate +
+
+

Should be type t_immediate : immediate

+
+
+
+
+ + type t_value +
+

Should be type t_value : value

+
+
+
+
+ + type t_any +
+

Should be type t_any : any

+
+
+
+
+ + type t_float64 +
+
+

Should be type t_float64 : float64

+
+
+
+
+ + type t_bits32 +
+
+

Should be type t_bits32 : bits32

+
+
+
+
+ + type t_bits64 +
+
+

Should be type t_bits64 : bits64

+
+
+
+
+ + type t_word +
+

Should be type t_word : word

+
+
+
+
+ + type t_void +
+

Should be type t_void : void

+
+
+

+ Kind + annotations with modalities +

+
+
+ + type t_portable +
+
+

Should be type t_portable : value mod portable

+
+
+
+
+ + type t_contended +
+
+

Should be type t_contended : value mod contended

+
+
+
+
+ + type t_multi_mod +
+
+

Should be + type t_multi_mod : value mod portable contended +

+
+
+

+ + Kind annotations on parameterized types +

+
+
+ + + type 'a imm_param + + +
+
+

The kind constraint on 'a is not rendered.

+
+
+
+
+ + + type 'a float_param + + +
+
+

The kind constraint on 'a is not rendered.

+
+
+
+
+ + + type + ('a, 'b) multi_kind + + +
+

Multiple kind-constrained parameters.

+
+

+ + Kind annotations with with constraints +

+
+
+ + + type 'a t_with + +
+
+

Should be type 'a t_with : immediate with 'a

+
+
+

+ Kind + annotations on type aliases +

+
+
+ + type t_alias + = int + +
+

Has both a kind annotation and a manifest.

+
+
+

+ + Kind-constrained polymorphism in values +

+
+
+ + + val poly_immediate : 'a. + 'a + -> + 'a + + +
+
+

The kind constraint on 'a is not rendered.

+
+
+
+
+ + + val poly_float64 : 'a. + 'a + -> + 'a + + +
+
+

The kind constraint on 'a is not rendered.

+
+
diff --git a/test/generators/latex/Oxcaml.tex b/test/generators/latex/Oxcaml.tex index db657fcbe7..e3c9b514b2 100644 --- a/test/generators/latex/Oxcaml.tex +++ b/test/generators/latex/Oxcaml.tex @@ -1,5 +1,49 @@ \section{Module \ocamlinlinecode{Oxcaml}}\label{Oxcaml}% \label{Oxcaml--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : int \ocamltag{arrow}{$\rightarrow$} ('a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}) \ocamltag{arrow}{$\rightarrow$} unit}\begin{ocamlindent}Polymorphic arguments require parentheses\end{ocamlindent}% \medbreak +\subsection{Kind annotations on abstract types\label{Oxcaml--kind-annotations-on-abstract-types}}% +These type declarations have kind annotations that constrain their layout. Currently, odoc does not render the kind annotations. + +\label{Oxcaml--type-t_immediate}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}immediate : immediate}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_value}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}value : value}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_any}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}any}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}any : any}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_float64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float64}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}float64 : float64}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_bits32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits32}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}bits32 : bits32}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_bits64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits64}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}bits64 : bits64}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_word}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}word}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}word : word}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_void}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}void}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}void : void}\end{ocamlindent}% +\medbreak +\subsection{Kind annotations with modalities\label{Oxcaml--kind-annotations-with-modalities}}% +\label{Oxcaml--type-t_portable}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}portable}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}portable : value mod portable}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_contended}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}contended}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}contended : value mod contended}\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_multi_mod}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}multi\_\allowbreak{}mod}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}multi\_\allowbreak{}mod : value mod portable contended}\end{ocamlindent}% +\medbreak +\subsection{Kind annotations on parameterized types\label{Oxcaml--kind-annotations-on-parameterized-types}}% +\label{Oxcaml--type-imm_param}\ocamlcodefragment{\ocamltag{keyword}{type} 'a imm\_\allowbreak{}param}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-float_param}\ocamlcodefragment{\ocamltag{keyword}{type} 'a float\_\allowbreak{}param}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-multi_kind}\ocamlcodefragment{\ocamltag{keyword}{type} ('a,\allowbreak{} 'b) multi\_\allowbreak{}kind}\begin{ocamlindent}Multiple kind-constrained parameters.\end{ocamlindent}% +\medbreak +\subsection{Kind annotations with \ocamlinlinecode{with} constraints\label{Oxcaml--kind-annotations-with-with-constraints}}% +\label{Oxcaml--type-t_with}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with}\begin{ocamlindent}Should be \ocamlinlinecode{type 'a t\_\allowbreak{}with : immediate with 'a}\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 = int}\begin{ocamlindent}Has both a kind annotation and a manifest.\end{ocamlindent}% +\medbreak +\subsection{Kind-constrained polymorphism in values\label{Oxcaml--kind-constrained-polymorphism-in-values}}% +\label{Oxcaml--val-poly_immediate}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}immediate : 'a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\medbreak +\label{Oxcaml--val-poly_float64}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}float64 : 'a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\medbreak diff --git a/test/generators/man/Oxcaml.3o b/test/generators/man/Oxcaml.3o index a3daa8e343..3a19017cb1 100644 --- a/test/generators/man/Oxcaml.3o +++ b/test/generators/man/Oxcaml.3o @@ -17,4 +17,158 @@ Oxcaml .ti +2 Polymorphic arguments require parentheses .nf +.sp +.in 3 +\fB1 Kind annotations on abstract types\fR +.in +.sp +.fi +These type declarations have kind annotations that constrain their layout\. Currently, odoc does not render the kind annotations\. +.nf +.sp +\f[CB]type\fR t_immediate +.fi +.br +.ti +2 +Should be type t_immediate : immediate +.nf +.sp +\f[CB]type\fR t_value +.fi +.br +.ti +2 +Should be type t_value : value +.nf +.sp +\f[CB]type\fR t_any +.fi +.br +.ti +2 +Should be type t_any : any +.nf +.sp +\f[CB]type\fR t_float64 +.fi +.br +.ti +2 +Should be type t_float64 : float64 +.nf +.sp +\f[CB]type\fR t_bits32 +.fi +.br +.ti +2 +Should be type t_bits32 : bits32 +.nf +.sp +\f[CB]type\fR t_bits64 +.fi +.br +.ti +2 +Should be type t_bits64 : bits64 +.nf +.sp +\f[CB]type\fR t_word +.fi +.br +.ti +2 +Should be type t_word : word +.nf +.sp +\f[CB]type\fR t_void +.fi +.br +.ti +2 +Should be type t_void : void +.nf +.sp +.in 3 +\fB2 Kind annotations with modalities\fR +.in +.sp +\f[CB]type\fR t_portable +.fi +.br +.ti +2 +Should be type t_portable : value mod portable +.nf +.sp +\f[CB]type\fR t_contended +.fi +.br +.ti +2 +Should be type t_contended : value mod contended +.nf +.sp +\f[CB]type\fR t_multi_mod +.fi +.br +.ti +2 +Should be type t_multi_mod : value mod portable contended +.nf +.sp +.in 3 +\fB3 Kind annotations on parameterized types\fR +.in +.sp +\f[CB]type\fR 'a imm_param +.fi +.br +.ti +2 +The kind constraint on 'a is not rendered\. +.nf +.sp +\f[CB]type\fR 'a float_param +.fi +.br +.ti +2 +The kind constraint on 'a is not rendered\. +.nf +.sp +\f[CB]type\fR ('a, 'b) multi_kind +.fi +.br +.ti +2 +Multiple kind-constrained parameters\. +.nf +.sp +.in 3 +\fB4 Kind annotations with with constraints\fR +.in +.sp +\f[CB]type\fR 'a t_with +.fi +.br +.ti +2 +Should be type 'a t_with : immediate with 'a +.nf +.sp +.in 3 +\fB5 Kind annotations on type aliases\fR +.in +.sp +\f[CB]type\fR t_alias = int +.fi +.br +.ti +2 +Has both a kind annotation and a manifest\. +.nf +.sp +.in 3 +\fB6 Kind-constrained polymorphism in values\fR +.in +.sp +\f[CB]val\fR poly_immediate : 'a\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +.fi +.br +.ti +2 +The kind constraint on 'a is not rendered\. +.nf +.sp +\f[CB]val\fR poly_float64 : 'a\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +.fi +.br +.ti +2 +The kind constraint on 'a is not rendered\. +.nf diff --git a/test/generators/markdown/Oxcaml.md b/test/generators/markdown/Oxcaml.md index 76d86c56a3..e9a019d744 100644 --- a/test/generators/markdown/Oxcaml.md +++ b/test/generators/markdown/Oxcaml.md @@ -5,3 +5,113 @@ val f : int -> ('a. 'a -> 'a) -> unit ``` Polymorphic arguments require parentheses + + +## Kind annotations on abstract types + +These type declarations have kind annotations that constrain their layout. Currently, odoc does not render the kind annotations. + +```ocaml +type t_immediate +``` +Should be `type t_immediate : immediate` + +```ocaml +type t_value +``` +Should be `type t_value : value` + +```ocaml +type t_any +``` +Should be `type t_any : any` + +```ocaml +type t_float64 +``` +Should be `type t_float64 : float64` + +```ocaml +type t_bits32 +``` +Should be `type t_bits32 : bits32` + +```ocaml +type t_bits64 +``` +Should be `type t_bits64 : bits64` + +```ocaml +type t_word +``` +Should be `type t_word : word` + +```ocaml +type t_void +``` +Should be `type t_void : void` + + +## Kind annotations with modalities + +```ocaml +type t_portable +``` +Should be `type t_portable : value mod portable` + +```ocaml +type t_contended +``` +Should be `type t_contended : value mod contended` + +```ocaml +type t_multi_mod +``` +Should be `type t_multi_mod : value mod portable contended` + + +## Kind annotations on parameterized types + +```ocaml +type 'a imm_param +``` +The kind constraint on `'a` is not rendered. + +```ocaml +type 'a float_param +``` +The kind constraint on `'a` is not rendered. + +```ocaml +type ('a, 'b) multi_kind +``` +Multiple kind-constrained parameters. + + +## Kind annotations with `with` constraints + +```ocaml +type 'a t_with +``` +Should be `type 'a t_with : immediate with 'a` + + +## Kind annotations on type aliases + +```ocaml +type t_alias = int +``` +Has both a kind annotation and a manifest. + + +## Kind-constrained polymorphism in values + +```ocaml +val poly_immediate : 'a. 'a -> 'a +``` +The kind constraint on `'a` is not rendered. + +```ocaml +val poly_float64 : 'a. 'a -> 'a +``` +The kind constraint on `'a` is not rendered. From 018e8b25e7024b3af0dde0b9093b7d4af0b0d3e0 Mon Sep 17 00:00:00 2001 From: Arthur Wendling Date: Tue, 14 Apr 2026 13:13:37 +0200 Subject: [PATCH 2/4] OxCaml: Support for kind annotations --- CHANGES.md | 1 + src/document/generator.ml | 71 +++++++++++--- src/loader/cmi.ml | 65 ++++++++++++- src/loader/cmi.mli | 6 ++ src/loader/cmti.ml | 29 +++--- src/model/lang.ml | 17 +++- src/model_desc/lang_desc.ml | 23 ++++- src/search/html.ml | 2 +- src/search/json_index/json_search.ml | 1 + src/xref2/component.ml | 4 +- src/xref2/component.mli | 3 +- src/xref2/lang_of.ml | 1 + src/xref2/strengthen.ml | 1 + test/generators/cases/oxcaml.mli | 37 ++++--- test/generators/html/Oxcaml.html | 113 ++++++++++++---------- test/generators/html/Recent_impl-B.html | 3 +- test/generators/latex/Oxcaml.tex | 38 ++++---- test/generators/latex/Recent_impl.B.tex | 2 +- test/generators/man/Oxcaml.3o | 70 +++++++------- test/generators/man/Recent_impl.B.3o | 2 +- test/generators/markdown/Oxcaml.md | 68 +++++++------ test/generators/markdown/Recent_impl-B.md | 2 +- test/xref2/canonical_nested.t/run.t | 3 +- test/xref2/deep_substitution.t/run.t | 3 +- test/xref2/hidden_modules.t/run.t | 3 +- 25 files changed, 364 insertions(+), 204 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f7d64d2f91..6e5b869e19 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ - `markdown-generate` command now accepts multiple `.odocl` files in a single invocation, eliminating the need for shell scripting (@davesnx, #1387) - Support for OxCaml (@lukemaurer, @art-w, #1399) +- Support for OxCaml kind annotations (@art-w, #1410) ### Fixed - Fix compile-time crashing bugs #930 and #1385 (@jonludlam, #1400) diff --git a/src/document/generator.ml b/src/document/generator.ml index de14ee9a5a..df96a9352f 100644 --- a/src/document/generator.ml +++ b/src/document/generator.ml @@ -306,6 +306,11 @@ module Make (Syntax : SYNTAX) = struct val format_type_path : delim:[ `parens | `brackets ] -> Lang.TypeExpr.t list -> text -> text + + val kind_annotation : Odoc_model.Lang.KindAnnotation.t -> text + + val with_kind_annotation : + Odoc_model.Lang.KindAnnotation.t -> text -> text end = struct let rec te_variant (t : Odoc_model.Lang.TypeExpr.Polymorphic_variant.t) = let style_arguments ~constant arguments = @@ -426,6 +431,31 @@ module Make (Syntax : SYNTAX) = struct then enclose ~l:lparen res ~r:")" else res + and kind_annotation (k : Odoc_model.Lang.KindAnnotation.t) = + match k with + | Default -> O.noop + | Abbreviation s -> O.txt s + | Mod (base, modes) -> + kind_annotation base ++ O.txt " " ++ O.keyword "mod" + ++ O.txt (" " ^ String.concat ~sep:" " modes) + | With (base, ty, modalities) -> ( + kind_annotation base ++ O.txt " " ++ O.keyword "with" ++ O.txt " " + ++ type_expr ty + ++ + match modalities with + | [] -> O.noop + | mods -> + O.txt " " ++ O.keyword "mod" + ++ O.txt (" " ^ String.concat ~sep:" " mods)) + | Kind_of ty -> O.keyword "kind_of_" ++ O.txt " " ++ type_expr ty + | Product ks -> O.list ks ~sep:(O.txt " & ") ~f:kind_annotation + + and with_kind_annotation kind base = + match kind with + | Odoc_model.Lang.KindAnnotation.Default -> base + | k -> + O.txt "(" ++ base ++ O.txt " : " ++ kind_annotation k ++ O.txt ")" + and type_expr ?(needs_parentheses = false) (t : Odoc_model.Lang.TypeExpr.t) = let enclose_parens_if_needed res = @@ -478,9 +508,11 @@ module Make (Syntax : SYNTAX) = struct format_type_path ~delim:`brackets args (Link.from_path (path :> Paths.Path.t)) | Poly (polyvars, t) -> - enclose_parens_if_needed - @@ O.txt ("'" ^ String.concat ~sep:" '" polyvars ^ ". ") - ++ type_expr t + let format_poly_var (name, kind) = + with_kind_annotation kind (O.txt ("'" ^ name)) + in + let vars = O.list polyvars ~sep:(O.txt " ") ~f:format_poly_var in + enclose_parens_if_needed @@ (vars ++ O.txt ". " ++ type_expr t) | Quote t -> O.span (O.txt "<[ " ++ O.box_hv (type_expr t) ++ O.txt " ]>") | Splice t -> O.span (O.txt "$" ++ type_expr ~needs_parentheses:true t) | Package pkg -> @@ -821,8 +853,8 @@ module Make (Syntax : SYNTAX) = struct Odoc_model.Lang.TypeDecl.param list -> text = fun ?(delim = `parens) params -> - let format_param { Odoc_model.Lang.TypeDecl.desc; variance; injectivity } - = + let format_param_str + { Odoc_model.Lang.TypeDecl.desc; variance; injectivity; kind = _ } = let desc = match desc with | Odoc_model.Lang.TypeDecl.Any -> [ "_" ] @@ -838,15 +870,19 @@ module Make (Syntax : SYNTAX) = struct let final = if injectivity then "!" :: var_desc else var_desc in String.concat ~sep:"" final in - O.txt - (match params with - | [] -> "" - | [ x ] -> format_param x |> Syntax.Type.handle_format_params - | lst -> ( - let params = String.concat ~sep:", " (List.map format_param lst) in - (match delim with `parens -> "(" | `brackets -> "[") - ^ params - ^ match delim with `parens -> ")" | `brackets -> "]")) + let format_param p = + Type_expression.with_kind_annotation p.Odoc_model.Lang.TypeDecl.kind + (O.txt (format_param_str p)) + in + match params with + | [] -> O.noop + | [ x ] -> + let base = format_param_str x |> Syntax.Type.handle_format_params in + Type_expression.with_kind_annotation x.kind (O.txt base) + | lst -> + let l = match delim with `parens -> "(" | `brackets -> "[" in + let r = match delim with `parens -> ")" | `brackets -> "]" in + O.txt l ++ O.list lst ~sep:(O.txt ", ") ~f:format_param ++ O.txt r let format_constraints constraints = O.list constraints ~f:(fun (t1, t2) -> @@ -896,7 +932,12 @@ module Make (Syntax : SYNTAX) = struct let params = format_params l in Syntax.Type.handle_constructor_params (O.txt tyname) params in - let intro = keyword' ++ O.txt " " ++ tconstr in + let kind_annot = + match t.equation.kind with + | Default -> O.noop + | k -> O.txt " : " ++ Type_expression.kind_annotation k + in + let intro = keyword' ++ O.txt " " ++ tconstr ++ kind_annot in let constraints = format_constraints t.equation.constraints in let manifest, need_private, long_prefix = match t.equation.manifest with diff --git a/src/loader/cmi.ml b/src/loader/cmi.ml index db7bfd1ba3..a60053aaea 100644 --- a/src/loader/cmi.ml +++ b/src/loader/cmi.ml @@ -490,6 +490,51 @@ let mark_class_declaration cld = List.iter mark_type_parameter cld.cty_params; mark_class_type cld.cty_params cld.cty_type +#if defined OXCAML +let 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) = + let open KindAnnotation in + match jk.pjkind_desc with + | Pjk_default -> Default + | Pjk_abbreviation s -> Abbreviation s + | 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) + | Pjk_with (jk', cty, modalities) -> + let ty = read_parsetree_core_type cty in + let modalities = List.map (fun (m : Parsetree.modality Location.loc) -> + let (Parsetree.Modality s) = m.txt in s) modalities in + With (read_jkind_annotation jk', ty, modalities) + | Pjk_kind_of cty -> + Kind_of (read_parsetree_core_type cty) + | Pjk_product jks -> + Product (List.map read_jkind_annotation jks) + +let read_jkind_annotation = function + | None -> KindAnnotation.Default + | Some jk -> + match read_jkind_annotation jk with + | Abbreviation "value" -> Default + | k -> k + +let jkind_of_type_desc te = + match te with + | Tvar { jkind; _ } | Tunivar { jkind; _ } -> + read_jkind_annotation jkind.annotation + | _ -> KindAnnotation.Default +#else + +let jkind_of_type_desc _te = KindAnnotation.Default + +#endif + let rec read_type_expr env typ = let open TypeExpr in let px = proxy typ in @@ -549,10 +594,14 @@ let rec read_type_expr env typ = | Tpoly (typ, []) -> read_type_expr env typ | Tpoly (typ, tyl) -> let tyl = List.map Compat.repr tyl in - let vars = List.map name_of_type_repr tyl in + let vars_with_kinds = List.map (fun ty -> + let name = name_of_type_repr ty in + let kind = jkind_of_type_desc ty.desc in + (name, kind) + ) tyl in let typ = read_type_expr env typ in remove_names tyl; - Poly(vars, typ) + Poly(vars_with_kinds, typ) | Tunivar _ -> Var (name_of_type typ) #if OCAML_VERSION>=(5,4,0) | Tpackage {pack_path=p; pack_cstrs } -> @@ -827,6 +876,7 @@ let read_type_parameter abstr var param = if name = "_" then Any else Var name in + let kind = jkind_of_type_desc (Compat.get_desc param) in let variance = if not (abstr || aliasable param) then None else begin @@ -836,7 +886,7 @@ let read_type_parameter abstr var param = else None end in let injectivity = read_injectivity var in - {desc; variance; injectivity} + {desc; variance; injectivity; kind} let read_type_constraints env params = List.fold_right @@ -898,7 +948,14 @@ let read_type_declaration env parent id decl = List.map2 (read_type_parameter abstr) decl.type_variance params in let private_ = (decl.type_private = Private) in - let equation = Equation.{params; manifest; constraints; private_} in + let kind = +#if defined OXCAML + read_jkind_annotation decl.type_jkind.annotation +#else + KindAnnotation.Default +#endif + in + let equation = Equation.{params; manifest; constraints; private_; kind} in {id; source_loc; doc; canonical; equation; representation} let read_extension_constructor env parent id ext = diff --git a/src/loader/cmi.mli b/src/loader/cmi.mli index 1d0cca0ac5..b39358455f 100644 --- a/src/loader/cmi.mli +++ b/src/loader/cmi.mli @@ -96,3 +96,9 @@ val read_extension_constructor : env -> val read_exception : env -> Paths.Identifier.Signature.t -> Ident.t -> Types.extension_constructor -> Odoc_model.Lang.Exception.t + +#if defined OXCAML +val read_jkind_annotation : + Parsetree.jkind_annotation option -> + Odoc_model.Lang.KindAnnotation.t +#endif diff --git a/src/loader/cmti.ml b/src/loader/cmti.ml index 5468d42af3..40fb60a2b7 100644 --- a/src/loader/cmti.ml +++ b/src/loader/cmti.ml @@ -168,10 +168,11 @@ let rec read_core_type env container ctyp = | Ttyp_poly([], typ) -> read_core_type env container typ #if defined OXCAML | Ttyp_poly(vars, typ) -> - (* TODO: presumably want the layouts, eventually *) - Poly(List.map fst vars, read_core_type env container typ) + Poly(List.map (fun (name, jk) -> + (name, Cmi.read_jkind_annotation jk) + ) vars, read_core_type env container typ) #else - | Ttyp_poly(vars, typ) -> Poly(vars, read_core_type env container typ) + | Ttyp_poly(vars, typ) -> Poly(List.map (fun v -> (v, KindAnnotation.Default)) vars, read_core_type env container typ) #endif #if OCAML_VERSION >= (5,4,0) | Ttyp_package {tpt_path = pack_path; tpt_cstrs=pack_fields; _} -> @@ -219,15 +220,14 @@ let read_value_description env parent vd = let read_type_parameter (ctyp, var_and_injectivity) = let open TypeDecl in - let desc = + let desc, kind = match ctyp.ctyp_desc with #if defined OXCAML - (* TODO: presumably we want the layouts below, eventually *) - | Ttyp_var (None, _layout) -> Any - | Ttyp_var (Some s, _layout) -> Var s + | Ttyp_var (None, layout) -> Any, Cmi.read_jkind_annotation layout + | Ttyp_var (Some s, layout) -> Var s, Cmi.read_jkind_annotation layout #else - | Ttyp_any -> Any - | Ttyp_var s -> Var s + | Ttyp_any -> Any, KindAnnotation.Default + | Ttyp_var s -> Var s, KindAnnotation.Default #endif | _ -> assert false in @@ -254,7 +254,7 @@ let read_type_parameter (ctyp, var_and_injectivity) = var, injectivity #endif in - {desc; variance; injectivity} + {desc; variance; injectivity; kind} #if defined OXCAML let is_mutable = Types.is_mutable @@ -346,7 +346,14 @@ let read_type_equation env container decl = read_core_type env container typ2)) decl.typ_cstrs in - {params; private_; manifest; constraints} + let kind = +#if defined OXCAML + Cmi.read_jkind_annotation decl.typ_jkind_annotation +#else + KindAnnotation.Default +#endif + in + {params; private_; manifest; constraints; kind} let read_type_declaration env parent decl = let open TypeDecl in diff --git a/src/model/lang.ml b/src/model/lang.ml index e801ebbf2e..7298140608 100644 --- a/src/model/lang.ml +++ b/src/model/lang.ml @@ -258,6 +258,7 @@ and TypeDecl : sig desc : param_desc; variance : variance option; injectivity : bool; + kind : KindAnnotation.t; } module Equation : sig @@ -266,6 +267,7 @@ and TypeDecl : sig private_ : bool; manifest : TypeExpr.t option; constraints : (TypeExpr.t * TypeExpr.t) list; + kind : KindAnnotation.t; } end @@ -417,6 +419,19 @@ and InstanceVariable : sig end = InstanceVariable +(** {3 Kind annotations} *) + +and KindAnnotation : sig + type t = + | Default + | Abbreviation of string + | Mod of t * string list + | With of t * TypeExpr.t * string list + | Kind_of of TypeExpr.t + | Product of t list +end = + KindAnnotation + (** {3 Type expressions} *) and TypeExpr : sig @@ -464,7 +479,7 @@ and TypeExpr : sig | Polymorphic_variant of TypeExpr.Polymorphic_variant.t | Object of TypeExpr.Object.t | Class of Path.ClassType.t * t list - | Poly of string list * t + | Poly of (string * KindAnnotation.t) list * t | Quote of t | Splice of t | Package of TypeExpr.Package.t diff --git a/src/model_desc/lang_desc.ml b/src/model_desc/lang_desc.ml index 8df9471334..a56672234c 100644 --- a/src/model_desc/lang_desc.ml +++ b/src/model_desc/lang_desc.ml @@ -367,6 +367,21 @@ and typedecl_variance = Variant (function Pos -> C0 "Pos" | Neg -> C0 "Neg" | Bivariant -> C0 "Bivariant") +and kind_annotation = + let open Lang.KindAnnotation in + Variant + (function + | Default -> C0 "Default" + | Abbreviation x -> C ("Abbreviation", x, string) + | Mod (x1, x2) -> C ("Mod", (x1, x2), Pair (kind_annotation, List string)) + | With (x1, x2, x3) -> + C + ( "With", + (x1, x2, x3), + Triple (kind_annotation, typeexpr_t, List string) ) + | Kind_of x -> C ("Kind_of", x, typeexpr_t) + | Product x -> C ("Product", x, List kind_annotation)) + and typedecl_param_desc = let open Lang.TypeDecl in Variant (function Any -> C0 "Any" | Var x -> C ("Var", x, string)) @@ -378,6 +393,7 @@ and typedecl_param = F ("desc", (fun t -> t.desc), typedecl_param_desc); F ("variance", (fun t -> t.variance), Option typedecl_variance); F ("injectivity", (fun t -> t.injectivity), bool); + F ("kind", (fun t -> t.kind), kind_annotation); ] and typedecl_equation = @@ -391,6 +407,7 @@ and typedecl_equation = ( "constraints", (fun t -> t.constraints), List (Pair (typeexpr_t, typeexpr_t)) ); + F ("kind", (fun t -> t.kind), kind_annotation); ] and typedecl_t = @@ -667,7 +684,11 @@ and typeexpr_t = | Object x -> C ("Object", x, typeexpr_object) | Class (x1, x2) -> C ("Class", ((x1 :> Paths.Path.t), x2), Pair (path, List typeexpr_t)) - | Poly (x1, x2) -> C ("Poly", (x1, x2), Pair (List string, typeexpr_t)) + | Poly (x1, x2) -> + C + ( "Poly", + (x1, x2), + Pair (List (Pair (string, kind_annotation)), typeexpr_t) ) | Quote x -> C ("Quote", x, typeexpr_t) | Splice x -> C ("Splice", x, typeexpr_t) | Package x -> C ("Package", x, typeexpr_package)) diff --git a/src/search/html.ml b/src/search/html.ml index df5aaab310..f8e08a4b55 100644 --- a/src/search/html.ml +++ b/src/search/html.ml @@ -55,7 +55,7 @@ let field_rhs ({ mutable_ = _; type_; parent_type = _ } : Entry.field_entry) = " : " ^ Text.of_type type_ let typedecl_params ?(delim = `parens) params = - let format_param { TypeDecl.desc; variance; injectivity } = + let format_param { TypeDecl.desc; variance; injectivity; kind = _ } = let desc = match desc with TypeDecl.Any -> [ "_" ] | Var s -> [ "'"; s ] in diff --git a/src/search/json_index/json_search.ml b/src/search/json_index/json_search.ml index e490e7b41b..9ba178fbd4 100644 --- a/src/search/json_index/json_search.ml +++ b/src/search/json_index/json_search.ml @@ -152,6 +152,7 @@ let of_entry ({ Entry.id; doc; kind } as entry) html occurrences = private_; manifest; constraints; + kind = _; } = equation in diff --git a/src/xref2/component.ml b/src/xref2/component.ml index 9017fea357..ef4fb82125 100644 --- a/src/xref2/component.ml +++ b/src/xref2/component.ml @@ -128,7 +128,7 @@ and TypeExpr : sig | Polymorphic_variant of TypeExpr.Polymorphic_variant.t | Object of TypeExpr.Object.t | Class of Cpath.class_type * t list - | Poly of string list * t + | Poly of (string * Odoc_model.Lang.KindAnnotation.t) list * t | Quote of t | Splice of t | Package of TypeExpr.Package.t @@ -286,6 +286,7 @@ and TypeDecl : sig private_ : bool; manifest : TypeExpr.t option; constraints : (TypeExpr.t * TypeExpr.t) list; + kind : Odoc_model.Lang.KindAnnotation.t; } end @@ -2282,6 +2283,7 @@ module Of_Lang = struct (fun (x, y) -> (type_expression ident_map x, type_expression ident_map y)) teq.constraints; + kind = teq.kind; } and type_expr_polyvar ident_map v = diff --git a/src/xref2/component.mli b/src/xref2/component.mli index 0cd6e900f5..7d77c511a4 100644 --- a/src/xref2/component.mli +++ b/src/xref2/component.mli @@ -123,7 +123,7 @@ and TypeExpr : sig | Polymorphic_variant of TypeExpr.Polymorphic_variant.t | Object of TypeExpr.Object.t | Class of Cpath.class_type * t list - | Poly of string list * t + | Poly of (string * Odoc_model.Lang.KindAnnotation.t) list * t | Quote of t | Splice of t | Package of TypeExpr.Package.t @@ -276,6 +276,7 @@ and TypeDecl : sig private_ : bool; manifest : TypeExpr.t option; constraints : (TypeExpr.t * TypeExpr.t) list; + kind : Odoc_model.Lang.KindAnnotation.t; } end diff --git a/src/xref2/lang_of.ml b/src/xref2/lang_of.ml index ed5f45dfd0..f3e7bc1b4c 100644 --- a/src/xref2/lang_of.ml +++ b/src/xref2/lang_of.ml @@ -954,6 +954,7 @@ and type_decl_equation map (parent : Identifier.FieldParent.t) List.map (fun (x, y) -> (type_expr map parent x, type_expr map parent y)) eqn.constraints; + kind = eqn.kind; } and type_decl map parent id (t : Component.TypeDecl.t) : diff --git a/src/xref2/strengthen.ml b/src/xref2/strengthen.ml index a1c4125960..c6460856d6 100644 --- a/src/xref2/strengthen.ml +++ b/src/xref2/strengthen.ml @@ -112,6 +112,7 @@ and type_decl : Cpath.type_ -> TypeDecl.t -> TypeDecl.t = private_ = e.private_; manifest; constraints = e.constraints; + kind = e.kind; } in { t with equation } diff --git a/test/generators/cases/oxcaml.mli b/test/generators/cases/oxcaml.mli index 320ed24af0..4ddc59a7bb 100644 --- a/test/generators/cases/oxcaml.mli +++ b/test/generators/cases/oxcaml.mli @@ -1,53 +1,50 @@ val f : int -> ('a . 'a -> 'a) -> unit (** Polymorphic arguments require parentheses *) -(** {1 Kind annotations on abstract types} - - These type declarations have kind annotations that constrain their layout. - Currently, odoc does not render the kind annotations. *) +(** {1 Kind annotations on abstract types} *) type t_immediate : immediate -(** Should be [type t_immediate : immediate] *) +(** Kind annotation on abstract type. *) type t_value : value -(** Should be [type t_value : value] *) +(** [value] is the default kind, so the annotation is not rendered. *) type t_any : any -(** Should be [type t_any : any] *) +(** A type with the [any] kind. *) type t_float64 : float64 -(** Should be [type t_float64 : float64] *) +(** A type with the [float64] kind. *) type t_bits32 : bits32 -(** Should be [type t_bits32 : bits32] *) +(** A type with the [bits32] kind. *) type t_bits64 : bits64 -(** Should be [type t_bits64 : bits64] *) +(** A type with the [bits64] kind. *) type t_word : word -(** Should be [type t_word : word] *) +(** A type with the [word] kind. *) type t_void : void -(** Should be [type t_void : void] *) +(** A type with the [void] kind. *) (** {1 Kind annotations with modalities} *) type t_portable : value mod portable -(** Should be [type t_portable : value mod portable] *) +(** Kind annotation with a modality. *) type t_contended : value mod contended -(** Should be [type t_contended : value mod contended] *) +(** Kind annotation with a different modality. *) type t_multi_mod : value mod portable contended -(** Should be [type t_multi_mod : value mod portable contended] *) +(** Kind annotation with multiple modalities. *) (** {1 Kind annotations on parameterized types} *) type ('a : immediate) imm_param -(** The kind constraint on ['a] is not rendered. *) +(** A type parameter with a kind constraint. *) type ('a : float64) float_param -(** The kind constraint on ['a] is not rendered. *) +(** A type parameter with a different kind constraint. *) type ('a : immediate, 'b : float64) multi_kind (** Multiple kind-constrained parameters. *) @@ -55,7 +52,7 @@ type ('a : immediate, 'b : float64) multi_kind (** {1 Kind annotations with [with] constraints} *) type 'a t_with : immediate with 'a -(** Should be [type 'a t_with : immediate with 'a] *) +(** Kind annotation with a [with] constraint. *) (** {1 Kind annotations on type aliases} *) @@ -65,7 +62,7 @@ type t_alias : immediate = int (** {1 Kind-constrained polymorphism in values} *) val poly_immediate : ('a : immediate). 'a -> 'a -(** The kind constraint on ['a] is not rendered. *) +(** Kind constraint on a polymorphic type variable. *) val poly_float64 : ('a : float64). 'a -> 'a -(** The kind constraint on ['a] is not rendered. *) +(** Kind constraint on a polymorphic type variable with a different kind. *) diff --git a/test/generators/html/Oxcaml.html b/test/generators/html/Oxcaml.html index ecd39e1b1f..d6c805b251 100644 --- a/test/generators/html/Oxcaml.html +++ b/test/generators/html/Oxcaml.html @@ -74,75 +74,76 @@

Kind annotations on abstract types

-

These type declarations have kind annotations that constrain their - layout. Currently, odoc does not render the kind annotations. -

- type t_immediate -
-
-

Should be type t_immediate : immediate

+ + type t_immediate : immediate +
+

Kind annotation on abstract type.

type t_value
-

Should be type t_value : value

+
+

value is the default kind, so the annotation is + not rendered. +

- type t_any -
-

Should be type t_any : any

+ type t_any : any
+

A type with the any kind.

- type t_float64 + type t_float64 : float64 +
-
-

Should be type t_float64 : float64

+

A type with the float64 kind.

- type t_bits32 + type t_bits32 : bits32 +
-
-

Should be type t_bits32 : bits32

+

A type with the bits32 kind.

- type t_bits64 + type t_bits64 : bits64 +
-
-

Should be type t_bits64 : bits64

+

A type with the bits64 kind.

- type t_word + type t_word : word +
-

Should be type t_word : word

+

A type with the word kind.

- type t_void + type t_void : void +
-

Should be type t_void : void

+

A type with the void kind.

@@ -152,30 +153,35 @@

- type t_portable -
-
-

Should be type t_portable : value mod portable

-
+ + type t_portable : value + mod portable + + +

Kind annotation with a modality.

- type t_contended + + type t_contended : value + mod contended + +
-
-

Should be type t_contended : value mod contended

+

Kind annotation with a different modality.

- type t_multi_mod + + type t_multi_mod : value + mod portable contended + +
-
-

Should be - type t_multi_mod : value mod portable contended -

+

Kind annotation with multiple modalities.

@@ -186,24 +192,25 @@

- type 'a imm_param + type + ('a : immediate) imm_param
-
-

The kind constraint on 'a is not rendered.

+

A type parameter with a kind constraint.

- type 'a float_param + type + ('a : float64) float_param
-

The kind constraint on 'a is not rendered.

+

A type parameter with a different kind constraint.

@@ -211,7 +218,7 @@

type - ('a, 'b) multi_kind + (('a : immediate), ('b : float64)) multi_kind

@@ -225,11 +232,14 @@

- type 'a t_with + type 'a t_with : + immediate with + 'a +
-

Should be type 'a t_with : immediate with 'a

+

Kind annotation with a with constraint.

@@ -239,7 +249,7 @@

- type t_alias + type t_alias : immediate = int
@@ -254,7 +264,8 @@

- val poly_immediate : 'a. + val poly_immediate : ('a : immediate + ). 'a -> 'a @@ -262,14 +273,15 @@

-

The kind constraint on 'a is not rendered.

+

Kind constraint on a polymorphic type variable.

- val poly_float64 : 'a. + val poly_float64 : ('a : float64 + ). 'a -> 'a @@ -277,7 +289,8 @@

-

The kind constraint on 'a is not rendered.

+

Kind constraint on a polymorphic type variable with a different kind. +

diff --git a/test/generators/html/Recent_impl-B.html b/test/generators/html/Recent_impl-B.html index 3fe204717a..6b08e2f218 100644 --- a/test/generators/html/Recent_impl-B.html +++ b/test/generators/html/Recent_impl-B.html @@ -19,7 +19,8 @@

Module Recent_impl.B

- type t = + type t : immediate + =
  1. diff --git a/test/generators/latex/Oxcaml.tex b/test/generators/latex/Oxcaml.tex index e3c9b514b2..38d94dd425 100644 --- a/test/generators/latex/Oxcaml.tex +++ b/test/generators/latex/Oxcaml.tex @@ -2,48 +2,46 @@ \section{Module \ocamlinlinecode{Oxcaml}}\label{Oxcaml}% \label{Oxcaml--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : int \ocamltag{arrow}{$\rightarrow$} ('a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}) \ocamltag{arrow}{$\rightarrow$} unit}\begin{ocamlindent}Polymorphic arguments require parentheses\end{ocamlindent}% \medbreak \subsection{Kind annotations on abstract types\label{Oxcaml--kind-annotations-on-abstract-types}}% -These type declarations have kind annotations that constrain their layout. Currently, odoc does not render the kind annotations. - -\label{Oxcaml--type-t_immediate}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}immediate : immediate}\end{ocamlindent}% +\label{Oxcaml--type-t_immediate}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate : immediate}\begin{ocamlindent}Kind annotation on abstract type.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_value}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}value : value}\end{ocamlindent}% +\label{Oxcaml--type-t_value}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value}\begin{ocamlindent}\ocamlinlinecode{value} is the default kind, so the annotation is not rendered.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_any}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}any}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}any : any}\end{ocamlindent}% +\label{Oxcaml--type-t_any}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}any : any}\begin{ocamlindent}A type with the \ocamlinlinecode{any} kind.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_float64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float64}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}float64 : float64}\end{ocamlindent}% +\label{Oxcaml--type-t_float64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float64 : float64}\begin{ocamlindent}A type with the \ocamlinlinecode{float64} kind.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_bits32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits32}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}bits32 : bits32}\end{ocamlindent}% +\label{Oxcaml--type-t_bits32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits32 : bits32}\begin{ocamlindent}A type with the \ocamlinlinecode{bits32} kind.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_bits64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits64}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}bits64 : bits64}\end{ocamlindent}% +\label{Oxcaml--type-t_bits64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits64 : bits64}\begin{ocamlindent}A type with the \ocamlinlinecode{bits64} kind.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_word}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}word}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}word : word}\end{ocamlindent}% +\label{Oxcaml--type-t_word}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}word : word}\begin{ocamlindent}A type with the \ocamlinlinecode{word} kind.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_void}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}void}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}void : void}\end{ocamlindent}% +\label{Oxcaml--type-t_void}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}void : void}\begin{ocamlindent}A type with the \ocamlinlinecode{void} kind.\end{ocamlindent}% \medbreak \subsection{Kind annotations with modalities\label{Oxcaml--kind-annotations-with-modalities}}% -\label{Oxcaml--type-t_portable}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}portable}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}portable : value mod portable}\end{ocamlindent}% +\label{Oxcaml--type-t_portable}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}portable : value \ocamltag{keyword}{mod} portable}\begin{ocamlindent}Kind annotation with a modality.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_contended}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}contended}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}contended : value mod contended}\end{ocamlindent}% +\label{Oxcaml--type-t_contended}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}contended : value \ocamltag{keyword}{mod} contended}\begin{ocamlindent}Kind annotation with a different modality.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_multi_mod}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}multi\_\allowbreak{}mod}\begin{ocamlindent}Should be \ocamlinlinecode{type t\_\allowbreak{}multi\_\allowbreak{}mod : value mod portable contended}\end{ocamlindent}% +\label{Oxcaml--type-t_multi_mod}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}multi\_\allowbreak{}mod : value \ocamltag{keyword}{mod} portable contended}\begin{ocamlindent}Kind annotation with multiple modalities.\end{ocamlindent}% \medbreak \subsection{Kind annotations on parameterized types\label{Oxcaml--kind-annotations-on-parameterized-types}}% -\label{Oxcaml--type-imm_param}\ocamlcodefragment{\ocamltag{keyword}{type} 'a imm\_\allowbreak{}param}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\label{Oxcaml--type-imm_param}\ocamlcodefragment{\ocamltag{keyword}{type} ('a : immediate) imm\_\allowbreak{}param}\begin{ocamlindent}A type parameter with a kind constraint.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-float_param}\ocamlcodefragment{\ocamltag{keyword}{type} 'a float\_\allowbreak{}param}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\label{Oxcaml--type-float_param}\ocamlcodefragment{\ocamltag{keyword}{type} ('a : float64) float\_\allowbreak{}param}\begin{ocamlindent}A type parameter with a different kind constraint.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-multi_kind}\ocamlcodefragment{\ocamltag{keyword}{type} ('a,\allowbreak{} 'b) multi\_\allowbreak{}kind}\begin{ocamlindent}Multiple kind-constrained parameters.\end{ocamlindent}% +\label{Oxcaml--type-multi_kind}\ocamlcodefragment{\ocamltag{keyword}{type} (('a : immediate),\allowbreak{} ('b : float64)) multi\_\allowbreak{}kind}\begin{ocamlindent}Multiple kind-constrained parameters.\end{ocamlindent}% \medbreak \subsection{Kind annotations with \ocamlinlinecode{with} constraints\label{Oxcaml--kind-annotations-with-with-constraints}}% -\label{Oxcaml--type-t_with}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with}\begin{ocamlindent}Should be \ocamlinlinecode{type 'a t\_\allowbreak{}with : immediate with 'a}\end{ocamlindent}% +\label{Oxcaml--type-t_with}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with : immediate \ocamltag{keyword}{with} \ocamltag{type-var}{'a}}\begin{ocamlindent}Kind annotation with a \ocamlinlinecode{with} constraint.\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 = int}\begin{ocamlindent}Has both a kind annotation and a manifest.\end{ocamlindent}% +\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 \subsection{Kind-constrained polymorphism in values\label{Oxcaml--kind-constrained-polymorphism-in-values}}% -\label{Oxcaml--val-poly_immediate}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}immediate : 'a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\label{Oxcaml--val-poly_immediate}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}immediate : ('a : immediate).\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}Kind constraint on a polymorphic type variable.\end{ocamlindent}% \medbreak -\label{Oxcaml--val-poly_float64}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}float64 : 'a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}The kind constraint on \ocamlinlinecode{'a} is not rendered.\end{ocamlindent}% +\label{Oxcaml--val-poly_float64}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}float64 : ('a : float64).\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}Kind constraint on a polymorphic type variable with a different kind.\end{ocamlindent}% \medbreak diff --git a/test/generators/latex/Recent_impl.B.tex b/test/generators/latex/Recent_impl.B.tex index 38b1c5c050..cacfd7a923 100644 --- a/test/generators/latex/Recent_impl.B.tex +++ b/test/generators/latex/Recent_impl.B.tex @@ -1,5 +1,5 @@ \section{Module \ocamlinlinecode{Recent\_\allowbreak{}impl.\allowbreak{}B}}\label{Recent_impl-B}% -\label{Recent_impl-B--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }\\ +\label{Recent_impl-B--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t : immediate = }\\ \begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B}}\label{Recent_impl-B--type-t.B}\\ \end{ocamltabular}% \\ diff --git a/test/generators/man/Oxcaml.3o b/test/generators/man/Oxcaml.3o index 3a19017cb1..9b8923f93b 100644 --- a/test/generators/man/Oxcaml.3o +++ b/test/generators/man/Oxcaml.3o @@ -22,110 +22,106 @@ Polymorphic arguments require parentheses \fB1 Kind annotations on abstract types\fR .in .sp -.fi -These type declarations have kind annotations that constrain their layout\. Currently, odoc does not render the kind annotations\. -.nf -.sp -\f[CB]type\fR t_immediate +\f[CB]type\fR t_immediate : immediate .fi .br .ti +2 -Should be type t_immediate : immediate +Kind annotation on abstract type\. .nf .sp \f[CB]type\fR t_value .fi .br .ti +2 -Should be type t_value : value +value is the default kind, so the annotation is not rendered\. .nf .sp -\f[CB]type\fR t_any +\f[CB]type\fR t_any : any .fi .br .ti +2 -Should be type t_any : any +A type with the any kind\. .nf .sp -\f[CB]type\fR t_float64 +\f[CB]type\fR t_float64 : float64 .fi .br .ti +2 -Should be type t_float64 : float64 +A type with the float64 kind\. .nf .sp -\f[CB]type\fR t_bits32 +\f[CB]type\fR t_bits32 : bits32 .fi .br .ti +2 -Should be type t_bits32 : bits32 +A type with the bits32 kind\. .nf .sp -\f[CB]type\fR t_bits64 +\f[CB]type\fR t_bits64 : bits64 .fi .br .ti +2 -Should be type t_bits64 : bits64 +A type with the bits64 kind\. .nf .sp -\f[CB]type\fR t_word +\f[CB]type\fR t_word : word .fi .br .ti +2 -Should be type t_word : word +A type with the word kind\. .nf .sp -\f[CB]type\fR t_void +\f[CB]type\fR t_void : void .fi .br .ti +2 -Should be type t_void : void +A type with the void kind\. .nf .sp .in 3 \fB2 Kind annotations with modalities\fR .in .sp -\f[CB]type\fR t_portable +\f[CB]type\fR t_portable : value \f[CB]mod\fR portable .fi .br .ti +2 -Should be type t_portable : value mod portable +Kind annotation with a modality\. .nf .sp -\f[CB]type\fR t_contended +\f[CB]type\fR t_contended : value \f[CB]mod\fR contended .fi .br .ti +2 -Should be type t_contended : value mod contended +Kind annotation with a different modality\. .nf .sp -\f[CB]type\fR t_multi_mod +\f[CB]type\fR t_multi_mod : value \f[CB]mod\fR portable contended .fi .br .ti +2 -Should be type t_multi_mod : value mod portable contended +Kind annotation with multiple modalities\. .nf .sp .in 3 \fB3 Kind annotations on parameterized types\fR .in .sp -\f[CB]type\fR 'a imm_param +\f[CB]type\fR ('a : immediate) imm_param .fi .br .ti +2 -The kind constraint on 'a is not rendered\. +A type parameter with a kind constraint\. .nf .sp -\f[CB]type\fR 'a float_param +\f[CB]type\fR ('a : float64) float_param .fi .br .ti +2 -The kind constraint on 'a is not rendered\. +A type parameter with a different kind constraint\. .nf .sp -\f[CB]type\fR ('a, 'b) multi_kind +\f[CB]type\fR (('a : immediate), ('b : float64)) multi_kind .fi .br .ti +2 @@ -136,18 +132,18 @@ Multiple kind-constrained parameters\. \fB4 Kind annotations with with constraints\fR .in .sp -\f[CB]type\fR 'a t_with +\f[CB]type\fR 'a t_with : immediate \f[CB]with\fR \f[CB]'a\fR .fi .br .ti +2 -Should be type 'a t_with : immediate with 'a +Kind annotation with a with constraint\. .nf .sp .in 3 \fB5 Kind annotations on type aliases\fR .in .sp -\f[CB]type\fR t_alias = int +\f[CB]type\fR t_alias : immediate = int .fi .br .ti +2 @@ -158,17 +154,17 @@ Has both a kind annotation and a manifest\. \fB6 Kind-constrained polymorphism in values\fR .in .sp -\f[CB]val\fR poly_immediate : 'a\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +\f[CB]val\fR poly_immediate : ('a : immediate)\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR .fi .br .ti +2 -The kind constraint on 'a is not rendered\. +Kind constraint on a polymorphic type variable\. .nf .sp -\f[CB]val\fR poly_float64 : 'a\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +\f[CB]val\fR poly_float64 : ('a : float64)\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR .fi .br .ti +2 -The kind constraint on 'a is not rendered\. +Kind constraint on a polymorphic type variable with a different kind\. .nf diff --git a/test/generators/man/Recent_impl.B.3o b/test/generators/man/Recent_impl.B.3o index 60192553b3..05d780c9d0 100644 --- a/test/generators/man/Recent_impl.B.3o +++ b/test/generators/man/Recent_impl.B.3o @@ -11,7 +11,7 @@ Recent_impl\.B .SH Documentation .sp .nf -\f[CB]type\fR t = +\f[CB]type\fR t : immediate = .br .ti +2 | \f[CB]B\fR diff --git a/test/generators/markdown/Oxcaml.md b/test/generators/markdown/Oxcaml.md index e9a019d744..b55d9145f7 100644 --- a/test/generators/markdown/Oxcaml.md +++ b/test/generators/markdown/Oxcaml.md @@ -9,81 +9,79 @@ Polymorphic arguments require parentheses ## Kind annotations on abstract types -These type declarations have kind annotations that constrain their layout. Currently, odoc does not render the kind annotations. - ```ocaml -type t_immediate +type t_immediate : immediate ``` -Should be `type t_immediate : immediate` +Kind annotation on abstract type. ```ocaml type t_value ``` -Should be `type t_value : value` +`value` is the default kind, so the annotation is not rendered. ```ocaml -type t_any +type t_any : any ``` -Should be `type t_any : any` +A type with the `any` kind. ```ocaml -type t_float64 +type t_float64 : float64 ``` -Should be `type t_float64 : float64` +A type with the `float64` kind. ```ocaml -type t_bits32 +type t_bits32 : bits32 ``` -Should be `type t_bits32 : bits32` +A type with the `bits32` kind. ```ocaml -type t_bits64 +type t_bits64 : bits64 ``` -Should be `type t_bits64 : bits64` +A type with the `bits64` kind. ```ocaml -type t_word +type t_word : word ``` -Should be `type t_word : word` +A type with the `word` kind. ```ocaml -type t_void +type t_void : void ``` -Should be `type t_void : void` +A type with the `void` kind. ## Kind annotations with modalities ```ocaml -type t_portable +type t_portable : value mod portable ``` -Should be `type t_portable : value mod portable` +Kind annotation with a modality. ```ocaml -type t_contended +type t_contended : value mod contended ``` -Should be `type t_contended : value mod contended` +Kind annotation with a different modality. ```ocaml -type t_multi_mod +type t_multi_mod : value mod portable contended ``` -Should be `type t_multi_mod : value mod portable contended` +Kind annotation with multiple modalities. ## Kind annotations on parameterized types ```ocaml -type 'a imm_param +type ('a : immediate) imm_param ``` -The kind constraint on `'a` is not rendered. +A type parameter with a kind constraint. ```ocaml -type 'a float_param +type ('a : float64) float_param ``` -The kind constraint on `'a` is not rendered. +A type parameter with a different kind constraint. ```ocaml -type ('a, 'b) multi_kind +type (('a : immediate), ('b : float64)) multi_kind ``` Multiple kind-constrained parameters. @@ -91,15 +89,15 @@ Multiple kind-constrained parameters. ## Kind annotations with `with` constraints ```ocaml -type 'a t_with +type 'a t_with : immediate with 'a ``` -Should be `type 'a t_with : immediate with 'a` +Kind annotation with a `with` constraint. ## Kind annotations on type aliases ```ocaml -type t_alias = int +type t_alias : immediate = int ``` Has both a kind annotation and a manifest. @@ -107,11 +105,11 @@ Has both a kind annotation and a manifest. ## Kind-constrained polymorphism in values ```ocaml -val poly_immediate : 'a. 'a -> 'a +val poly_immediate : ('a : immediate). 'a -> 'a ``` -The kind constraint on `'a` is not rendered. +Kind constraint on a polymorphic type variable. ```ocaml -val poly_float64 : 'a. 'a -> 'a +val poly_float64 : ('a : float64). 'a -> 'a ``` -The kind constraint on `'a` is not rendered. +Kind constraint on a polymorphic type variable with a different kind. diff --git a/test/generators/markdown/Recent_impl-B.md b/test/generators/markdown/Recent_impl-B.md index 285b67286e..42ef387e4a 100644 --- a/test/generators/markdown/Recent_impl-B.md +++ b/test/generators/markdown/Recent_impl-B.md @@ -2,6 +2,6 @@ # Module `Recent_impl.B` ```ocaml -type t = +type t : immediate = | B ``` \ No newline at end of file diff --git a/test/xref2/canonical_nested.t/run.t b/test/xref2/canonical_nested.t/run.t index a4435450c3..ff24d6b43a 100644 --- a/test/xref2/canonical_nested.t/run.t +++ b/test/xref2/canonical_nested.t/run.t @@ -295,7 +295,8 @@ unresolved in the paths though: "params": [], "private_": "false", "manifest": "None", - "constraints": [] + "constraints": [], + "kind": "Default" }, "representation": "None" } diff --git a/test/xref2/deep_substitution.t/run.t b/test/xref2/deep_substitution.t/run.t index 909a11fdcf..da3b8c6ec7 100644 --- a/test/xref2/deep_substitution.t/run.t +++ b/test/xref2/deep_substitution.t/run.t @@ -57,7 +57,8 @@ its RHS correctly replaced with an `int` ] } }, - "constraints": [] + "constraints": [], + "kind": "Default" }, "representation": "None" } diff --git a/test/xref2/hidden_modules.t/run.t b/test/xref2/hidden_modules.t/run.t index 1febde41ea..f60519bd5b 100644 --- a/test/xref2/hidden_modules.t/run.t +++ b/test/xref2/hidden_modules.t/run.t @@ -109,7 +109,8 @@ There should be an expansion on `NotHidden` "params": [], "private_": "false", "manifest": "None", - "constraints": [] + "constraints": [], + "kind": "Default" }, "representation": "None" } From edb5e65b860a768de6463591495733906755f4e6 Mon Sep 17 00:00:00 2001 From: Arthur Wendling Date: Tue, 14 Apr 2026 13:25:59 +0200 Subject: [PATCH 3/4] OxCaml: test kind abbreviations --- src/document/generator.ml | 15 +-- src/xref2/test.md | 39 +++++--- test/generators/cases/oxcaml.mli | 56 ++++++++--- test/generators/html/Oxcaml.html | 149 +++++++++++++++++++++-------- test/generators/latex/Oxcaml.tex | 35 +++++-- test/generators/man/Oxcaml.3o | 100 +++++++++++++++---- test/generators/markdown/Oxcaml.md | 73 +++++++++++--- test/xref2/resolve/test.md | 99 ++++++++++--------- 8 files changed, 395 insertions(+), 171 deletions(-) diff --git a/src/document/generator.ml b/src/document/generator.ml index df96a9352f..daa939e3cf 100644 --- a/src/document/generator.ml +++ b/src/document/generator.ml @@ -309,8 +309,7 @@ module Make (Syntax : SYNTAX) = struct val kind_annotation : Odoc_model.Lang.KindAnnotation.t -> text - val with_kind_annotation : - Odoc_model.Lang.KindAnnotation.t -> text -> text + val with_kind_annotation : Odoc_model.Lang.KindAnnotation.t -> text -> text end = struct let rec te_variant (t : Odoc_model.Lang.TypeExpr.Polymorphic_variant.t) = let style_arguments ~constant arguments = @@ -453,8 +452,7 @@ module Make (Syntax : SYNTAX) = struct and with_kind_annotation kind base = match kind with | Odoc_model.Lang.KindAnnotation.Default -> base - | k -> - O.txt "(" ++ base ++ O.txt " : " ++ kind_annotation k ++ O.txt ")" + | k -> O.txt "(" ++ base ++ O.txt " : " ++ kind_annotation k ++ O.txt ")" and type_expr ?(needs_parentheses = false) (t : Odoc_model.Lang.TypeExpr.t) = @@ -880,9 +878,12 @@ module Make (Syntax : SYNTAX) = struct let base = format_param_str x |> Syntax.Type.handle_format_params in Type_expression.with_kind_annotation x.kind (O.txt base) | lst -> - let l = match delim with `parens -> "(" | `brackets -> "[" in - let r = match delim with `parens -> ")" | `brackets -> "]" in - O.txt l ++ O.list lst ~sep:(O.txt ", ") ~f:format_param ++ O.txt r + let left, right = + match delim with `parens -> ("(", ")") | `brackets -> ("[", "]") + in + O.txt left + ++ O.list lst ~sep:(O.txt ", ") ~f:format_param + ++ O.txt right let format_constraints constraints = O.list constraints ~f:(fun (t1, t2) -> diff --git a/src/xref2/test.md b/src/xref2/test.md index 6c4306b182..b64a29119a 100644 --- a/src/xref2/test.md +++ b/src/xref2/test.md @@ -211,7 +211,8 @@ and so we simply look up the type in the environment, giving a `Component.Type.t canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary, {Odoc_model.Lang.TypeDecl.id = @@ -248,7 +249,7 @@ and so we simply look up the type in the environment, giving a `Component.Type.t x); ihash = 622581103; ikey = "t_x.r_Root.p_None"}), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}} @@ -355,7 +356,8 @@ val module_ : Component.Module.t Component.Delayed.t = canonical = None; equation = {Odoc_xref2.Component.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -383,7 +385,8 @@ Odoc_xref2.Tools.Signature canonical = None; equation = {Odoc_xref2.Component.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -539,7 +542,9 @@ val m : Component.Element.module_type option = {Odoc_xref2.Component.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = + Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -1074,7 +1079,8 @@ Odoc_xref2.Tools.Signature canonical = None; equation = {Odoc_xref2.Component.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -2631,7 +2637,8 @@ let resolved = Common.compile_signature sg;; canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None} ``` @@ -2700,7 +2707,8 @@ let sg = Common.signature_of_mli_string test_data;; canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = false; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -2722,7 +2730,8 @@ let sg = Common.signature_of_mli_string test_data;; canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.ModuleType {Odoc_model.Lang.ModuleType.id = @@ -2765,7 +2774,8 @@ let sg = Common.signature_of_mli_string test_data;; u); ihash = 15973539; ikey = "t_u.r_Root.p_None"}), [])); - constraints = []})]; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default})]; w_expansion = None; w_expr = Odoc_model.Lang.ModuleType.U.Path @@ -2835,7 +2845,8 @@ Odoc_model.Lang.ModuleType.Path canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = Some (Odoc_model.Lang.TypeDecl.Representation.Variant @@ -3125,7 +3136,7 @@ let sg = Common.signature_of_mli_string test_data;; false), t), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Value {Odoc_model.Lang.Value.id = @@ -3214,7 +3225,7 @@ let sg = Common.signature_of_mli_string test_data;; false), t), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Value {Odoc_model.Lang.Value.id = @@ -3335,7 +3346,7 @@ let sg = Common.signature_of_mli_string test_data;; false), t), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Value {Odoc_model.Lang.Value.id = diff --git a/test/generators/cases/oxcaml.mli b/test/generators/cases/oxcaml.mli index 4ddc59a7bb..2edf2a7703 100644 --- a/test/generators/cases/oxcaml.mli +++ b/test/generators/cases/oxcaml.mli @@ -1,31 +1,54 @@ val f : int -> ('a . 'a -> 'a) -> unit (** Polymorphic arguments require parentheses *) -(** {1 Kind annotations on abstract types} *) - -type t_immediate : immediate -(** Kind annotation on abstract type. *) - -type t_value : value -(** [value] is the default kind, so the annotation is not rendered. *) +(** {1 Layouts} *) type t_any : any -(** A type with the [any] kind. *) +(** Layout [any]. *) + +type t_value_or_null : value_or_null +(** Layout [value_or_null]. *) type t_float64 : float64 -(** A type with the [float64] kind. *) +(** Layout [float64]. *) -type t_bits32 : bits32 -(** A type with the [bits32] kind. *) +type t_float32 : float32 +(** Layout [float32]. *) + +type t_word : word +(** Layout [word]. *) type t_bits64 : bits64 -(** A type with the [bits64] kind. *) +(** Layout [bits64]. *) -type t_word : word -(** A type with the [word] kind. *) +type t_bits32 : bits32 +(** Layout [bits32]. *) + +type t_vec128 : vec128 +(** Layout [vec128]. *) type t_void : void -(** A type with the [void] kind. *) +(** Layout [void]. *) + +(** {1 Kind abbreviations} *) + +type t_value : value +(** [value] is the default kind, so the annotation is not rendered. *) + +type t_immediate : immediate +(** Kind abbreviation [immediate]. *) + +type t_immediate64 : immediate64 +(** Kind abbreviation [immediate64]. *) + +type t_immutable_data : immutable_data +(** Kind abbreviation [immutable_data]. *) + +type t_sync_data : sync_data +(** Kind abbreviation [sync_data]. *) + +type t_mutable_data : mutable_data +(** Kind abbreviation [mutable_data]. *) (** {1 Kind annotations with modalities} *) @@ -38,6 +61,9 @@ type t_contended : value mod contended type t_multi_mod : value mod portable contended (** Kind annotation with multiple modalities. *) +type t_everything : float64 mod everything +(** The [everything] bounds abbreviation. *) + (** {1 Kind annotations on parameterized types} *) type ('a : immediate) imm_param diff --git a/test/generators/html/Oxcaml.html b/test/generators/html/Oxcaml.html index d6c805b251..c10ba74f28 100644 --- a/test/generators/html/Oxcaml.html +++ b/test/generators/html/Oxcaml.html @@ -16,12 +16,8 @@

    Module Oxcaml

    Polymorphic arguments require parentheses

    +

Layouts

+
+
+ + type t_any : any +

Layout any.

-

- - Kind annotations on abstract types -

-
- +
+ - type t_immediate : immediate + type t_value_or_null : value_or_null +
-

Kind annotation on abstract type.

+

Layout value_or_null.

+
+
+
+ + type t_float64 : float64 + +

Layout float64.

+
+
+
+ + type t_float32 : float32 + +

Layout float32.

+
+
+
+ + type t_word : word + +

Layout word.

+
+
+
+ + type t_bits64 : bits64 + +

Layout bits64.

+
+
+
+ + type t_bits32 : bits32 + +

Layout bits32.

+
+
+
+ + type t_vec128 : vec128 + +

Layout vec128.

+
+
+
+ + type t_void : void + +

Layout void.

+

+ Kind abbreviations +

@@ -95,55 +146,58 @@

-
- - type t_any : any -
-

A type with the any kind.

-
-
-
- - type t_float64 : float64 +
+ + + type t_immediate : immediate
-

A type with the float64 kind.

+

Kind abbreviation immediate.

-
- - type t_bits32 : bits32 +
+ + + type t_immediate64 : immediate64 +
-

A type with the bits32 kind.

+

Kind abbreviation immediate64.

-
- - type t_bits64 : bits64 +
+ + + type t_immutable_data : + immutable_data +
-

A type with the bits64 kind.

+
+

Kind abbreviation immutable_data.

-
- - type t_word : word +
+ + + type t_sync_data : sync_data
-

A type with the word kind.

+

Kind abbreviation sync_data.

-
- - type t_void : void +
+ + + type t_mutable_data : mutable_data +
-

A type with the void kind.

+

Kind abbreviation mutable_data.

@@ -184,6 +238,19 @@

Kind annotation with multiple modalities.

+
+
+ + + type t_everything : float64 + mod everything + + +
+
+

The everything bounds abbreviation.

+
+

Kind annotations on parameterized types diff --git a/test/generators/latex/Oxcaml.tex b/test/generators/latex/Oxcaml.tex index 38d94dd425..e369a3c933 100644 --- a/test/generators/latex/Oxcaml.tex +++ b/test/generators/latex/Oxcaml.tex @@ -1,22 +1,37 @@ \section{Module \ocamlinlinecode{Oxcaml}}\label{Oxcaml}% \label{Oxcaml--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : int \ocamltag{arrow}{$\rightarrow$} ('a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}) \ocamltag{arrow}{$\rightarrow$} unit}\begin{ocamlindent}Polymorphic arguments require parentheses\end{ocamlindent}% \medbreak -\subsection{Kind annotations on abstract types\label{Oxcaml--kind-annotations-on-abstract-types}}% -\label{Oxcaml--type-t_immediate}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate : immediate}\begin{ocamlindent}Kind annotation on abstract type.\end{ocamlindent}% +\subsection{Layouts\label{Oxcaml--layouts}}% +\label{Oxcaml--type-t_any}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}any : any}\begin{ocamlindent}Layout \ocamlinlinecode{any}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_value}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value}\begin{ocamlindent}\ocamlinlinecode{value} is the default kind, so the annotation is not rendered.\end{ocamlindent}% +\label{Oxcaml--type-t_value_or_null}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value\_\allowbreak{}or\_\allowbreak{}null : value\_\allowbreak{}or\_\allowbreak{}null}\begin{ocamlindent}Layout \ocamlinlinecode{value\_\allowbreak{}or\_\allowbreak{}null}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_float64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float64 : float64}\begin{ocamlindent}Layout \ocamlinlinecode{float64}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_float32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float32 : float32}\begin{ocamlindent}Layout \ocamlinlinecode{float32}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_word}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}word : word}\begin{ocamlindent}Layout \ocamlinlinecode{word}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_bits64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits64 : bits64}\begin{ocamlindent}Layout \ocamlinlinecode{bits64}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_any}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}any : any}\begin{ocamlindent}A type with the \ocamlinlinecode{any} kind.\end{ocamlindent}% +\label{Oxcaml--type-t_bits32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits32 : bits32}\begin{ocamlindent}Layout \ocamlinlinecode{bits32}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_float64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float64 : float64}\begin{ocamlindent}A type with the \ocamlinlinecode{float64} kind.\end{ocamlindent}% +\label{Oxcaml--type-t_vec128}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}vec128 : vec128}\begin{ocamlindent}Layout \ocamlinlinecode{vec128}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_bits32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits32 : bits32}\begin{ocamlindent}A type with the \ocamlinlinecode{bits32} kind.\end{ocamlindent}% +\label{Oxcaml--type-t_void}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}void : void}\begin{ocamlindent}Layout \ocamlinlinecode{void}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_bits64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits64 : bits64}\begin{ocamlindent}A type with the \ocamlinlinecode{bits64} kind.\end{ocamlindent}% +\subsection{Kind abbreviations\label{Oxcaml--kind-abbreviations}}% +\label{Oxcaml--type-t_value}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value}\begin{ocamlindent}\ocamlinlinecode{value} is the default kind, so the annotation is not rendered.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_immediate}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate : immediate}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{immediate}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_immediate64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate64 : immediate64}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{immediate64}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_word}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}word : word}\begin{ocamlindent}A type with the \ocamlinlinecode{word} kind.\end{ocamlindent}% +\label{Oxcaml--type-t_immutable_data}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immutable\_\allowbreak{}data : immutable\_\allowbreak{}data}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{immutable\_\allowbreak{}data}.\end{ocamlindent}% \medbreak -\label{Oxcaml--type-t_void}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}void : void}\begin{ocamlindent}A type with the \ocamlinlinecode{void} kind.\end{ocamlindent}% +\label{Oxcaml--type-t_sync_data}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}sync\_\allowbreak{}data : sync\_\allowbreak{}data}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{sync\_\allowbreak{}data}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_mutable_data}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}mutable\_\allowbreak{}data : mutable\_\allowbreak{}data}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{mutable\_\allowbreak{}data}.\end{ocamlindent}% \medbreak \subsection{Kind annotations with modalities\label{Oxcaml--kind-annotations-with-modalities}}% \label{Oxcaml--type-t_portable}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}portable : value \ocamltag{keyword}{mod} portable}\begin{ocamlindent}Kind annotation with a modality.\end{ocamlindent}% @@ -25,6 +40,8 @@ \subsection{Kind annotations with modalities\label{Oxcaml--kind-annotations-with \medbreak \label{Oxcaml--type-t_multi_mod}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}multi\_\allowbreak{}mod : value \ocamltag{keyword}{mod} portable contended}\begin{ocamlindent}Kind annotation with multiple modalities.\end{ocamlindent}% \medbreak +\label{Oxcaml--type-t_everything}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}everything : float64 \ocamltag{keyword}{mod} everything}\begin{ocamlindent}The \ocamlinlinecode{everything} bounds abbreviation.\end{ocamlindent}% +\medbreak \subsection{Kind annotations on parameterized types\label{Oxcaml--kind-annotations-on-parameterized-types}}% \label{Oxcaml--type-imm_param}\ocamlcodefragment{\ocamltag{keyword}{type} ('a : immediate) imm\_\allowbreak{}param}\begin{ocamlindent}A type parameter with a kind constraint.\end{ocamlindent}% \medbreak diff --git a/test/generators/man/Oxcaml.3o b/test/generators/man/Oxcaml.3o index 9b8923f93b..38d671d5e1 100644 --- a/test/generators/man/Oxcaml.3o +++ b/test/generators/man/Oxcaml.3o @@ -19,67 +19,120 @@ Polymorphic arguments require parentheses .nf .sp .in 3 -\fB1 Kind annotations on abstract types\fR +\fB1 Layouts\fR .in .sp -\f[CB]type\fR t_immediate : immediate +\f[CB]type\fR t_any : any .fi .br .ti +2 -Kind annotation on abstract type\. +Layout any\. .nf .sp -\f[CB]type\fR t_value +\f[CB]type\fR t_value_or_null : value_or_null .fi .br .ti +2 -value is the default kind, so the annotation is not rendered\. +Layout value_or_null\. .nf .sp -\f[CB]type\fR t_any : any +\f[CB]type\fR t_float64 : float64 .fi .br .ti +2 -A type with the any kind\. +Layout float64\. .nf .sp -\f[CB]type\fR t_float64 : float64 +\f[CB]type\fR t_float32 : float32 .fi .br .ti +2 -A type with the float64 kind\. +Layout float32\. .nf .sp -\f[CB]type\fR t_bits32 : bits32 +\f[CB]type\fR t_word : word .fi .br .ti +2 -A type with the bits32 kind\. +Layout word\. .nf .sp \f[CB]type\fR t_bits64 : bits64 .fi .br .ti +2 -A type with the bits64 kind\. +Layout bits64\. .nf .sp -\f[CB]type\fR t_word : word +\f[CB]type\fR t_bits32 : bits32 .fi .br .ti +2 -A type with the word kind\. +Layout bits32\. +.nf +.sp +\f[CB]type\fR t_vec128 : vec128 +.fi +.br +.ti +2 +Layout vec128\. .nf .sp \f[CB]type\fR t_void : void .fi .br .ti +2 -A type with the void kind\. +Layout void\. .nf .sp .in 3 -\fB2 Kind annotations with modalities\fR +\fB2 Kind abbreviations\fR +.in +.sp +\f[CB]type\fR t_value +.fi +.br +.ti +2 +value is the default kind, so the annotation is not rendered\. +.nf +.sp +\f[CB]type\fR t_immediate : immediate +.fi +.br +.ti +2 +Kind abbreviation immediate\. +.nf +.sp +\f[CB]type\fR t_immediate64 : immediate64 +.fi +.br +.ti +2 +Kind abbreviation immediate64\. +.nf +.sp +\f[CB]type\fR t_immutable_data : immutable_data +.fi +.br +.ti +2 +Kind abbreviation immutable_data\. +.nf +.sp +\f[CB]type\fR t_sync_data : sync_data +.fi +.br +.ti +2 +Kind abbreviation sync_data\. +.nf +.sp +\f[CB]type\fR t_mutable_data : mutable_data +.fi +.br +.ti +2 +Kind abbreviation mutable_data\. +.nf +.sp +.in 3 +\fB3 Kind annotations with modalities\fR .in .sp \f[CB]type\fR t_portable : value \f[CB]mod\fR portable @@ -103,8 +156,15 @@ Kind annotation with a different modality\. Kind annotation with multiple modalities\. .nf .sp +\f[CB]type\fR t_everything : float64 \f[CB]mod\fR everything +.fi +.br +.ti +2 +The everything bounds abbreviation\. +.nf +.sp .in 3 -\fB3 Kind annotations on parameterized types\fR +\fB4 Kind annotations on parameterized types\fR .in .sp \f[CB]type\fR ('a : immediate) imm_param @@ -129,7 +189,7 @@ Multiple kind-constrained parameters\. .nf .sp .in 3 -\fB4 Kind annotations with with constraints\fR +\fB5 Kind annotations with with constraints\fR .in .sp \f[CB]type\fR 'a t_with : immediate \f[CB]with\fR \f[CB]'a\fR @@ -140,7 +200,7 @@ Kind annotation with a with constraint\. .nf .sp .in 3 -\fB5 Kind annotations on type aliases\fR +\fB6 Kind annotations on type aliases\fR .in .sp \f[CB]type\fR t_alias : immediate = int @@ -151,7 +211,7 @@ Has both a kind annotation and a manifest\. .nf .sp .in 3 -\fB6 Kind-constrained polymorphism in values\fR +\fB7 Kind-constrained polymorphism in values\fR .in .sp \f[CB]val\fR poly_immediate : ('a : immediate)\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR diff --git a/test/generators/markdown/Oxcaml.md b/test/generators/markdown/Oxcaml.md index b55d9145f7..4ab0bde3c8 100644 --- a/test/generators/markdown/Oxcaml.md +++ b/test/generators/markdown/Oxcaml.md @@ -7,47 +7,85 @@ val f : int -> ('a. 'a -> 'a) -> unit Polymorphic arguments require parentheses -## Kind annotations on abstract types +## Layouts ```ocaml -type t_immediate : immediate +type t_any : any ``` -Kind annotation on abstract type. +Layout `any`. ```ocaml -type t_value +type t_value_or_null : value_or_null ``` -`value` is the default kind, so the annotation is not rendered. +Layout `value_or_null`. ```ocaml -type t_any : any +type t_float64 : float64 ``` -A type with the `any` kind. +Layout `float64`. ```ocaml -type t_float64 : float64 +type t_float32 : float32 ``` -A type with the `float64` kind. +Layout `float32`. ```ocaml -type t_bits32 : bits32 +type t_word : word ``` -A type with the `bits32` kind. +Layout `word`. ```ocaml type t_bits64 : bits64 ``` -A type with the `bits64` kind. +Layout `bits64`. ```ocaml -type t_word : word +type t_bits32 : bits32 ``` -A type with the `word` kind. +Layout `bits32`. + +```ocaml +type t_vec128 : vec128 +``` +Layout `vec128`. ```ocaml type t_void : void ``` -A type with the `void` kind. +Layout `void`. + + +## Kind abbreviations + +```ocaml +type t_value +``` +`value` is the default kind, so the annotation is not rendered. + +```ocaml +type t_immediate : immediate +``` +Kind abbreviation `immediate`. + +```ocaml +type t_immediate64 : immediate64 +``` +Kind abbreviation `immediate64`. + +```ocaml +type t_immutable_data : immutable_data +``` +Kind abbreviation `immutable_data`. + +```ocaml +type t_sync_data : sync_data +``` +Kind abbreviation `sync_data`. + +```ocaml +type t_mutable_data : mutable_data +``` +Kind abbreviation `mutable_data`. ## Kind annotations with modalities @@ -67,6 +105,11 @@ type t_multi_mod : value mod portable contended ``` Kind annotation with multiple modalities. +```ocaml +type t_everything : float64 mod everything +``` +The `everything` bounds abbreviation. + ## Kind annotations on parameterized types diff --git a/test/xref2/resolve/test.md b/test/xref2/resolve/test.md index 8f2288adf7..67c97f503c 100644 --- a/test/xref2/resolve/test.md +++ b/test/xref2/resolve/test.md @@ -106,7 +106,8 @@ Simplest possible resolution: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary, {Odoc_model.Lang.TypeDecl.id = @@ -144,7 +145,7 @@ Simplest possible resolution: t); ihash = 1016576344; ikey = "t_t.r_Root.p_None"}), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}; @@ -282,7 +283,8 @@ Basic resolution 2, environment lookup: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}); @@ -325,7 +327,7 @@ Basic resolution 2, environment lookup: ihash = 716453475; ikey = "m_M.r_Root.p_None"}, t)), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}; @@ -437,7 +439,8 @@ Basic resolution 3, module type: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -489,7 +492,8 @@ Basic resolution 3, module type: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -531,18 +535,12 @@ Basic resolution 3, module type: manifest = Some (Odoc_model.Lang.TypeExpr.Constr - (`Resolved - (`Type - (`Identifier - {Odoc_model__Paths_types.iv = ...; ihash = ...; - ikey = ...}, - ...)), - ...)); - constraints = ...}; - representation = ...}); - ...]; - compiled = ...; removed = ...; doc = ...}; - expansion = ...; linked = ...; source_loc = ...; canonical = ...} + (`Resolved (`Type (`Identifier ...)), ...)); + constraints = ...; kind = ...}; + representation = ...}); + ...]; + compiled = ...; removed = ...; doc = ...}; + expansion = ...; linked = ...; source_loc = ...; canonical = ...} ``` This example is very similar but there is one more level of nesting of the modules: @@ -665,7 +663,8 @@ Basic resolution 4, module type: equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -736,7 +735,7 @@ Basic resolution 4, module type: `Root (Some {Odoc_model__Paths_types.iv - = `Page (None, ...); + = `Page (...); ihash = ...; ikey = ...}, ...); @@ -917,7 +916,8 @@ and then we can look up the type `t`. equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -989,7 +989,9 @@ and then we can look up the type `t`. {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = + Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -998,11 +1000,7 @@ and then we can look up the type `t`. p_path = `Resolved (`Identifier - {Odoc_model__Paths_types.iv = - `ModuleType - ({Odoc_model__Paths_types.iv = ...; - ihash = ...; ikey = ...}, - ...); + {Odoc_model__Paths_types.iv = `ModuleType (...); ihash = ...; ikey = ...})}); canonical = ...; hidden = ...}); ...]; @@ -1121,7 +1119,8 @@ and then we can look up the type `t`. equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -1675,7 +1674,8 @@ Resolve a module alias: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}); @@ -1766,10 +1766,10 @@ Resolve a module alias: ihash = 814134997; ikey = "m_B.r_Ro"... (* string length 17; truncated *)}, - false)), + ...)), ...)), ...)); - constraints = ...}; + constraints = ...; kind = ...}; representation = ...}); ...]; compiled = ...; removed = ...; doc = ...}; @@ -1845,7 +1845,8 @@ Resolve a module alias: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}); @@ -1926,7 +1927,7 @@ Resolve a module alias: Root); ihash = 818126955; ikey = - "r_Root.p_No"... (* string length 13; truncated *)}, + "r_Root.p_N"... (* string length 13; truncated *)}, B); ihash = 814134997; ikey = "m_B.r_Ro"... (* string length 17; truncated *)}, @@ -2014,7 +2015,8 @@ Resolve a functor: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -2096,7 +2098,8 @@ Resolve a functor: equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -2116,16 +2119,14 @@ Resolve a functor: Root); ihash = 818126955; ikey = - "r_Root.p_"... (* string length 13; truncated *)}, + "r_Root.p"... (* string length 13; truncated *)}, S); ihash = 527535255; ikey = "mt_S.r_R"... (* string length 18; truncated *)})}}, Odoc_model.Lang.ModuleType.Functor (Odoc_model.Lang.FunctorParameter.Named - {Odoc_model.Lang.FunctorParameter.id = - {Odoc_model__Paths_types.iv = ...; ihash = ...; ikey = ...}; - expr = ...}, + {Odoc_model.Lang.FunctorParameter.id = ...; expr = ...}, ...))); canonical = ...; hidden = ...}); ...]; @@ -2228,7 +2229,8 @@ Resolve a functor: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -2311,7 +2313,8 @@ Resolve a functor: equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -2331,21 +2334,17 @@ Resolve a functor: Root); ihash = 818126955; ikey = - "r_Root.p_"... (* string length 13; truncated *)}, + "r_Root.p"... (* string length 13; truncated *)}, S); ihash = 527535255; ikey = "mt_S.r_R"... (* string length 18; truncated *)})}}, Odoc_model.Lang.ModuleType.Path {Odoc_model.Lang.ModuleType.p_expansion = - Some - (Odoc_model.Lang.ModuleType.Signature - {Odoc_model.Lang.Signature.items = [...]; compiled = ...; - removed = ...; doc = ...}); - p_path = ...}))}; - ...]; - compiled = ...; removed = ...; doc = ...}; - expansion = ...; linked = ...; source_loc = ...; canonical = ...} + Some (Odoc_model.Lang.ModuleType.Signature ...); p_path = ...}))}; + ...]; + compiled = ...; removed = ...; doc = ...}; + expansion = ...; linked = ...; source_loc = ...; canonical = ...} ``` ```ocaml skip From d0a2d4e0dc3abd4bccec3cb8ac8da0e87da8c6fe Mon Sep 17 00:00:00 2001 From: Arthur Wendling Date: Tue, 14 Apr 2026 13:36:46 +0200 Subject: [PATCH 4/4] OxCaml: fix OCaml CI, ignore recent_impl test --- test/generators/gen_rules/gen_rules.ml | 2 +- test/generators/gen_rules_lib.ml | 14 ++ test/generators/html/Recent_impl-B.html | 3 +- test/generators/latex/Recent_impl.B.tex | 2 +- test/generators/link.dune.inc | 160 ++++++++++++++++------ test/generators/man/Recent_impl.B.3o | 2 +- test/generators/markdown/Recent_impl-B.md | 2 +- 7 files changed, 139 insertions(+), 46 deletions(-) diff --git a/test/generators/gen_rules/gen_rules.ml b/test/generators/gen_rules/gen_rules.ml index e20d5f64ab..ad9c1bd4d8 100644 --- a/test/generators/gen_rules/gen_rules.ml +++ b/test/generators/gen_rules/gen_rules.ml @@ -62,7 +62,7 @@ let constraints = ("ocamlary.mli", Min "4.14"); ("recent.mli", Min "5.4"); ("labels.mli", Min "4.09"); - ("recent_impl.ml", Min "4.09"); + ("recent_impl.ml", MinNotOxCaml "4.09"); ("bugs_pre_410.ml", Max "4.09"); ("module_type_subst.mli", Min "4.13"); ("class_comments.mli", Min "4.08"); diff --git a/test/generators/gen_rules_lib.ml b/test/generators/gen_rules_lib.ml index b3340e0221..dff635cf1c 100644 --- a/test/generators/gen_rules_lib.ml +++ b/test/generators/gen_rules_lib.ml @@ -7,6 +7,7 @@ type enabledif = | Max of string | MinMax of string * string | OxCaml + | MinNotOxCaml of string type test_case = { input : Fpath.t; @@ -54,6 +55,19 @@ module Dune = struct ]; ] | Some OxCaml -> [ List [ Atom "enabled_if"; Atom "%{ocaml-config:ox}" ] ] + | Some (MinNotOxCaml v) -> + [ + List + [ + Atom "enabled_if"; + List + [ + Atom "and"; + List [ Atom ">="; Atom "%{ocaml_version}"; Atom v ]; + List [ Atom "not"; Atom "%{ocaml-config:ox}" ]; + ]; + ]; + ] | None -> [] let run cmd = List (Atom "run" :: arg_list cmd) diff --git a/test/generators/html/Recent_impl-B.html b/test/generators/html/Recent_impl-B.html index 6b08e2f218..3fe204717a 100644 --- a/test/generators/html/Recent_impl-B.html +++ b/test/generators/html/Recent_impl-B.html @@ -19,8 +19,7 @@

Module Recent_impl.B

- type t : immediate - = + type t =
  1. diff --git a/test/generators/latex/Recent_impl.B.tex b/test/generators/latex/Recent_impl.B.tex index cacfd7a923..38b1c5c050 100644 --- a/test/generators/latex/Recent_impl.B.tex +++ b/test/generators/latex/Recent_impl.B.tex @@ -1,5 +1,5 @@ \section{Module \ocamlinlinecode{Recent\_\allowbreak{}impl.\allowbreak{}B}}\label{Recent_impl-B}% -\label{Recent_impl-B--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t : immediate = }\\ +\label{Recent_impl-B--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }\\ \begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B}}\label{Recent_impl-B--type-t.B}\\ \end{ocamltabular}% \\ diff --git a/test/generators/link.dune.inc b/test/generators/link.dune.inc index e5d3455c96..20f9cfc96c 100644 --- a/test/generators/link.dune.inc +++ b/test/generators/link.dune.inc @@ -617,7 +617,9 @@ (action (run ocamlc -c -bin-annot -o %{target} %{dep:cases/recent_impl.ml})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (target recent_impl.odoc) @@ -625,7 +627,9 @@ (action (run odoc compile -o %{target} %{dep:recent_impl.cmt})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (target recent_impl.odocl) @@ -633,7 +637,9 @@ (action (run odoc link -o %{target} %{dep:recent_impl.odoc})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (target section.cmti) @@ -12195,49 +12201,63 @@ . %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.html Recent_impl.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo.html Recent_impl-Foo.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-A.html Recent_impl-Foo-A.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-B.html Recent_impl-Foo-B.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-B.html Recent_impl-B.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S.html Recent_impl-module-type-S.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12246,7 +12266,9 @@ Recent_impl-module-type-S-F.html Recent_impl-module-type-S-F.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12255,7 +12277,9 @@ Recent_impl-module-type-S-F-argument-1-_.html Recent_impl-module-type-S-F-argument-1-_.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12264,7 +12288,9 @@ Recent_impl-module-type-S-X.html Recent_impl-module-type-S-X.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir html @@ -12276,14 +12302,18 @@ recent_impl.targets.gen (run odoc html-targets -o . %{dep:../recent_impl.odocl} --flat))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir latex @@ -12300,21 +12330,27 @@ gen %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.tex Recent_impl.tex.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.B.tex Recent_impl.B.tex.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir latex @@ -12326,14 +12362,18 @@ recent_impl.targets.gen (run odoc latex-targets -o . %{dep:../recent_impl.odocl}))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir man @@ -12355,42 +12395,54 @@ gen %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.3o Recent_impl.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.Foo.3o Recent_impl.Foo.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.Foo.A.3o Recent_impl.Foo.A.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.Foo.B.3o Recent_impl.Foo.B.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.B.3o Recent_impl.B.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir man @@ -12402,14 +12454,18 @@ recent_impl.targets.gen (run odoc man-targets -o . %{dep:../recent_impl.odocl}))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir markdown @@ -12435,56 +12491,72 @@ gen %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.md Recent_impl.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo.md Recent_impl-Foo.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-A.md Recent_impl-Foo-A.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-B.md Recent_impl-Foo-B.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-B.md Recent_impl-B.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S.md Recent_impl-module-type-S.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S-F.md Recent_impl-module-type-S-F.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12493,14 +12565,18 @@ Recent_impl-module-type-S-F-argument-1-_.md Recent_impl-module-type-S-F-argument-1-_.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S-X.md Recent_impl-module-type-S-X.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir markdown @@ -12512,14 +12588,18 @@ recent_impl.targets.gen (run odoc markdown-targets -o . %{dep:../recent_impl.odocl}))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir html diff --git a/test/generators/man/Recent_impl.B.3o b/test/generators/man/Recent_impl.B.3o index 05d780c9d0..60192553b3 100644 --- a/test/generators/man/Recent_impl.B.3o +++ b/test/generators/man/Recent_impl.B.3o @@ -11,7 +11,7 @@ Recent_impl\.B .SH Documentation .sp .nf -\f[CB]type\fR t : immediate = +\f[CB]type\fR t = .br .ti +2 | \f[CB]B\fR diff --git a/test/generators/markdown/Recent_impl-B.md b/test/generators/markdown/Recent_impl-B.md index 42ef387e4a..285b67286e 100644 --- a/test/generators/markdown/Recent_impl-B.md +++ b/test/generators/markdown/Recent_impl-B.md @@ -2,6 +2,6 @@ # Module `Recent_impl.B` ```ocaml -type t : immediate = +type t = | B ``` \ No newline at end of file