Module Out_type

Functions for representing type expressions and module types as outcometree (with as 'a aliases for cycles) and printing them. All functions below depends on global contexts that keep track of

Whenever possible, it is advised to use the simpler functions available in Printtyp which take care of setting up this naming context. The functions below are needed when one needs to share a common naming context (or part of it) between different calls to printing functions (or in order to implement Printtyp).

Wrapping functions

val wrap_printing_env : error:bool -> Env.t -> (unit -> 'a) -> 'a

Call the function using the environment for type path shortening This affects all the printing and tree cration functions functions below Also, if ~error:true, then disable the loading of cmis

val with_labels : bool -> (unit -> 'a) -> 'a

with_labels false disable labels in function types

Printing idents and paths

val tree_of_path : ?disambiguation:bool -> Path.t -> Outcometree.out_ident
val namespaced_tree_of_path : Shape.Sig_component_kind.t -> Path.t -> Outcometree.out_ident
val tree_of_type_path : Path.t -> Outcometree.out_ident

Specialized functions for printing types with short-paths

val same_path : Types.type_expr -> Types.type_expr -> bool

same_path ty ty2 is true when there is an equation ty=ty2 in the short-path scope

val rewrite_double_underscore_paths : Env.t -> Path.t -> Path.t

Simple heuristic to rewrite Foo__bar.* as Foo.Bar.* when Foo.Bar is an alias for Foo__bar. This pattern is used by the stdlib.

Printing type expressions

Printing type expressions requires to translate the internal graph based representation into to an Outcometree closer to the source syntax. In order to do so, the printing is generally split in three phase:

val prepare_for_printing : Types.type_expr list -> unit

prepare_for_printing resets the global naming environment, a la reset_except_conflicts, and prepares the types for printing by reserving variable names and marking cycles. Any type variables that are shared between multiple types in the input list will be given the same name when printed with prepared_type_expr.

val add_type_to_preparation : Types.type_expr -> unit

add_type_to_preparation ty extend a previous type expression preparation to the type expression ty

type type_or_scheme =
  1. | Type
  2. | Type_scheme

In Type_scheme mode, non-generic types variables are printed as weakly polymorphic type variables.

tree_of_typexp generate the outcometree for a prepared type expression.

val prepared_type_scheme : Types.type_expr Format_doc.printer
val prepared_type_expr : Types.type_expr Format_doc.printer

The printers prepared_type_expr and prepared_type_scheme should only be used on prepared types. Types can be prepared by initially calling prepare_for_printing or adding them later to the preparation with add_type_to_preparation.

Calling this function on non-prepared types may cause a stack overflow (see #8860) due to cycles in the printed types.

See Printtyp.type_expr for a safer but less flexible printer.

val type_expr_with_reserved_names : Types.type_expr Format_doc.printer

type_expr_with_reserved_names can print "half-prepared" type expression. A "half-prepared" type expression should have had its names reserved (with Variable_names.reserve), but should not have had its cycles marked.

type 'a diff =
  1. | Same of 'a
  2. | Diff of 'a * 'a
val hide_variant_name : Types.type_expr -> Types.type_expr
val prepare_type_constructor_arguments : Types.constructor_arguments -> unit

Label and constructors

val tree_of_constructor_arguments : Types.constructor_arguments -> Outcometree.out_type list
val add_constructor_to_preparation : Types.constructor_declaration -> unit
val extension_constructor_args_and_ret_type_subtree : Types.constructor_arguments -> Types.type_expr option -> Outcometree.out_type list * Outcometree.out_type option
val add_extension_constructor_to_preparation : Types.extension_constructor -> unit
val prepared_extension_constructor : Ident.t -> Types.extension_constructor Format_doc.printer

Declarations

val add_type_declaration_to_preparation : Ident.t -> Types.type_declaration -> unit
val prepared_type_declaration : Ident.t -> Types.type_declaration Format_doc.printer
val tree_of_value_description : Ident.t -> Types.value_description -> Outcometree.out_sig_item
val tree_of_modtype_declaration : Ident.t -> Types.modtype_declaration -> Outcometree.out_sig_item

Module types

val tree_of_module : Ident.t -> ?ellipsis:bool -> Types.module_type -> Types.rec_status -> Outcometree.out_sig_item
val tree_of_signature : Types.signature -> Outcometree.out_sig_item list
val prepare_class_type : Types.class_type -> unit
val print_items : (Env.t -> Types.signature_item -> 'a option) -> Env.t -> Types.signature_item list -> (Outcometree.out_sig_item * 'a option) list

Toplevel printing

Naming contexts

module Out_name : sig ... end

Path name, which were mutable at some point

module Ident_names : sig ... end

Disambiguation for identifiers, e.g. the two type constructors named t in the type of f in

module Ident_conflicts : sig ... end

The Ident_conflicts module keeps track of conflicts arising when attributing names to identifiers and provides functions that can print explanations for these conflict in error messages

module Variable_names : sig ... end

Naming choice for type variable names ('a, 'b, ...), for instance the two classes of distinct type variables in

module Internal_names : sig ... end

Register internal typechecker names ($0,$a) appearing in the outcometree

val reset : unit -> unit

Reset all contexts

val reset_except_conflicts : unit -> unit

Reset all contexts except for conflicts