From f5c6aa70c528af9d797124ec2776e3d28dc4dc39 Mon Sep 17 00:00:00 2001 From: jlapacik Date: Thu, 6 Dec 2018 16:51:01 -0800 Subject: [PATCH] fix(semantic): collision between external and fresh type vars Fixes #263. Type inference replaces any external free type variables with new fresh type variables. The result is a new but completely equivalent type expression. Previously during the substitution process collisions could occur between the names of old type variables and the names of the new freshly generated type variables. This would render the new type expression invalid. To remedy this problem, fresh type variables are now generated before being substituted into the original type expression. If there is a collision, that type variable is discarded and a new one is generated. --- semantic/constraints.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/semantic/constraints.go b/semantic/constraints.go index 76fb0a67ff..0db6640ae4 100644 --- a/semantic/constraints.go +++ b/semantic/constraints.go @@ -96,7 +96,11 @@ func (v ConstraintGenerator) typeof(n Node) (PolyType, error) { ftv := n.ExternType.freeVars(nil) subst := make(Substitution, len(ftv)) for _, tv := range ftv { - subst[tv] = v.cs.f.Fresh() + f := v.cs.f.Fresh() + for ftv.contains(f) { + f = v.cs.f.Fresh() + } + subst[tv] = f } t := subst.ApplyType(n.ExternType) // Check if this type knows about its kind constraints