traverse

package
v0.14.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package traverse provides safe type traversal with automatic cycle detection. This prevents infinite loops when traversing cyclic type graphs (e.g., recursive ADTs).

API Design Rule (from M-PERF2 post-mortem): Every function of shape `func(Type) T` MUST document cycle-safety. Either use traverse.Visit or add a `visited` parameter.

Index

Constants

View Source
const DefaultMaxDepth = 1000

DefaultMaxDepth is the maximum traversal depth before panic. This prevents hangs on pathological cases even if cycle detection fails.

Variables

This section is empty.

Functions

func AllTypes

func AllTypes(t types.Type) []types.Type

AllTypes returns all types in a type graph in pre-order traversal. Safe for cyclic types - cycles are visited once.

func CollectFreeVars

func CollectFreeVars(t types.Type) map[string]bool

CollectFreeVars returns all free type variable names in a type. Safe for cyclic types - will not hang on self-referential type graphs.

Example:

vars := traverse.CollectFreeVars(funcType)
// vars might be: {"a": true, "b": true}

func CollectTypesByKind

func CollectTypesByKind(t types.Type, predicate func(types.Type) bool) []types.Type

CollectTypesByKind returns all types of a specific kind in a type graph. The predicate function determines which types to collect. Safe for cyclic types.

Example:

funcs := traverse.CollectTypesByKind(t, func(typ types.Type) bool {
    _, ok := typ.(*types.TFunc2)
    return ok
})

func ContainsType

func ContainsType(t, target types.Type) bool

ContainsType checks if a type graph contains a specific target type. Uses pointer equality for comparison. Safe for cyclic types.

Example:

if traverse.ContainsType(funcType, targetVar) {
    // targetVar appears somewhere in funcType
}

func ContainsTypeByName

func ContainsTypeByName(t types.Type, name string) bool

ContainsTypeByName checks if a type graph contains a type variable with the given name. Safe for cyclic types.

Example:

if traverse.ContainsTypeByName(funcType, "a") {
    // Type variable "a" appears somewhere in funcType
}

func CountTypes

func CountTypes(t types.Type) int

CountTypes returns the total number of type nodes in a type graph. Safe for cyclic types - cycles are counted once.

Useful for complexity estimation and debugging.

func Depth

func Depth(t types.Type) int

Depth returns the maximum nesting depth of a type graph. Safe for cyclic types - cycles are detected and counted once.

Useful for complexity analysis and debugging.

func HasCycles

func HasCycles(t types.Type) bool

HasCycles checks if a type graph contains any cycles. Returns true if the type references itself directly or indirectly.

Example:

if traverse.HasCycles(adtType) {
    // This is a recursive type like List[T] or Tree[T]
}

func HasTypeVars

func HasTypeVars(t types.Type) bool

HasTypeVars checks if a type contains any type variables (TVar, TVar2, RowVar). Safe for cyclic types - will not hang on recursive ADTs.

This is the cycle-safe replacement for isPolymorphic checks. Use this in monomorphization and specialization passes.

Example:

if traverse.HasTypeVars(funcType) {
    // Type is polymorphic, needs specialization
}

func IsMonomorphic

func IsMonomorphic(t types.Type) bool

IsMonomorphic checks if a type is fully concrete (no type variables). This is the inverse of HasTypeVars. Safe for cyclic types.

Example:

if traverse.IsMonomorphic(funcType) {
    // Type can be used directly without specialization
}

func Walk

func Walk(t types.Type, fn func(types.Type))

Walk is a convenience function that creates a visitor and traverses. For simple one-off traversals where you don't need OnCycle.

func WalkWithCycleCallback

func WalkWithCycleCallback(t types.Type, fn func(types.Type), onCycle func(types.Type))

WalkWithCycleCallback traverses with a cycle callback.

Types

type TypeVisitor

type TypeVisitor struct {

	// OnCycle is called when a cycle is detected.
	// If nil, cycles are silently skipped.
	OnCycle func(typ types.Type)
	// contains filtered or unexported fields
}

TypeVisitor traverses type graphs with automatic cycle detection. Use NewVisitor() to create instances.

func NewVisitor

func NewVisitor() *TypeVisitor

NewVisitor creates a TypeVisitor with default settings.

func (*TypeVisitor) Visit

func (v *TypeVisitor) Visit(t types.Type, fn func(types.Type))

Visit traverses a type graph, calling fn for each type node. Automatically detects cycles and enforces depth limits.

The visitor uses pre-order traversal: fn is called before children. Cycles are detected and skipped (or OnCycle is called if set).

func (*TypeVisitor) WithMaxDepth

func (v *TypeVisitor) WithMaxDepth(depth int) *TypeVisitor

WithMaxDepth sets a custom maximum depth (for testing).

func (*TypeVisitor) WithOnCycle

func (v *TypeVisitor) WithOnCycle(fn func(types.Type)) *TypeVisitor

WithOnCycle sets a callback for cycle detection.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL