Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/AdjustExprType.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -74,7 +74,6 @@
 
 	Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
-		EqvClass eqvClass;
-		if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
-			if ( eqvClass.data.kind == TypeDecl::Ftype ) {
+		if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
+			if ( eqvClass->data.kind == TypeDecl::Ftype ) {
 				return new PointerType{ Type::Qualifiers(), typeInst };
 			}
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -1109,7 +1109,6 @@
 					}
 				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
-					EqvClass eqvClass;
-					if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
-						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
+					if ( const EqvClass *eqvClass = func->env.lookup( typeInst->get_name() ) ) {
+						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
 							Alternative newFunc( *func );
 							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/CastCost.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -43,13 +43,11 @@
 	Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			NamedTypeDecl *namedType;
-			if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
-				if ( eqvClass.type ) {
-					return castCost( src, eqvClass.type, indexer, env );
+			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+				if ( eqvClass->type ) {
+					return castCost( src, eqvClass->type, indexer, env );
 				} else {
 					return Cost::infinity;
 				}
-			} else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
+			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
 				// all typedefs should be gone by this point
 				TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/ConversionCost.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -43,14 +43,12 @@
 	Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			NamedTypeDecl *namedType;
 			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
-			if ( env.lookup( destAsTypeInst->name, eqvClass ) ) {
-				if ( eqvClass.type ) {
-					return conversionCost( src, eqvClass.type, indexer, env );
+			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
+				if ( eqvClass->type ) {
+					return conversionCost( src, eqvClass->type, indexer, env );
 				} else {
 					return Cost::infinity;
 				}
-			} else if ( ( namedType = indexer.lookupType( destAsTypeInst->name ) ) ) {
+			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
 				PRINT( std::cerr << " found" << std::endl; )
 				TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
@@ -362,13 +360,11 @@
 
 	void ConversionCost::postvisit( TypeInstType *inst ) {
-		EqvClass eqvClass;
-		NamedTypeDecl *namedType;
-		if ( env.lookup( inst->name, eqvClass ) ) {
-			cost = costFunc( eqvClass.type, dest, indexer, env );
+		if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
+			cost = costFunc( eqvClass->type, dest, indexer, env );
 		} else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
 			}
-		} else if ( ( namedType = indexer.lookupType( inst->name ) ) ) {
+		} else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
 			TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
 			// all typedefs should be gone by this point
Index: src/ResolvExpr/Occurs.cc
===================================================================
--- src/ResolvExpr/Occurs.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/Occurs.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -38,7 +38,6 @@
 
 	Occurs::Occurs( std::string varName, const TypeEnvironment & env ) : result( false ), tenv( env ) {
-		EqvClass eqvClass;
-		if ( tenv.lookup( varName, eqvClass ) ) {
-			eqvVars = eqvClass.vars;
+		if ( const EqvClass *eqvClass = tenv.lookup( varName ) ) {
+			eqvVars = eqvClass->vars;
 		} else {
 			eqvVars.insert( varName );
@@ -47,16 +46,15 @@
 
 	void Occurs::previsit( TypeInstType * typeInst ) {
-		EqvClass eqvClass;
-///   std::cerr << "searching for vars: ";
+		///   std::cerr << "searching for vars: ";
 ///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cerr, " " ) );
 ///   std::cerr << std::endl;
 		if ( eqvVars.find( typeInst->get_name() ) != eqvVars.end() ) {
 			result = true;
-		} else if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
-			if ( eqvClass.type ) {
+		} else if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
+			if ( eqvClass->type ) {
 ///       std::cerr << typeInst->get_name() << " is bound to";
 ///       eqvClass.type->print( std::cerr );
 ///       std::cerr << std::endl;
-				eqvClass.type->accept( *visitor );
+				eqvClass->type->accept( *visitor );
 			} // if
 		} // if
Index: src/ResolvExpr/PolyCost.cc
===================================================================
--- src/ResolvExpr/PolyCost.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/PolyCost.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -39,8 +39,7 @@
 
 	void PolyCost::previsit(TypeInstType * typeInst) {
-		EqvClass eqvClass;
-		if ( tenv.lookup( typeInst->name, eqvClass ) ) {
-			if ( eqvClass.type ) {
-				if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
+		if ( const EqvClass *eqvClass = tenv.lookup( typeInst->name ) ) {
+			if ( eqvClass->type ) {
+				if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass->type ) ) {
 					if ( indexer.lookupType( otherTypeInst->name ) ) {
 						// bound to opaque type
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -51,7 +51,6 @@
 		// std::cerr << "assignable: " << src << " | " << dest << std::endl;
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
-				return ptrsAssignable( src, eqvClass.type, env );
+			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
@@ -95,8 +94,9 @@
 	void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
 	void PtrsAssignable::postvisit( TypeInstType *inst ) {
-		EqvClass eqvClass;
-		if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
-			// T * = S * for any S depends on the type bound to T
-			result = ptrsAssignable( eqvClass.type, dest, env );
+		if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
+			if ( eqvClass->type ) {
+				// T * = S * for any S depends on the type bound to T
+				result = ptrsAssignable( eqvClass->type, dest, env );
+			}
 		} // if
 	}
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/PtrsCastable.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -57,5 +57,4 @@
 				return -1;
 			} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
-				EqvClass eqvClass;
 				if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
 					if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
@@ -64,6 +63,6 @@
 						} // if
 					} //if
-				} else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
-					if ( eqvClass.data.kind == TypeDecl::Ftype ) {
+				} else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
+					if ( eqvClass->data.kind == TypeDecl::Ftype ) {
 						return -1;
 					} // if
@@ -79,8 +78,7 @@
 	int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
 				// xxx - should this be ptrsCastable?
-				return ptrsAssignable( src, eqvClass.type, env );
+				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -17,5 +17,5 @@
 #include <algorithm>                   // for copy, set_intersection
 #include <iterator>                    // for ostream_iterator, insert_iterator
-#include <utility>                     // for pair
+#include <utility>                     // for pair, move
 
 #include "Common/PassVisitor.h"        // for PassVisitor<GcTracer>
@@ -79,31 +79,38 @@
 	}
 
-	bool TypeEnvironment::lookup( const std::string &var, EqvClass &eqvClass ) const {
+	const EqvClass* TypeEnvironment::lookup( const std::string &var ) const {
 		for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
 			if ( i->vars.find( var ) != i->vars.end() ) {
 ///       std::cout << var << " is in class ";
 ///       i->print( std::cout );
-				eqvClass = *i;
-				return true;
+				return &*i;
 			}
 ///     std::cout << var << " is not in class ";
 ///     i->print( std::cout );
 		} // for
-		return false;
+		return nullptr;
+	}
+
+	/// Removes any class from env that intersects eqvClass
+	void filterOverlappingClasses( std::list<EqvClass> &env, const EqvClass &eqvClass ) {
+		for ( auto i = env.begin(); i != env.end(); ) {
+			auto next = i;
+			++next;
+			std::set<std::string> intersection;
+			std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), 
+				std::inserter( intersection, intersection.begin() ) );
+			if ( ! intersection.empty() ) { env.erase( i ); }
+			i = next;
+		}
 	}
 
 	void TypeEnvironment::add( const EqvClass &eqvClass ) {
-		std::list< EqvClass >::iterator i = env.begin();
-		while ( i != env.end() ) {
-			std::list< EqvClass >::iterator next = i;
-			next++;
-			std::set< std::string > intersection;
-			std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), std::inserter( intersection, intersection.begin() ) );
-			if ( ! intersection.empty() ) {
-				env.erase( i );
-			} // if
-			i = next;
-		} // while
-		env.insert( env.end(), eqvClass );
+		filterOverlappingClasses( env, eqvClass );
+		env.push_back( eqvClass );
+	}
+
+	void TypeEnvironment::add( EqvClass &&eqvClass ) {
+		filterOverlappingClasses( env, eqvClass );
+		env.push_back( std::move(eqvClass) );
 	}
 
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/TypeEnvironment.h	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -85,6 +85,7 @@
 	class TypeEnvironment {
 	  public:
-		bool lookup( const std::string &var, EqvClass &eqvClass ) const;
+		const EqvClass* lookup( const std::string &var ) const;
 		void add( const EqvClass &eqvClass );
+		void add( EqvClass &&eqvClass  );
 		void add( const Type::ForallList &tyDecls );
 		void add( const TypeSubstitution & sub );
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 75308bcc1e9eee8d871b17db8841634a08cd0141)
+++ src/ResolvExpr/Unify.cc	(revision 0182bfaedbda41b528bda0ec934c1c190335bc44)
@@ -19,5 +19,5 @@
 #include <set>                    // for set
 #include <string>                 // for string, operator==, operator!=, bas...
