Documentation
¶
Overview ¶
Package typ defines the core Type interface and type implementations.
All types in the type system implement the Type interface, which provides kind classification, string representation, hashing, and equality. Types are designed to be immutable and structurally comparable.
Primitive Types ¶
Nil, Boolean, Number, Integer, String are singleton types representing Lua primitives. Integer is a subtype of Number.
Special Types ¶
Any: Explicit dynamic type (opt-out of type checking). Operations on Any are permissive but lose type safety.
Unknown: Unresolved type information. Forces narrowing/inference rather than silently permitting operations.
Never: Bottom type (empty set). Represents unreachable code or impossible values. Never is a subtype of all types.
Self: Placeholder for the receiver type in method signatures. Substituted with the actual type when methods are resolved.
Composite Types ¶
See the respective type files for: Function, Record, Union, Optional, Intersection, Tuple, Array, Map, Generic, Alias, Interface, and others.
Index ¶
- Constants
- Variables
- func DepthExceeded(depth int) bool
- func Format(t Type, opts FormatOptions) string
- func FormatShort(t Type) string
- func GuardForDepth(maxDepth int) internal.RecursionGuard
- func HasKnownType(types []Type) bool
- func IsAbsentOrUnknown(t Type) bool
- func IsAny(t Type) bool
- func IsBinaryMetamethod(m Metamethod) bool
- func IsComparisonMetamethod(m Metamethod) bool
- func IsMetamethod(name string) bool
- func IsNever(t Type) bool
- func IsRecursiveRef(t Type, rec *Recursive) bool
- func IsRefinableAnnotation(t Type) bool
- func IsSoft(t Type, policy SoftPolicy) bool
- func IsUnaryMetamethod(m Metamethod) bool
- func IsUnknown(t Type) bool
- func IsUnknownOnlyOrEmpty(types []Type) bool
- func IsUnknownOrNil(t Type) bool
- func LiteralEquals(a, b *Literal) bool
- func MinRequiredArgs(f *Function) int
- func NewDeepGuard() internal.RecursionGuard
- func NewGuard() internal.RecursionGuard
- func TypeEquals(a, b Type) bool
- func TypeMatchesLiteral(t Type, lit *Literal) bool
- func TypeString(t Type) string
- func Visit[R any](t Type, v Visitor[R]) R
- func VisitWithGuard[R any](t Type, guard internal.RecursionGuard, onCycle R, ...) R
- func WithGuard[R any](t Type, guard internal.RecursionGuard, onCycle R, ...) R
- type Alias
- type Annotated
- type Annotation
- type Array
- type CaptureInfo
- type CaptureMode
- type EffectInfo
- type Field
- type FieldAccess
- type FormatOptions
- type Function
- type FunctionBuilder
- func (b *FunctionBuilder) Build() *Function
- func (b *FunctionBuilder) Effects(e EffectInfo) *FunctionBuilder
- func (b *FunctionBuilder) OptParam(name string, t Type) *FunctionBuilder
- func (b *FunctionBuilder) Param(name string, t Type) *FunctionBuilder
- func (b *FunctionBuilder) Returns(types ...Type) *FunctionBuilder
- func (b *FunctionBuilder) Spec(s SpecInfo) *FunctionBuilder
- func (b *FunctionBuilder) TypeParam(name string, constraint Type) *FunctionBuilder
- func (b *FunctionBuilder) Variadic(t Type) *FunctionBuilder
- func (b *FunctionBuilder) WithRefinement(r RefinementInfo) *FunctionBuilder
- type Generic
- type IndexAccess
- type Instantiated
- type Interface
- type Intersection
- type Literal
- type Map
- type Meta
- type Metamethod
- type Metatabled
- type Method
- type Optional
- type Param
- type Platform
- type Record
- type RecordBuilder
- func (b *RecordBuilder) AnnotatedField(name string, t Type, optional bool, annotations []Annotation) *RecordBuilder
- func (b *RecordBuilder) Build() *Record
- func (b *RecordBuilder) Field(name string, t Type) *RecordBuilder
- func (b *RecordBuilder) MapComponent(key, value Type) *RecordBuilder
- func (b *RecordBuilder) Metatable(t Type) *RecordBuilder
- func (b *RecordBuilder) OptField(name string, t Type) *RecordBuilder
- func (b *RecordBuilder) OptReadonlyField(name string, t Type) *RecordBuilder
- func (b *RecordBuilder) ReadonlyField(name string, t Type) *RecordBuilder
- func (b *RecordBuilder) SetOpen(open bool) *RecordBuilder
- type Recursive
- type RecursiveBuilder
- type Ref
- type RefinementInfo
- type SoftPolicy
- type SpecInfo
- type Sum
- type Tuple
- type Type
- func ExtendRecordWithField(base Type, field string, fieldType Type) Type
- func JoinBranchOutcome(a, b Type) Type
- func JoinPreferNonSoft(a, b Type) Type
- func JoinReturnSlot(a, b Type) Type
- func NewAnnotated(inner Type, annotations []Annotation) Type
- func NewIntersection(members ...Type) Type
- func NewOptional(inner Type) Type
- func NewUnion(members ...Type) Type
- func PruneSoftUnionMembers(t Type) Type
- func Rewrite(t Type, fn func(Type) (Type, bool)) Type
- func UnwrapAnnotated(t Type) Type
- type TypeParam
- type TypeVar
- type Union
- type Variant
- type Visitor
Constants ¶
const DeepRecursionDepth = internal.MaxDeepDepth
DeepRecursionDepth is used for deep structural expansions.
const DefaultRecursionDepth = internal.MaxMediumDepth
DefaultRecursionDepth is the canonical recursion depth for typ operations.
Variables ¶
var ( True = &Literal{Base: kind.Boolean, Value: true, hash: trueHash} False = &Literal{Base: kind.Boolean, Value: false, hash: falseHash} )
True and False are singleton boolean literals.
var DefaultFormatOptions = FormatOptions{
MaxDepth: 6,
MaxNodes: 200,
MaxUnionMembers: 6,
MaxRecordFields: 8,
MaxTupleElems: 8,
MaxTypeParams: 6,
MaxParams: 8,
MaxReturns: 6,
MaxBytes: 800,
}
DefaultFormatOptions keeps diagnostics readable while avoiding huge output.
var SoftAnnotationPolicy = SoftPolicy{}
SoftAnnotationPolicy treats empty records as non-soft (annotation semantics).
var SoftPlaceholderPolicy = SoftPolicy{AllowEmptyRecord: true}
SoftPlaceholderPolicy treats empty records as soft (placeholder semantics).
Functions ¶
func DepthExceeded ¶
DepthExceeded reports whether depth exceeds the default recursion limit.
func Format ¶
func Format(t Type, opts FormatOptions) string
Format renders a type using the provided options.
func FormatShort ¶
FormatShort renders a type for diagnostics with bounded output size.
func GuardForDepth ¶
func GuardForDepth(maxDepth int) internal.RecursionGuard
GuardForDepth returns a recursion guard for a specific depth. If maxDepth is non-positive, the default depth is used.
func HasKnownType ¶ added in v1.5.6
HasKnownType reports whether the slice contains at least one concrete type. nil entries and unknown entries are treated as unresolved.
func IsAbsentOrUnknown ¶ added in v1.5.6
IsAbsentOrUnknown reports whether t is missing (nil) or unknown.
This intentionally does not treat the explicit nil type as unknown.
func IsBinaryMetamethod ¶
func IsBinaryMetamethod(m Metamethod) bool
IsBinaryMetamethod returns true if the metamethod is for binary operators.
func IsComparisonMetamethod ¶
func IsComparisonMetamethod(m Metamethod) bool
IsComparisonMetamethod returns true if the metamethod is for comparisons.
func IsMetamethod ¶
IsMetamethod returns true if the name is a valid metamethod.
func IsRecursiveRef ¶
IsRecursiveRef returns true if t is a reference to the given recursive type.
func IsRefinableAnnotation ¶ added in v1.5.6
IsRefinableAnnotation reports whether an explicit annotation should be treated as a soft placeholder that call-site/contextual hints may refine.
Canonical rule: explicit top types (`any`, `unknown`) are authoritative and must not be rewritten by hints. Structural soft placeholders like `{any}` or `any[]` remain refinable.
func IsSoft ¶
func IsSoft(t Type, policy SoftPolicy) bool
IsSoft reports whether a type should be treated as a soft placeholder under policy.
func IsUnaryMetamethod ¶
func IsUnaryMetamethod(m Metamethod) bool
IsUnaryMetamethod returns true if the metamethod is for unary operators.
func IsUnknownOnlyOrEmpty ¶ added in v1.5.6
IsUnknownOnlyOrEmpty reports whether the slice has no concrete types.
func IsUnknownOrNil ¶ added in v1.5.6
IsUnknownOrNil reports whether t is missing (nil), unknown, or explicit nil type.
func LiteralEquals ¶
LiteralEquals checks if two literals are equal.
func MinRequiredArgs ¶ added in v1.5.6
MinRequiredArgs returns the minimum positional argument count required to call f.
Lua arguments are positional, so a required parameter after an optional parameter still requires all earlier positions to be present.
func NewDeepGuard ¶
func NewDeepGuard() internal.RecursionGuard
NewDeepGuard returns a recursion guard using the canonical deep depth.
func NewGuard ¶
func NewGuard() internal.RecursionGuard
NewGuard returns a recursion guard using the canonical default depth.
func TypeEquals ¶
TypeEquals compares two types for structural equality with cycle detection.
Uses coinductive equality for recursive types: if the same type pair is encountered again during traversal, they are assumed equal. This handles infinite recursive structures correctly.
Aliases are transparent: compares through to their targets.
func TypeMatchesLiteral ¶
TypeMatchesLiteral checks if a type is compatible with a literal value.
func TypeString ¶
TypeString returns string representation with depth limiting.
func VisitWithGuard ¶
func VisitWithGuard[R any]( t Type, guard internal.RecursionGuard, onCycle R, build func(next internal.RecursionGuard) Visitor[R], ) R
VisitWithGuard applies a Visitor with recursion guarding. Returns onCycle when the guard disallows entry.
func WithGuard ¶
func WithGuard[R any]( t Type, guard internal.RecursionGuard, onCycle R, fn func(next internal.RecursionGuard) R, ) R
WithGuard runs fn with a recursion guard and returns onCycle on guard rejection.
Types ¶
type Alias ¶
type Alias struct {
Name string // Alias name
Target Type // Underlying type
// contains filtered or unexported fields
}
Alias represents a named type alias.
Aliases provide alternative names for types without creating new types. An Alias is structurally equivalent to its Target for subtyping and equality, but preserves the name for error messages and documentation.
Example: type UserId = number creates Alias{Name: "UserId", Target: number}
type Annotated ¶
type Annotated struct {
Inner Type
Annotations []Annotation
// contains filtered or unexported fields
}
Annotated wraps a type with runtime validation annotations. The underlying type determines structural typing while annotations add runtime constraints like @min(0), @max(100), @pattern("^.+$").
type Annotation ¶
Annotation represents a runtime validation constraint.
func GetAnnotations ¶
func GetAnnotations(t Type) []Annotation
GetAnnotations returns annotations from a type, or nil if none.
type Array ¶
type Array struct {
Element Type
// contains filtered or unexported fields
}
Array represents a homogeneous sequence type: T[].
Arrays are Lua tables with integer keys starting at 1. The Element type describes what each element contains. Arrays support ipairs iteration and length operator (#).
type CaptureInfo ¶
type CaptureInfo struct {
Name string
Type Type
Mode CaptureMode
Escapes bool
Mutated bool
}
CaptureInfo describes a single captured variable.
func (CaptureInfo) NeedsUpvalue ¶
func (c CaptureInfo) NeedsUpvalue() bool
NeedsUpvalue returns true if this capture requires a heap-allocated upvalue.
type CaptureMode ¶
type CaptureMode int
CaptureMode indicates how a variable is captured by a closure.
const ( CaptureUnknown CaptureMode = iota CaptureByValue // immutable, safe to copy at closure creation CaptureByRef // mutable or escapes, needs upvalue )
func (CaptureMode) String ¶
func (m CaptureMode) String() string
type EffectInfo ¶
EffectInfo describes function effects (e.g., io, throw). Implemented by effect.Row.
type Field ¶
type Field struct {
Name string
Type Type
Optional bool // True if field may be absent (nil access returns nil)
Readonly bool // True if field cannot be reassigned
}
Field represents a record field with name, type, optionality, and mutability.
type FieldAccess ¶
type FieldAccess struct {
Base Type // Base type (usually a TypeParam)
Field string // Field name to access
// contains filtered or unexported fields
}
FieldAccess represents a projected field type from an unresolved base.
Used in generic contexts where we need T.field but T is a type parameter. When T is instantiated with a concrete type, FieldAccess resolves to the actual field type.
Example: In a generic function returning T.name, if T is unresolved, the return type is FieldAccess{Base: T, Field: "name"}.
func NewFieldAccess ¶
func NewFieldAccess(base Type, field string) *FieldAccess
NewFieldAccess creates a deferred field access.
func (*FieldAccess) Equals ¶
func (f *FieldAccess) Equals(other Type) bool
func (*FieldAccess) Hash ¶
func (f *FieldAccess) Hash() uint64
func (*FieldAccess) Kind ¶
func (f *FieldAccess) Kind() kind.Kind
func (*FieldAccess) String ¶
func (f *FieldAccess) String() string
type FormatOptions ¶
type FormatOptions struct {
MaxDepth int
MaxNodes int
MaxUnionMembers int
MaxRecordFields int
MaxTupleElems int
MaxTypeParams int
MaxParams int
MaxReturns int
MaxBytes int
}
FormatOptions controls budgeted type rendering for diagnostics. Limits are best-effort; rendering may truncate with "..." when exceeded.
type Function ¶
type Function struct {
TypeParams []*TypeParam // Generic type parameters (empty for non-generic)
Params []Param // Positional parameters
Variadic Type // Variadic element type (nil if not variadic)
Returns []Type // Return types (empty for void functions)
Effects EffectInfo // Effect row (effect.Row) for mutation/throw/io tracking
Spec SpecInfo // Contract specification (*contract.Spec)
Refinement RefinementInfo // Type refinement effect (*constraint.FunctionEffect)
// contains filtered or unexported fields
}
Function represents a function type with parameters, returns, and effects.
Functions support generics via TypeParams, variadic arguments via Variadic, multiple return values via Returns, and effect tracking via Effects.
The Spec field holds Hoare-style contracts (pre/post conditions). The Refinement field holds type narrowing constraints for predicate functions.
type FunctionBuilder ¶
type FunctionBuilder struct {
// contains filtered or unexported fields
}
FunctionBuilder provides a fluent API for constructing function types.
Example:
fn := typ.Func().
Param("x", typ.Number).
Param("y", typ.Number).
Returns(typ.Number).
Build()
func (*FunctionBuilder) Build ¶
func (b *FunctionBuilder) Build() *Function
Build creates the function type.
func (*FunctionBuilder) Effects ¶
func (b *FunctionBuilder) Effects(e EffectInfo) *FunctionBuilder
Effects sets effect row.
func (*FunctionBuilder) OptParam ¶
func (b *FunctionBuilder) OptParam(name string, t Type) *FunctionBuilder
OptParam adds an optional parameter.
func (*FunctionBuilder) Param ¶
func (b *FunctionBuilder) Param(name string, t Type) *FunctionBuilder
Param adds a required parameter.
func (*FunctionBuilder) Returns ¶
func (b *FunctionBuilder) Returns(types ...Type) *FunctionBuilder
Returns sets return types.
func (*FunctionBuilder) Spec ¶
func (b *FunctionBuilder) Spec(s SpecInfo) *FunctionBuilder
Spec sets contract specification.
func (*FunctionBuilder) TypeParam ¶
func (b *FunctionBuilder) TypeParam(name string, constraint Type) *FunctionBuilder
TypeParam adds a type parameter for generic functions.
func (*FunctionBuilder) Variadic ¶
func (b *FunctionBuilder) Variadic(t Type) *FunctionBuilder
Variadic sets variadic parameter type.
func (*FunctionBuilder) WithRefinement ¶
func (b *FunctionBuilder) WithRefinement(r RefinementInfo) *FunctionBuilder
WithRefinement sets the function refinement effect.
type Generic ¶
type Generic struct {
Name string // Type name (empty for anonymous generics)
TypeParams []*TypeParam // Type parameters to be substituted
Body Type // Template type with TypeParam references
// contains filtered or unexported fields
}
Generic represents a parameterized type definition awaiting instantiation.
Generics have type parameters that are substituted with concrete types when instantiated. The Body contains the type with TypeParam references.
Identity:
- Named generics use nominal identity (name + params, ignoring body)
- Anonymous generics use structural identity (includes body in hash)
func NewGeneric ¶
NewGeneric creates a generic type definition. Named generics use nominal identity, anonymous generics use structural identity.
type IndexAccess ¶
type IndexAccess struct {
Base Type // Base type (usually contains a TypeParam)
Index Type // Index type for the access
// contains filtered or unexported fields
}
IndexAccess represents a projected index type from an unresolved base.
Used in generic contexts where we need T[K] but T is a type parameter. When T is instantiated with a concrete type, IndexAccess resolves to the actual indexed element type.
Example: For Array<T>[number], if T is unresolved, the result is IndexAccess{Base: Array<T>, Index: number}.
func NewIndexAccess ¶
func NewIndexAccess(base, index Type) *IndexAccess
NewIndexAccess creates a deferred index access.
func (*IndexAccess) Equals ¶
func (i *IndexAccess) Equals(other Type) bool
func (*IndexAccess) Hash ¶
func (i *IndexAccess) Hash() uint64
func (*IndexAccess) Kind ¶
func (i *IndexAccess) Kind() kind.Kind
func (*IndexAccess) String ¶
func (i *IndexAccess) String() string
type Instantiated ¶
type Instantiated struct {
Generic *Generic // The generic being instantiated
TypeArgs []Type // Concrete types for each type parameter
// contains filtered or unexported fields
}
Instantiated represents a generic type with concrete type arguments applied.
When a generic like Array<T> is used as Array<number>, an Instantiated type is created with Generic=Array and TypeArgs=[number]. The body can be expanded by substituting type parameters with arguments.
func Instantiate ¶
func Instantiate(g *Generic, args ...Type) *Instantiated
Instantiate creates an instantiated generic type with the given arguments.
func (*Instantiated) Equals ¶
func (i *Instantiated) Equals(other Type) bool
func (*Instantiated) Hash ¶
func (i *Instantiated) Hash() uint64
func (*Instantiated) Kind ¶
func (i *Instantiated) Kind() kind.Kind
func (*Instantiated) String ¶
func (i *Instantiated) String() string
type Interface ¶
type Interface struct {
Name string // Interface name (empty for anonymous)
Methods []Method // Required methods
// contains filtered or unexported fields
}
Interface represents a structural interface type (trait/protocol).
Interfaces define a set of methods that a type must implement. Unlike nominal interfaces, subtyping is structural: any type with matching methods satisfies the interface.
Named interfaces (Name != "") use nominal identity for marker interfaces (interfaces with no methods, like Channel<T>).
func NewInterface ¶
NewInterface creates an interface type.
type Intersection ¶
type Intersection struct {
Members []Type
// contains filtered or unexported fields
}
Intersection represents a type satisfying all member constraints: T1 & T2 & ...
Intersections require a value to satisfy every member type simultaneously. They are normalized during construction:
- Nested intersections are flattened
- Duplicate members are removed
- Any members are dropped (Any is identity for intersection)
- Never absorbs all other members (intersection with Never = Never)
Members are sorted by hash for deterministic comparison.
func (*Intersection) Equals ¶
func (i *Intersection) Equals(other Type) bool
func (*Intersection) Hash ¶
func (i *Intersection) Hash() uint64
func (*Intersection) Kind ¶
func (i *Intersection) Kind() kind.Kind
func (*Intersection) String ¶
func (i *Intersection) String() string
type Literal ¶
type Literal struct {
Base kind.Kind // Boolean, Number, Integer, or String
Value any // bool, float64, int64, or string
// contains filtered or unexported fields
}
Literal represents a singleton type containing exactly one value.
Literal types enable precise type checking for constant values:
- LiteralBool(true) is a subtype of boolean
- LiteralString("foo") is a subtype of string
- LiteralInt(42) is a subtype of integer (and number)
Base indicates the underlying primitive kind (Boolean, Number, Integer, String). Value holds the actual value with the appropriate Go type.
func LiteralBool ¶
LiteralBool returns the canonical boolean literal type.
func LiteralNumber ¶
LiteralNumber creates a number literal type.
func LiteralString ¶
LiteralString creates a string literal type.
type Map ¶
Map represents a homogeneous key-value mapping: {[K]: V}.
Maps are Lua tables where all keys have type K and all values have type V. Unlike Records, Maps have uniform types for all entries rather than named fields with potentially different types.
type Meta ¶
type Meta struct {
Of Type // The type being wrapped
// contains filtered or unexported fields
}
Meta represents a metatype (the type of a type value).
Meta types are used when types themselves are values, such as in type predicates or reflection. Meta{Of: T} represents the type of a runtime value that carries type T.
Example: typeof(Point) has type Meta{Of: Point}
type Metamethod ¶
type Metamethod string
Metamethod represents a Lua metamethod identifier.
const ( MetaIndex Metamethod = "__index" MetaNewIndex Metamethod = "__newindex" MetaCall Metamethod = "__call" MetaAdd Metamethod = "__add" MetaSub Metamethod = "__sub" MetaMul Metamethod = "__mul" MetaDiv Metamethod = "__div" MetaMod Metamethod = "__mod" MetaPow Metamethod = "__pow" MetaUnm Metamethod = "__unm" MetaIDiv Metamethod = "__idiv" MetaBand Metamethod = "__band" MetaBor Metamethod = "__bor" MetaBxor Metamethod = "__bxor" MetaBnot Metamethod = "__bnot" MetaShl Metamethod = "__shl" MetaShr Metamethod = "__shr" MetaConcat Metamethod = "__concat" MetaLen Metamethod = "__len" MetaEq Metamethod = "__eq" MetaLt Metamethod = "__lt" MetaLe Metamethod = "__le" MetaToString Metamethod = "__tostring" MetaPairs Metamethod = "__pairs" MetaIPairs Metamethod = "__ipairs" MetaGC Metamethod = "__gc" MetaClose Metamethod = "__close" MetaMode Metamethod = "__mode" MetaName Metamethod = "__name" )
func OperatorToMetamethod ¶
func OperatorToMetamethod(op string) (Metamethod, bool)
OperatorToMetamethod maps a binary operator to its metamethod.
func UnaryOperatorToMetamethod ¶
func UnaryOperatorToMetamethod(op string) (Metamethod, bool)
UnaryOperatorToMetamethod maps a unary operator to its metamethod.
type Metatabled ¶
type Metatabled interface {
Type
GetMetamethod(m Metamethod) *Function
HasMetamethod(m Metamethod) bool
}
Metatabled is an interface for types that can have metamethods.
type Optional ¶
type Optional struct {
Inner Type
// contains filtered or unexported fields
}
Optional represents a nullable type: T | nil.
Optional is syntactic sugar for a union with nil. It provides cleaner representation for the common case of a value that may be absent.
The Inner field holds the non-nil type. An Optional never contains another Optional (they are flattened during construction).
type Platform ¶
type Platform struct {
Name string // Platform type name
// contains filtered or unexported fields
}
Platform represents a platform-specific opaque type.
Platform types are provided by the runtime environment and have no structural representation in the type system. They are compared nominally by name.
Example: userdata types, file handles, coroutines.
type Record ¶
type Record struct {
Fields []Field
Metatable Type // Metatable type for metamethod lookup
MapKey Type // Map component key type (nil if no map component)
MapValue Type // Map component value type (nil if no map component)
Open bool // Allow access to undefined fields
// contains filtered or unexported fields
}
Record represents a Lua table with named fields: {field1: T1, field2: T2, ...}.
Records support both structural typing (field presence/type matching) and optional map components for tables with dynamic indexing.
Features:
- Open: When true, unknown field access returns Unknown instead of error
- MapKey/MapValue: Optional map component for {foo: T, [K]: V} patterns
- Metatable: Optional metatable type for metamethod resolution
Fields are sorted by name for deterministic hashing and comparison.
func (*Record) HasMapComponent ¶
HasMapComponent returns true if the record has a map component (MapKey and MapValue set).
type RecordBuilder ¶
type RecordBuilder struct {
// contains filtered or unexported fields
}
RecordBuilder provides a fluent API for constructing record types.
Example:
rec := typ.NewRecord().
Field("name", typ.String).
OptField("age", typ.Integer).
Build()
func (*RecordBuilder) AnnotatedField ¶
func (b *RecordBuilder) AnnotatedField(name string, t Type, optional bool, annotations []Annotation) *RecordBuilder
AnnotatedField adds a field with validation annotations.
func (*RecordBuilder) Build ¶
func (b *RecordBuilder) Build() *Record
Build creates the record type.
func (*RecordBuilder) Field ¶
func (b *RecordBuilder) Field(name string, t Type) *RecordBuilder
Field adds a required field.
func (*RecordBuilder) MapComponent ¶
func (b *RecordBuilder) MapComponent(key, value Type) *RecordBuilder
MapComponent sets the map component key and value types.
func (*RecordBuilder) Metatable ¶
func (b *RecordBuilder) Metatable(t Type) *RecordBuilder
Metatable sets the metatable type.
func (*RecordBuilder) OptField ¶
func (b *RecordBuilder) OptField(name string, t Type) *RecordBuilder
OptField adds an optional field.
func (*RecordBuilder) OptReadonlyField ¶
func (b *RecordBuilder) OptReadonlyField(name string, t Type) *RecordBuilder
OptReadonlyField adds an optional readonly field.
func (*RecordBuilder) ReadonlyField ¶
func (b *RecordBuilder) ReadonlyField(name string, t Type) *RecordBuilder
ReadonlyField adds a readonly field.
func (*RecordBuilder) SetOpen ¶
func (b *RecordBuilder) SetOpen(open bool) *RecordBuilder
SetOpen marks the record as open (unknown field access returns unknown).
type Recursive ¶
Recursive represents a self-referential (mu) type. Recursive types are identified by a unique ID to allow cycle detection during equality comparison and hashing without infinite recursion.
Example: type Node = { next: Node? } is represented as:
Recursive{ID: 1, Name: "Node", Body: Record{Fields: [{name: "next", type: <self-ref>}]}}
func NewRecursive ¶
func NewRecursive(name string, builder RecursiveBuilder) *Recursive
NewRecursive creates a new recursive type. The builder function receives a placeholder that represents self-references and should return the body type using that placeholder where needed.
func NewRecursivePlaceholder ¶
NewRecursivePlaceholder creates an empty recursive type for deferred body assignment. Use SetBody to assign the body after creation. This is useful for mutual recursion.
func NewRecursiveWithBody ¶
NewRecursiveWithBody creates a recursive type with a pre-built body. Use this when the body is already constructed with proper self-references.
func (*Recursive) Equals ¶
Equals compares two recursive types by their structural identity. Two recursive types are equal if they have the same structure when the self-references are treated as equivalent.
type RecursiveBuilder ¶
RecursiveBuilder is used during construction to provide a self-reference.
type Ref ¶
type Ref struct {
Module string // Module path (empty for local references)
Name string // Type name
// contains filtered or unexported fields
}
Ref represents an unresolved reference to a named type definition.
Refs are created during parsing when a type name is encountered before its definition. They are resolved to the actual type during semantic analysis using the Module path to locate the definition.
Local refs (Module == "") refer to types in the current module. Cross-module refs include the module path for import resolution.
type RefinementInfo ¶
RefinementInfo describes type refinements from function calls. Implemented by *constraint.FunctionEffect.
type SoftPolicy ¶
type SoftPolicy struct {
// AllowEmptyRecord treats {} as a soft placeholder when true.
AllowEmptyRecord bool
}
SoftPolicy controls how soft-placeholder detection behaves.
type SpecInfo ¶
SpecInfo describes function specifications (pre/post conditions). Implemented by *contract.Spec.
type Sum ¶
type Sum struct {
Name string // Type name for display
Variants []Variant // Possible cases
// contains filtered or unexported fields
}
Sum represents a tagged union (sum type / discriminated union).
Sum types enable safe pattern matching over a closed set of variants. Each variant has a tag and optional associated data.
Example: Option<T> = Some(T) | None
type Tuple ¶
type Tuple struct {
Elements []Type
// contains filtered or unexported fields
}
Tuple represents a fixed-length heterogeneous sequence: (T1, T2, ...).
Tuples are used for multi-value returns and destructuring assignments. Unlike Arrays, each position can have a different type and the length is fixed at compile time.
type Type ¶
Type is the interface implemented by all types in the type system. Types are immutable and support structural equality and hashing.
var ( Nil Type = nilType{} Boolean Type = booleanType{} Number Type = numberType{} Integer Type = integerType{} String Type = stringType{} Any Type = anyType{} Unknown Type = unknownType{} Never Type = neverType{} Self Type = selfType{} )
Primitives are singletons.
Any vs Unknown semantics:
- Any: explicit dynamic type (opt-out). Use only when the source is explicitly "any" or a deliberate dynamic escape hatch. Operations on Any are permissive.
- Unknown: missing or unresolved information. It should force narrowing/inference rather than silently permitting operations.
var LuaError Type = NewInterface("Error", []Method{ {Name: "kind", Type: Func().Param("self", Self).Returns(String).Build()}, {Name: "retryable", Type: Func().Param("self", Self).Returns(Boolean).Build()}, {Name: "details", Type: Func().Param("self", Self).Returns(Any).Build()}, {Name: "message", Type: Func().Param("self", Self).Returns(String).Build()}, {Name: "stack", Type: Func().Param("self", Self).Returns(String).Build()}, })
LuaError is the standard error type for Lua functions. It represents structured errors with message, kind, retryable, etc.
func ExtendRecordWithField ¶
ExtendRecordWithField returns a record type extended with a field. If the base type is nil, any, unknown, or nil, creates a new record with just the field. If the base type is already a record, adds or updates the field.
func JoinBranchOutcome ¶ added in v1.5.6
JoinBranchOutcome merges mutually-exclusive expression outcomes (for example, `a and b` / `a or b`) while preserving uncertainty.
Unlike JoinPreferNonSoft, this must not treat unknown as absent information: expression typing needs to preserve runtime uncertainty when one branch may still produce unknown-like values.
func JoinPreferNonSoft ¶
JoinPreferNonSoft joins two types while preferring non-soft placeholders. This centralizes the "soft placeholder" policy used across inference and flow.
func JoinReturnSlot ¶ added in v1.5.6
JoinReturnSlot merges return slot types while preserving uncertainty.
Unknown in return inference means unresolved runtime behavior. When one branch is unknown and another is explicit nil, keep unknown so summaries do not collapse to nil-only.
func NewAnnotated ¶
func NewAnnotated(inner Type, annotations []Annotation) Type
NewAnnotated creates an annotated type wrapper. Returns the inner type directly if no annotations are provided.
func NewIntersection ¶
NewIntersection creates a normalized intersection type. Returns Any for empty intersections, the single type for one member, or a normalized Intersection for multiple distinct members.
func NewOptional ¶
NewOptional creates an optional type (T | nil).
Normalization rules:
- nil or Nil → Nil (already optional)
- T? → T? (already optional)
- Any → Any (Any already includes nil)
- Union → adds nil and re-normalizes through NewUnion
func NewUnion ¶
NewUnion creates a normalized union type from the given members. Returns Never for empty unions, the single type for one member, or a normalized Union for multiple distinct members.
func PruneSoftUnionMembers ¶
PruneSoftUnionMembers removes soft placeholder members from unions when any non-soft member is present. This helps inference avoid contaminating concrete types with placeholder unions.
func Rewrite ¶
Rewrite traverses a type tree and applies fn at each node (bottom-up transformation).
The function fn is called on each type node before recursing into children. If fn returns (replacement, true), the replacement is used and children are not visited (early termination). If fn returns (_, false), children are recursively rewritten first, then the result is reassembled.
Returns the original pointer when nothing changed (structural sharing). This is the foundation for type substitution, expansion, and other transforms.
func UnwrapAnnotated ¶
UnwrapAnnotated returns the inner type, stripping annotations.
type TypeParam ¶
type TypeParam struct {
Name string
Constraint Type // Upper bound (nil means any type)
// contains filtered or unexported fields
}
TypeParam represents a type parameter in a generic type or function.
Type parameters enable parametric polymorphism: a single definition that works with multiple types. The Constraint field bounds what types can instantiate this parameter (nil means any type is allowed).
Example: In Array<T>, T is a TypeParam with Name="T" and Constraint=nil.
func NewTypeParam ¶
NewTypeParam creates a type parameter.
type TypeVar ¶
type TypeVar struct {
ID int
// contains filtered or unexported fields
}
TypeVar represents an inference variable during type checking.
Type variables are placeholders created during generic instantiation and constraint solving. They are unified with concrete types as the checker gathers information. ID distinguishes different variables.
func NewTypeVar ¶
NewTypeVar creates a type variable with the given ID.
type Union ¶
type Union struct {
Members []Type
// contains filtered or unexported fields
}
Union represents a type that can be any of its member types: T1 | T2 | ...
Unions are normalized during construction:
- Nested unions are flattened
- Duplicate members are removed
- Never members are dropped (Never is identity for union)
- Any absorbs all other members (union with Any = Any)
- Literals are subsumed by their base types (string | "foo" = string)
- Single non-nil member with nil becomes Optional
Members are sorted by hash for deterministic comparison and serialization.
type Variant ¶
type Variant struct {
Tag string // Discriminant value (e.g., "Some", "None")
Types []Type // Associated data types (empty for unit variant like None)
}
Variant represents a case in a sum type (tagged union). Tag is the discriminant, Types holds the associated data (empty for unit variants).
type Visitor ¶
type Visitor[R any] struct { Optional func(*Optional) R Union func(*Union) R Intersection func(*Intersection) R Array func(*Array) R Map func(*Map) R Tuple func(*Tuple) R Function func(*Function) R Record func(*Record) R Alias func(*Alias) R Ref func(*Ref) R Platform func(*Platform) R Meta func(*Meta) R Generic func(*Generic) R Instantiated func(*Instantiated) R TypeParam func(*TypeParam) R TypeVar func(*TypeVar) R FieldAccess func(*FieldAccess) R IndexAccess func(*IndexAccess) R Sum func(*Sum) R Interface func(*Interface) R Recursive func(*Recursive) R Literal func(*Literal) R Default func(Type) R }
Visitor dispatches on concrete type implementations. Nil handlers fall back to Default when provided; otherwise return zero.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package join provides type join operations for control flow merging.
|
Package join provides type join operations for control flow merging. |
|
Package subst provides type substitution operations for generics.
|
Package subst provides type substitution operations for generics. |
|
Package union provides union type analysis operations.
|
Package union provides union type analysis operations. |
|
Package unwrap provides type unwrapping, extraction, and predicate operations.
|
Package unwrap provides type unwrapping, extraction, and predicate operations. |