Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision f07c1e6c25a1e3f03dafd36dd27430bfc2ca80c6)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision d7d9a605341969df23ea12387498dc6e6fea463c)
@@ -152,5 +152,5 @@
 
 		void renameTypes( Expression *expr ) {
-			expr->get_result()->accept( global_renamer );
+			renameTyVars( expr->result );
 		}
 	} // namespace
@@ -485,5 +485,5 @@
 			Type *adjType = candidate->get_type()->clone();
 			adjustExprType( adjType, newEnv, indexer );
-			adjType->accept( global_renamer );
+			renameTyVars( adjType );
 			PRINT(
 				std::cerr << "unifying ";
@@ -595,5 +595,5 @@
 
 		ArgPack()
-			: parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 
+			: parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
 			  tupleStart(0), nextExpl(0), explAlt(0) {}
 
@@ -706,5 +706,5 @@
 
 						if ( nTuples > 0 || ! results[i].expr ) {
-							// first iteration or no expression to clone, 
+							// first iteration or no expression to clone,
 							// push empty tuple expression
 							newResult.parent = i;
Index: src/ResolvExpr/RenameVars.cc
===================================================================
--- src/ResolvExpr/RenameVars.cc	(revision f07c1e6c25a1e3f03dafd36dd27430bfc2ca80c6)
+++ src/ResolvExpr/RenameVars.cc	(revision d7d9a605341969df23ea12387498dc6e6fea463c)
@@ -19,4 +19,5 @@
 #include <utility>                 // for pair
 
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
 #include "RenameVars.h"
@@ -27,126 +28,72 @@
 
 namespace ResolvExpr {
-	RenameVars global_renamer;
+	namespace {
+		struct RenameVars {
+			RenameVars();
+			void reset();
 
-	RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) {
-		mapStack.push_front( std::map< std::string, std::string >() );
+			void previsit( TypeInstType * instType );
+			void previsit( Type * );
+			void postvisit( Type * );
+
+		  private:
+			int level, resetCount;
+			std::list< std::map< std::string, std::string > > mapStack;
+		};
+
+		PassVisitor<RenameVars> global_renamer;
+	} // namespace
+
+	void renameTyVars( Type * t ) {
+		t->accept( global_renamer );
 	}
 
-	void RenameVars::reset() {
-		level = 0;
-		resetCount++;
+	void resetTyVarRenaming() {
+		global_renamer.pass.reset();
 	}
 
-	void RenameVars::visit( VoidType *voidType ) {
-		typeBefore( voidType );
-		typeAfter( voidType );
-	}
+	namespace {
+		RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) {
+			mapStack.push_front( std::map< std::string, std::string >() );
+		}
 
-	void RenameVars::visit( BasicType *basicType ) {
-		typeBefore( basicType );
-		typeAfter( basicType );
-	}
+		void RenameVars::reset() {
+			level = 0;
+			resetCount++;
+		}
 
-	void RenameVars::visit( PointerType *pointerType ) {
-		typeBefore( pointerType );
-		maybeAccept( pointerType->get_base(), *this );
-		typeAfter( pointerType );
-	}
+		void RenameVars::previsit( TypeInstType * instType ) {
+			previsit( (Type *)instType );
+			std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name );
+			if ( i != mapStack.front().end() ) {
+				instType->name = i->second;
+			} // if
+		}
 
-	void RenameVars::visit( ArrayType *arrayType ) {
-		typeBefore( arrayType );
-		maybeAccept( arrayType->get_dimension(), *this );
-		maybeAccept( arrayType->get_base(), *this );
-		typeAfter( arrayType );
-	}
+		void RenameVars::previsit( Type * type ) {
+			if ( ! type->forall.empty() ) {
+				// copies current name mapping into new mapping
+				mapStack.push_front( mapStack.front() );
+				// renames all "forall" type names to `_${level}_${name}'
+				for ( auto td : type->forall ) {
+					std::ostringstream output;
+					output << "_" << resetCount << "_" << level << "_" << td->name;
+					std::string newname( output.str() );
+					mapStack.front()[ td->get_name() ] = newname;
+					td->name = newname;
+					// ditto for assertion names, the next level in
+					level++;
+					// acceptAll( td->assertions, *this );
+				} // for
+			} // if
+		}
 
-	void RenameVars::visit( FunctionType *functionType ) {
-		typeBefore( functionType );
-		acceptAll( functionType->get_returnVals(), *this );
-		acceptAll( functionType->get_parameters(), *this );
-		typeAfter( functionType );
-	}
-
-	void RenameVars::visit( StructInstType *aggregateUseType ) {
-		typeBefore( aggregateUseType );
-		acceptAll( aggregateUseType->get_parameters(), *this );
-		typeAfter( aggregateUseType );
-	}
-
-	void RenameVars::visit( UnionInstType *aggregateUseType ) {
-		typeBefore( aggregateUseType );
-		acceptAll( aggregateUseType->get_parameters(), *this );
-		typeAfter( aggregateUseType );
-	}
-
-	void RenameVars::visit( EnumInstType *aggregateUseType ) {
-		typeBefore( aggregateUseType );
-		acceptAll( aggregateUseType->get_parameters(), *this );
-		typeAfter( aggregateUseType );
-	}
-
-	void RenameVars::visit( TraitInstType *aggregateUseType ) {
-		typeBefore( aggregateUseType );
-		acceptAll( aggregateUseType->get_parameters(), *this );
-		typeAfter( aggregateUseType );
-	}
-
-	void RenameVars::visit( TypeInstType *instType ) {
-		typeBefore( instType );
-		std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() );
-		if ( i != mapStack.front().end() ) {
-			instType->set_name( i->second );
-		} else {
-		} // if
-		acceptAll( instType->get_parameters(), *this );
-		typeAfter( instType );
-	}
-
-	void RenameVars::visit( TupleType *tupleType ) {
-		typeBefore( tupleType );
-		acceptAll( tupleType->get_types(), *this );
-		typeAfter( tupleType );
-	}
-
-	void RenameVars::visit( VarArgsType *varArgsType ) {
-		typeBefore( varArgsType );
-		typeAfter( varArgsType );
-	}
-
-	void RenameVars::visit( ZeroType *zeroType ) {
-		typeBefore( zeroType );
-		typeAfter( zeroType );
-	}
-
-	void RenameVars::visit( OneType *oneType ) {
-		typeBefore( oneType );
-		typeAfter( oneType );
-	}
-
-	void RenameVars::typeBefore( Type *type ) {
-		if ( ! type->get_forall().empty() ) {
-			// copies current name mapping into new mapping
-			mapStack.push_front( mapStack.front() );
-			// renames all "forall" type names to `_${level}_${name}'
-			for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
-				std::ostringstream output;
-				output << "_" << resetCount << "_" << level << "_" << (*i)->get_name();
-				std::string newname( output.str() );
-				mapStack.front()[ (*i)->get_name() ] = newname;
-				(*i)->set_name( newname );
-				// ditto for assertion names, the next level in
-				level++;
-				acceptAll( (*i)->get_assertions(), *this );
-			} // for
-		} // if
-	}
-
-	void RenameVars::typeAfter( Type *type ) {
-		// clears name mapping added by typeBefore()
-		if ( ! type->get_forall().empty() ) {
-			mapStack.pop_front();
-		} // if
-	}
-
+		void RenameVars::postvisit( Type * type ) {
+			// clears name mapping added by typeBefore()
+			if ( ! type->forall.empty() ) {
+				mapStack.pop_front();
+			} // if
+		}
+	} // namespace
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/RenameVars.h
===================================================================
--- src/ResolvExpr/RenameVars.h	(revision f07c1e6c25a1e3f03dafd36dd27430bfc2ca80c6)
+++ src/ResolvExpr/RenameVars.h	(revision d7d9a605341969df23ea12387498dc6e6fea463c)
@@ -24,33 +24,9 @@
 
 namespace ResolvExpr {
+	/// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID
+	void renameTyVars( Type * );
 
-	/// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID
-	class RenameVars : public Visitor {
-	  public:
-		RenameVars();
-		void reset();
-	  private:
-		virtual void visit( VoidType *basicType );
-		virtual void visit( BasicType *basicType );
-		virtual void visit( PointerType *pointerType );
-		virtual void visit( ArrayType *arrayType );
-		virtual void visit( FunctionType *functionType );
-		virtual void visit( StructInstType *aggregateUseType );
-		virtual void visit( UnionInstType *aggregateUseType );
-		virtual void visit( EnumInstType *aggregateUseType );
-		virtual void visit( TraitInstType *aggregateUseType );
-		virtual void visit( TypeInstType *aggregateUseType );
-		virtual void visit( TupleType *tupleType );
-		virtual void visit( VarArgsType *varArgsType );
-		virtual void visit( ZeroType *zeroType );
-		virtual void visit( OneType *oneType );
-
-		void typeBefore( Type *type );
-		void typeAfter( Type *type );
-		int level, resetCount;
-		std::list< std::map< std::string, std::string > > mapStack;
-	};
-
-	extern RenameVars global_renamer;
+	/// resets internal state of renamer to avoid overflow
+	void resetTyVarRenaming();
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision f07c1e6c25a1e3f03dafd36dd27430bfc2ca80c6)
+++ src/ResolvExpr/Resolver.cc	(revision d7d9a605341969df23ea12387498dc6e6fea463c)
@@ -132,5 +132,5 @@
 
 	void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
-		global_renamer.reset();
+		resetTyVarRenaming();
 		TypeEnvironment env;
 		Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