-#include <utility>                // for pair
+#include <utility>                // for pair, move
 
 #include "Common/PassVisitor.h"   // for PassVisitor
@@ -159,16 +159,16 @@
 			return false;
 		} // if
-		EqvClass curClass;
-		if ( env.lookup( typeInst->get_name(), curClass ) ) {
-			if ( curClass.type ) {
+		if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
+			if ( curClass->type ) {
 				Type *common = 0;
 				// attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
-				Type* newType = curClass.type->clone();
+				Type* newType = curClass->type->clone();
 				newType->get_qualifiers() = typeInst->get_qualifiers();
-				if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
+				if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
 					if ( common ) {
 						common->get_qualifiers() = Type::Qualifiers();
-						curClass.type = common;
-						env.add( curClass );
+						EqvClass newClass = *curClass;
+						newClass.type = common;
+						env.add( std::move(newClass) );
 					} // if
 					return true;
@@ -177,8 +177,9 @@
 				} // if
 			} else {
-				curClass.type = other->clone();
-				curClass.type->get_qualifiers() = Type::Qualifiers();
-				curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
-				env.add( curClass );
+				EqvClass newClass = *curClass;
+				newClass.type = other->clone();
+				newClass.type->get_qualifiers() = Type::Qualifiers();
+				newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
+				env.add( std::move(newClass) );
 			} // if
 		} else {
@@ -196,28 +197,26 @@
 	bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
 		bool result = true;
-		EqvClass class1, class2;
-		bool hasClass1 = false, hasClass2 = false;
+		const EqvClass *class1 = env.lookup( var1->get_name() );
+		const EqvClass *class2 = env.lookup( var2->get_name() );
 		bool widen1 = false, widen2 = false;
-		Type *type1 = 0, *type2 = 0;
-
-		if ( env.lookup( var1->get_name(), class1 ) ) {
-			hasClass1 = true;
-			if ( class1.type ) {
-				if ( occurs( class1.type, var2->get_name(), env ) ) {
+		Type *type1 = nullptr, *type2 = nullptr;
+
+		if ( class1 ) {
+			if ( class1->type ) {
+				if ( occurs( class1->type, var2->get_name(), env ) ) {
 					return false;
 				} // if
-				type1 = class1.type->clone();
-			} // if
-			widen1 = widenMode.widenFirst && class1.allowWidening;
-		} // if
-		if ( env.lookup( var2->get_name(), class2 ) ) {
-			hasClass2 = true;
-			if ( class2.type ) {
-				if ( occurs( class2.type, var1->get_name(), env ) ) {
+				type1 = class1->type->clone();
+			} // if
+			widen1 = widenMode.widenFirst && class1->allowWidening;
+		} // if
+		if ( class2 ) {
+			if ( class2->type ) {
+				if ( occurs( class2->type, var1->get_name(), env ) ) {
 					return false;
 				} // if
-				type2 = class2.type->clone();
-			} // if
-			widen2 = widenMode.widenSecond && class2.allowWidening;
+				type2 = class2->type->clone();
+			} // if
+			widen2 = widenMode.widenSecond && class2->allowWidening;
 		} // if
 
@@ -227,32 +226,37 @@
 			Type *common = 0;
 			if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
-				class1.vars.insert( class2.vars.begin(), class2.vars.end() );
-				class1.allowWidening = widen1 && widen2;
+				EqvClass newClass1 = *class1;
+				newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
+				newClass1.allowWidening = widen1 && widen2;
 				if ( common ) {
 					common->get_qualifiers() = Type::Qualifiers();
-					class1.type = common;
+					newClass1.type = common;
 				} // if
-				env.add( class1 );
+				env.add( std::move(newClass1) );
 			} else {
 				result = false;
 			} // if
-		} else if ( hasClass1 && hasClass2 ) {
+		} else if ( class1 && class2 ) {
 			if ( type1 ) {
-				class1.vars.insert( class2.vars.begin(), class2.vars.end() );
-				class1.allowWidening = widen1;
-				env.add( class1 );
+				EqvClass newClass1 = *class1;
+				newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
+				newClass1.allowWidening = widen1;
+				env.add( std::move(newClass1) );
 			} else {
-				class2.vars.insert( class1.vars.begin(), class1.vars.end() );
-				class2.allowWidening = widen2;
-				env.add( class2 );
-			} // if
-		} else if ( hasClass1 ) {
-			class1.vars.insert( var2->get_name() );
-			class1.allowWidening = widen1;
-			env.add( class1 );
-		} else if ( hasClass2 ) {
-			class2.vars.insert( var1->get_name() );
-			class2.allowWidening = widen2;
-			env.add( class2 );
+				EqvClass newClass2 = *class2;
+				newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
+				newClass2.allowWidening = widen2;
+				env.add( std::move(newClass2) );
+			} // if
+		} else if ( class1 ) {
+			EqvClass newClass1 = *class1;
+			newClass1.vars.insert( var2->get_name() );
+			newClass1.allowWidening = widen1;
+			env.add( std::move(newClass1) );
+		} else if ( class2 ) {
+			EqvClass newClass2 = *class2;
+			newClass2.vars.insert( var1->get_name() );
+			newClass2.allowWidening = widen2;
+			env.add( std::move(newClass2) );
 		} else {
 			EqvClass newClass;
@@ -521,11 +525,8 @@
 		void premutate( TypeInstType * ) { visit_children = false; }
 		Type * postmutate( TypeInstType * typeInst ) {
-			EqvClass eqvClass;
-			if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
-				if ( eqvClass.data.kind == TypeDecl::Ttype ) {
-					// expand ttype parameter into its actual type
-					if ( eqvClass.type ) {
-						return eqvClass.type->clone();
-					}
+			if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
+				// expand ttype parameter into its actual type
+				if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) {
+					return eqvClass->type->clone();
 				}
 			}
