Index: src/SynTree/TypeSubstitution.cc
===================================================================
--- src/SynTree/TypeSubstitution.cc	(revision 7862059cce5f318d65bb3ffe71be2e849497ea0b)
+++ src/SynTree/TypeSubstitution.cc	(revision deaef5b82ceb19ea3c0d1ae41ad3d1af880bb0fa)
@@ -149,12 +149,19 @@
 		return inst;
 	} else {
-///	    std::cerr << "found " << inst->get_name() << ", replacing with ";
-///	    i->second->print( std::cerr );
-///	    std::cerr << std::endl;
+		// cut off infinite loop for the case where a type is bound to itself.
+		// Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here.
+		// TODO: investigate preventing type variables from being bound to themselves in the first place.
+		if ( TypeInstType * replacement = dynamic_cast< TypeInstType * >( i->second ) ) {
+			if ( inst->name == replacement->name ) {
+				return inst;
+			}
+		}
+		// std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl;
 		subCount++;
 		Type * newtype = i->second->clone();
 		newtype->get_qualifiers() |= inst->get_qualifiers();
 		delete inst;
-		return newtype;
+		// Note: need to recursively apply substitution to the new type because normalize does not substitute bound vars, but bound vars must be substituted when not in freeOnly mode.
+		return newtype->acceptMutator( *visitor );
 	} // if
 }
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision 7862059cce5f318d65bb3ffe71be2e849497ea0b)
+++ src/SynTree/TypeSubstitution.h	(revision deaef5b82ceb19ea3c0d1ae41ad3d1af880bb0fa)
@@ -129,5 +129,5 @@
 
 // definitition must happen after PassVisitor is included so that WithGuards can be used
-struct TypeSubstitution::Substituter : public WithGuards {
+struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> {
 		Substituter( TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
 
