Wax_lang.InferSourceThe inferred-type lattice used while type checking, the mutable cells (Cell) that carry it, and the shared printers/type aliases built on top.
Output printers wrapping Output so they take a Format.formatter directly (rather than a Wax_utils.Printer.t), for use in diagnostics.
A mutable cell carrying a value, backed by union-find: merge unifies two cells so they share one value, and get resolves a cell to that value.
type inferred_valtype = {typ : Ast.valtype;internal : Internal.valtype;anon_comptype : Ast.comptype option;For a synthesized reference type with no source name — a string's byte array, an inline function-type cast target — the referenced composite type, which diagnostics render inline (e.g. [mut i8]) instead of the meaningless synthetic <..> name kept in typ. None otherwise.
}type inferred_type = | UnknownThe genuinely polymorphic type of a value taken off the stack of unreachable or branch-terminated code. No error has been reported for it: an instruction that needs its operand's concrete type to be compiled reports one when it meets an Unknown operand.
| ErrorThe recovery type of a value whose own typing already failed. An error has already been reported, so Error propagates silently — treated like Unknown but raising no further error.
| UnknownRefA non-null reference of unknown heap type — the Wax counterpart of the Wasm (ref bot). Produced when a reference is recovered from an otherwise-polymorphic value (null! / br_on_null on an Unknown operand or a bare null). Behaves like Unknown everywhere except that subtype knows it is a reference: a subtype of every reference type but of no numeric or vector type.
| NullA bare null literal: a null reference whose heap type is not yet fixed. Narrowed to a concrete reference type by context; with none it takes the bottom of the relevant hierarchy.
| NumberAny numeric literal: narrows to i32, i64, f32 or f64, defaulting to i32. The bottom of the flexible-literal lattice.
*)| Int8A packed narrow read — a load8 or an i8 struct/array field — which yields an i32 value tracked as 8-bit wide so a following widening cast (as i64_s/i64_u) fuses into the read. Defaults to i32.
| Int16A packed narrow read — a load16 or an i16 field — as Int8 but 16-bit. Defaults to i32.
| IntAn integer literal committed to the integer family (e.g. by a bitwise or shift operator): narrows to i32 or i64, defaulting to i32. It can no longer become a float by inference — only an explicit as cast, which emits a conversion, does that.
| LargeIntA numeric literal too large for i32: narrows to i64, f32 or f64 (never i32), defaulting to i64. Despite the name it is float-capable and so belongs to the number family, not Int — it is Number with i32 excluded by magnitude. Lets a decompiled out-of-range constant keep its width instead of overflowing, and renders as large number.
| FloatA floating-point literal: narrows to f32 or f64, defaulting to f64.
*)| Valtype of inferred_valtype| Collecting of collectingTransient state of a fresh cell used as the result / branch-target type of a block whose result is being inferred. A value checked against it is recorded into collected rather than unified, then joined by val_lub once the body is typed. The cell never escapes inference, so other uses treat it like Unknown.
and collecting = {mutable collected : (Ast.location option * inferred_type Cell.t) list;Each value reaching the block's exit, paired with the location it was produced at (when known) so a join failure can point at the offending exits.
*)mutable exacts : (Ast.location option * inferred_type Cell.t) list;Snapshots of the natural types of values delivered by br_if (and other pass-through branches). Such a value continues on the stack and is typed as the block result, so — unlike an ordinary exit, which need only be a subtype — its type must be exactly the result. Recorded before the delivery pins the live cell; used to decide the keep-bool (drop the annotation only if every exact matches it) and to reject an inferred block whose result would differ from an exact.
declared : inferred_type Cell.t option;The single result type the block already carries while being inferred — a Wasm->Wax annotation under test, or None when omitted.
mutable needed : bool;Set when declared is relied upon in a way the join cannot re-derive, forcing the annotation to be kept.
}Render an inferred type into a styled printer, so it shares a diagnostic message's colour theme and width (an unresolved one prints as any). This is what the typer's Message typ combinator is built on.
Render an inferred type as plain (uncoloured) text — for the editor's hover string and the stack/debug printers. Diagnostics use output_inferred_type_styled instead.
Whether a cell resolves to Unknown, Error or UnknownRef — the common "no concrete type known" test.
The numeric value types, and shared cells holding them. A concrete base type is never re-resolved during inference, so a base-type cell's value never changes and a single shared cell per type can stand in for a fresh one.
valtype_cell v wraps a fully resolved value type in a fresh cell.