pub struct Substitution { /* private fields */ }Expand description
A substitution mapping type variables to their resolved types.
The substitution is built incrementally during unification.
It maps type variable IDs to InferTypes, which may themselves
be type variables (requiring transitive lookup via apply).
§Performance
Uses a Vec<Option<InferType>> instead of HashMap<TypeVarId, InferType> for O(1)
lookups without hashing overhead. This works because TypeVarId is a sequential
u32 starting from 0.
Additionally implements path compression: when following a chain of variable references, intermediate links are updated to point directly to the final result, amortizing the cost of chain traversal.
Implementations§
Source§impl Substitution
impl Substitution
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Create a substitution with pre-allocated capacity.
Use when you know approximately how many type variables will be created.
Sourcepub fn insert(&mut self, var: TypeVarId, ty: InferType)
pub fn insert(&mut self, var: TypeVarId, ty: InferType)
Insert a mapping from a type variable to a type.
If the variable is already mapped, the old mapping is replaced.
Sourcepub fn get(&self, var: TypeVarId) -> Option<InferType>
pub fn get(&self, var: TypeVarId) -> Option<InferType>
Look up a type variable’s immediate mapping (without following chains).
Sourcepub fn apply(&self, ty: &InferType) -> InferType
pub fn apply(&self, ty: &InferType) -> InferType
Apply the substitution to a type, following type variable chains to their ultimate resolution.
Concrete(ty)→Concrete(ty)(unchanged)Var(id)→ follows chain until concrete or unbound variableIntLiteral→IntLiteral(unchanged, unless we add IntLiteral to variable mappings)Array { element, length }→ recursively apply to element type
§Path Compression
When following a chain like v0 -> v1 -> v2 -> i32, this method
updates all intermediate links to point directly to the final result.
This amortizes the cost of repeated lookups.
Sourcepub fn occurs_in(&self, var: TypeVarId, ty: &InferType) -> bool
pub fn occurs_in(&self, var: TypeVarId, ty: &InferType) -> bool
Check if a type variable occurs in a type (for occurs check).
This prevents creating infinite types like α = List<α>.
Returns true if the variable occurs in the type.