jon.recoil.org

Module Types.Lpoly

Tracks layout polymorphism state for a value binding. A value is either pending generalization (pending) or has a finalized list of layout vars (determined) at generic level. An empty list means the value is not layout-polymorphic.

Layout poly cannot be inferred from usages, so a value description should have determined layout poly. However, in type_let we add variables to the environment before type-checking the RHS and generalizing. Therefore, the value description uses a mutable cell that is filled in during generalization. After filling, layout poly is determined and should not be mutated again. We explicitly distinguish the two stages for extra safety.

type t
val determined : Jkind_types.Sort.var list -> t

determined vars creates a finalized value with the given generalized layout vars. Pass [] for a non-layout-polymorphic value.

val pending : loc:Location.t -> t

pending ~loc creates a value pending layout generalization, where loc is the source location that requested polymorphism.

val get_exn : t -> Jkind_types.Sort.var list

Assert that layout poly is determined and return the generalized vars.

val is_empty_exn : t -> bool

Returns true for determined [], false otherwise. Raise exception if pending.

val generalize : on_determined:(unit -> unit) -> on_to_generalize:(Location.t -> Jkind_types.Sort.var list) -> t -> unit

Dispatch on the state of t:

  • If pending (pending loc), call on_to_generalize loc, transition to finalized with the returned vars.
  • If finalized (determined _), call on_determined.