Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -373,5 +373,5 @@
 							unify(
 								ttype, argType, newResult.env, newResult.need, newResult.have,
-								newResult.open, symtab )
+								newResult.open )
 						) {
 							finalResults.emplace_back( std::move( newResult ) );
@@ -444,5 +444,5 @@
 				)
 
-				if ( unify( paramType, argType, env, need, have, open, symtab ) ) {
+				if ( unify( paramType, argType, env, need, have, open ) ) {
 					unsigned nextExpl = results[i].nextExpl + 1;
 					if ( nextExpl == expl.exprs.size() ) { nextExpl = 0; }
@@ -463,5 +463,5 @@
 					ast::OpenVarSet open = results[i].open;
 
-					if ( unify( paramType, cnst->result, env, need, have, open, symtab ) ) {
+					if ( unify( paramType, cnst->result, env, need, have, open ) ) {
 						results.emplace_back(
 							i, new ast::DefaultArgExpr{ cnst->location, cnst }, std::move( env ),
@@ -506,5 +506,5 @@
 
 				// attempt to unify types
-				if ( unify( paramType, argType, env, need, have, open, symtab ) ) {
+				if ( unify( paramType, argType, env, need, have, open ) ) {
 					// add new result
 					results.emplace_back(
@@ -750,5 +750,5 @@
 			const ast::Type * returnType = funcType->returns.front();
 			if ( ! unify(
-				returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
+				returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen )
 			) {
 				// unification failed, do not pursue this candidate
@@ -1159,5 +1159,5 @@
 
 			// unification run for side-effects
-			unify( toType, cand->expr->result, cand->env, need, have, open, symtab );
+			unify( toType, cand->expr->result, cand->env, need, have, open );
 			Cost thisCost =
 				(castExpr->isGenerated == ast::GeneratedFlag::GeneratedCast)
@@ -1483,5 +1483,5 @@
 					if (
 						unify(
-							r2->expr->result, r3->expr->result, env, need, have, open, symtab,
+							r2->expr->result, r3->expr->result, env, need, have, open,
 							common )
 					) {
@@ -1556,5 +1556,5 @@
 				if (
 					unify(
-						r1->expr->result, r2->expr->result, env, need, have, open, symtab,
+						r1->expr->result, r2->expr->result, env, need, have, open,
 						common )
 				) {
@@ -1659,5 +1659,5 @@
 
 				// unification run for side-effects
-				bool canUnify = unify( toType, cand->expr->result, env, need, have, open, symtab );
+				bool canUnify = unify( toType, cand->expr->result, env, need, have, open );
 				(void) canUnify;
 				Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/CastCost.cc	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -165,5 +165,5 @@
 				if (
 					pointerType->qualifiers <= ptr->qualifiers
-					&& typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env )
+					&& typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, env )
 				) {
 					cost = Cost::safe;
@@ -232,5 +232,5 @@
 	)
 
-	if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
+	if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
 		PRINT( std::cerr << "compatible!" << std::endl; )
 		return Cost::zero;
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/CommonType.cc	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -676,5 +676,4 @@
 		const ast::Type * type2;
 		WidenMode widen;
-		const ast::SymbolTable & symtab;
 		ast::TypeEnvironment & tenv;
 		const ast::OpenVarSet & open;
@@ -686,8 +685,8 @@
 
 		CommonType_new(
-			const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
+			const ast::Type * t2, WidenMode w,
 			ast::TypeEnvironment & env, const ast::OpenVarSet & o,
 			ast::AssertionSet & need, ast::AssertionSet & have )
-		: type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), need (need), have (have) ,result() {}
+		: type2( t2 ), widen( w ), tenv( env ), open( o ), need (need), have (have) ,result() {}
 
 		void previsit( const ast::Node * ) { visit_children = false; }
@@ -749,5 +748,5 @@
 					ast::AssertionSet need, have;
 					if ( ! tenv.bindVar(
-						var, voidPtr->base, entry->second, need, have, open, widen, symtab )
+						var, voidPtr->base, entry->second, need, have, open, widen )
 					) return;
 				}
@@ -762,5 +761,5 @@
 				ast::OpenVarSet newOpen{ open };
 				if (enumInst->base->base 
-				&& unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen, symtab)) {
+				&& unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen)) {
 					result = type1;
 					return true;
@@ -799,5 +798,5 @@
 
 					ast::OpenVarSet newOpen{ open };
-					if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
+					if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {
 						result = pointer;
 						if ( q1.val != q2.val ) {
@@ -842,5 +841,5 @@
 								if (unifyExact(
 									arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
-									noWiden(), symtab )) {
+									noWiden() )) {
 										break;
 
@@ -851,5 +850,5 @@
 								if (unifyExact(
 									tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open,
-									noWiden(), symtab )) {
+									noWiden() )) {
 										break;
 
@@ -875,5 +874,5 @@
 
 										if ( ! unifyExact(
-											base1, base2, tenv, need, have, open, noWiden(), symtab )
+											base1, base2, tenv, need, have, open, noWiden() )
 										) return;
 									}	
@@ -895,5 +894,5 @@
 
 										if ( ! unifyExact(
-											base1, base2, tenv, need, have, open, noWiden(), symtab )
+											base1, base2, tenv, need, have, open, noWiden() )
 										) return;
 									}	
@@ -903,5 +902,5 @@
 							}
 							else if (! unifyExact(
-								arg1, arg2, tenv, need, have, open, noWiden(), symtab )) return;
+								arg1, arg2, tenv, need, have, open, noWiden() )) return;
 
 							++crnt1; ++crnt2;
@@ -913,5 +912,5 @@
 							if (! unifyExact(
 								t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
-								noWiden(), symtab )) return;
+								noWiden() )) return;
 						} else if ( crnt2 != end2 ) {
 							// try unifying empty tuple with ttype
@@ -920,8 +919,8 @@
 							if (! unifyExact(
 								tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open,
-								noWiden(), symtab )) return;
+								noWiden() )) return;
 						}
 						if ((f1->returns.size() == 0 && f2->returns.size() == 0)
-						  || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden(), symtab))) {
+						  || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden()))) {
 							result = pointer;
 
@@ -980,5 +979,5 @@
 
 					ast::OpenVarSet newOpen{ open };
-					if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
+					if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {
 						result = ref;
 						if ( q1.val != q2.val ) {
@@ -995,5 +994,5 @@
 			} else {
 				if (!dynamic_cast<const ast::EnumInstType *>(type2))
-					result = commonType( type2, ref, tenv, need, have, open, widen, symtab );
+					result = commonType( type2, ref, tenv, need, have, open, widen );
 			}
 		}
@@ -1013,32 +1012,10 @@
 		void postvisit( const ast::EnumInstType * enumInst ) {
 			if (!dynamic_cast<const ast::EnumInstType *>(type2))
-				result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab);
+				result = commonType( type2, enumInst, tenv, need, have, open, widen);
 		}
 
 		void postvisit( const ast::TraitInstType * ) {}
 
-		void postvisit( const ast::TypeInstType * inst ) {
-			if ( ! widen.first ) return;
-			if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
-				if ( const ast::Type * base =
-						strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
-				) {
-					ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
-
-					// force t{1,2} to be cloned if their qualifiers must be mutated
-					ast::ptr< ast::Type > t1{ base }, t2{ type2 };
-					reset_qualifiers( t1, q1 );
-					reset_qualifiers( t2 );
-
-					ast::OpenVarSet newOpen{ open };
-					if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
-						result = type2;
-						reset_qualifiers( result, q1 | q2 );
-					} else {
-						tryResolveWithTypedEnum( t1 );
-					}
-				}
-			}
-		}
+		void postvisit( const ast::TypeInstType * inst ) {}
 
 		void postvisit( const ast::TupleType * tuple) {
@@ -1103,5 +1080,5 @@
 		ast::ptr< ast::Type > handleReference(
 			const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
-			const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
+			ast::TypeEnvironment & env,
 			const ast::OpenVarSet & open
 		) {
@@ -1111,5 +1088,5 @@
 
 			// need unify to bind type variables
-			if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) {
+			if ( unify( t1, t2, env, have, need, newOpen, common ) ) {
 				ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
 				PRINT(
@@ -1135,5 +1112,5 @@
 			const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
 			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab
+			const ast::OpenVarSet & open, WidenMode widen
 	) {
 		unsigned depth1 = type1->referenceDepth();
@@ -1150,8 +1127,8 @@
 			if ( depth1 > depth2 ) {
 				assert( ref1 );
-				result = handleReference( ref1->base, type2, widen, symtab, env, open );
+				result = handleReference( ref1->base, type2, widen, env, open );
 			} else {  // implies depth1 < depth2
 				assert( ref2 );
-				result = handleReference( type1, ref2->base, widen, symtab, env, open );
+				result = handleReference( type1, ref2->base, widen, env, open );
 			}
 
@@ -1171,34 +1148,9 @@
 		}
 		// otherwise both are reference types of the same depth and this is handled by the visitor
-		ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open, need, have };
+		ast::Pass<CommonType_new> visitor{ type2, widen, env, open, need, have };
 		type1->accept( visitor );
-		ast::ptr< ast::Type > result = visitor.core.result;
-
-		// handling for opaque type declarations (?)
-		if ( ! result && widen.second ) {
-			if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) {
-				if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
-					auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt );
-					if ( type->base ) {
-						ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
-						ast::OpenVarSet newOpen{ open };
-
-						// force t{1,2} to be cloned if its qualifiers must be stripped, so that
-						// type1 and type->base are left unchanged; calling convention forces
-						// {type1,type->base}->strong_ref >= 1
-						ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
-						reset_qualifiers( t1 );
-						reset_qualifiers( t2, q1 );
-
-						if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
-							result = t1;
-							reset_qualifiers( result, q1 | q2 );
-						}
-					}
-				}
-			}
-		}
-
-		return result;
+		// ast::ptr< ast::Type > result = visitor.core.result;
+
+		return visitor.core.result;
 	}
 
Index: src/ResolvExpr/CommonType.hpp
===================================================================
--- src/ResolvExpr/CommonType.hpp	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/CommonType.hpp	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -36,6 +36,5 @@
 	ast::TypeEnvironment & env,
 	ast::AssertionSet & need, ast::AssertionSet & have,
-	const ast::OpenVarSet & open, WidenMode widen,
-	const ast::SymbolTable & symtab );
+	const ast::OpenVarSet & open, WidenMode widen);
 
 }
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/ConversionCost.cc	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -532,5 +532,5 @@
 		}
 	}
-	if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
+	if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
 		return Cost::zero;
 	} else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
@@ -566,5 +566,5 @@
 			ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
 			if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
-					srcAsRef->base, dstAsRef->base, symtab, env ) ) {
+					srcAsRef->base, dstAsRef->base, env ) ) {
 				if ( tq1 == tq2 ) {
 					return Cost::zero;
@@ -587,5 +587,5 @@
 		const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
 		assert( dstAsRef );
-		if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) {
+		if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
 			if ( srcIsLvalue ) {
 				if ( src->qualifiers == dstAsRef->base->qualifiers ) {
@@ -653,5 +653,5 @@
 		ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
 		if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
-				pointerType->base, dstAsPtr->base, symtab, env ) ) {
+				pointerType->base, dstAsPtr->base, env ) ) {
 			if ( tq1 == tq2 ) {
 				cost = Cost::zero;
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/Resolver.cc	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -1108,5 +1108,5 @@
 		void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
 			if ( const ast::CastExpr * castExpr = expr.as< ast::CastExpr >() ) {
-				if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
+				if ( typesCompatible( castExpr->arg->result, castExpr->result ) ) {
 					// cast is to the same type as its argument, remove it
 					swap_and_save_env( expr, castExpr->arg );
@@ -1834,6 +1834,5 @@
 								if (
 									! unify(
-										arg->expr->result, *param, resultEnv, need, have, open,
-										symtab )
+										arg->expr->result, *param, resultEnv, need, have, open )
 								) {
 									// Type doesn't match
Index: src/ResolvExpr/SatisfyAssertions.cpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.cpp	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/SatisfyAssertions.cpp	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -215,5 +215,5 @@
 			findOpenVars( adjType, newOpen, closed, newNeed, have, FirstOpen );
 			if ( allowConversion ) {
-				if ( auto c = commonType( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) {
+				if ( auto c = commonType( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true} ) ) {
 					// set up binding slot for recursive assertions
 					ast::UniqueId crntResnSlot = 0;
@@ -229,5 +229,5 @@
 			}
 			else {
-				if ( unifyExact( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) {
+				if ( unifyExact( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true} ) ) {
 					// set up binding slot for recursive assertions
 					ast::UniqueId crntResnSlot = 0;
@@ -392,5 +392,5 @@
 			mergeOpenVars( open, i.match.open );
 
-			if ( ! env.combine( i.match.env, open, symtab ) ) return false;
+			if ( ! env.combine( i.match.env, open ) ) return false;
 
 			crnt.emplace_back( i );
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/Unify.cc	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -128,5 +128,5 @@
 		const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
 		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
-		WidenMode widen, const ast::SymbolTable & symtab );
+		WidenMode widen );
 
 	bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
@@ -150,5 +150,5 @@
 
 	bool typesCompatible(
-			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
+			const ast::Type * first, const ast::Type * second,
 			const ast::TypeEnvironment & env ) {
 		ast::TypeEnvironment newEnv;
@@ -163,5 +163,5 @@
 		findOpenVars( newSecond, open, closed, need, have, FirstOpen );
 
-		return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
+		return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden() );
 	}
 
@@ -183,5 +183,5 @@
 
 	bool typesCompatibleIgnoreQualifiers(
-			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
+			const ast::Type * first, const ast::Type * second,
 			const ast::TypeEnvironment & env ) {
 		ast::TypeEnvironment newEnv;
@@ -216,5 +216,5 @@
 			subFirst,
 			subSecond,
-			newEnv, need, have, open, noWiden(), symtab );
+			newEnv, need, have, open, noWiden() );
 	}
 
@@ -786,5 +786,4 @@
 		const ast::OpenVarSet & open;
 		WidenMode widen;
-		const ast::SymbolTable & symtab;
 	public:
 		static size_t traceId;
@@ -793,8 +792,7 @@
 		Unify_new(
 			const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
-			ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
-			const ast::SymbolTable & symtab )
+			ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen )
 		: type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
-		  symtab(symtab), result(false) {}
+		result(false) {}
 
 		void previsit( const ast::Node * ) { visit_children = false; }
@@ -814,5 +812,5 @@
 				result = unifyExact(
 					pointer->base, pointer2->base, tenv, need, have, open,
-					noWiden(), symtab );
+					noWiden());
 			}
 		}
@@ -837,6 +835,5 @@
 
 			result = unifyExact(
-				array->base, array2->base, tenv, need, have, open, noWiden(),
-				symtab );
+				array->base, array2->base, tenv, need, have, open, noWiden());
 		}
 
@@ -844,6 +841,5 @@
 			if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
 				result = unifyExact(
-					ref->base, ref2->base, tenv, need, have, open, noWiden(),
-					symtab );
+					ref->base, ref2->base, tenv, need, have, open, noWiden());
 			}
 		}
@@ -854,6 +850,5 @@
 		static bool unifyTypeList(
 			Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
-			const ast::SymbolTable & symtab
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
 		) {
 			while ( crnt1 != end1 && crnt2 != end2 ) {
@@ -868,14 +863,14 @@
 					return unifyExact(
 						t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
-						noWiden(), symtab );
+						noWiden() );
 				} else if ( ! isTuple1 && isTuple2 ) {
 					// combine remainder of list1, then unify
 					return unifyExact(
 						tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
-						noWiden(), symtab );
+						noWiden() );
 				}
 
 				if ( ! unifyExact(
-					t1, t2, env, need, have, open, noWiden(), symtab )
+					t1, t2, env, need, have, open, noWiden() )
 				) return false;
 
@@ -891,5 +886,5 @@
 				return unifyExact(
 					t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
-					noWiden(), symtab );
+					noWiden() );
 			} else if ( crnt2 != end2 ) {
 				// try unifying empty tuple with ttype
@@ -898,5 +893,5 @@
 				return unifyExact(
 					tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
-					noWiden(), symtab );
+					noWiden() );
 			}
 
@@ -908,9 +903,8 @@
 			const std::vector< ast::ptr< ast::Type > > & list2,
 			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-			const ast::OpenVarSet & open, const ast::SymbolTable & symtab
+			const ast::OpenVarSet & open
 		) {
 			return unifyTypeList(
-				list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
-				symtab );
+				list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open);
 		}
 
@@ -953,7 +947,7 @@
 			) return;
 
-			if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return;
+			if ( ! unifyTypeList( params, params2, tenv, need, have, open ) ) return;
 			if ( ! unifyTypeList(
-				func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
+				func->returns, func2->returns, tenv, need, have, open ) ) return;
 
 			markAssertions( have, need, func );
@@ -1026,5 +1020,5 @@
 
 				if ( ! unifyExact(
-						pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
+						pty, pty2, tenv, need, have, open, noWiden() ) ) {
 					result = false;
 					return;
@@ -1065,6 +1059,5 @@
 			const std::vector< ast::ptr< ast::Type > > & list1,
 			const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
-			const ast::SymbolTable & symtab
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open
 		) {
 			auto crnt1 = list1.begin();
@@ -1081,14 +1074,14 @@
 					return unifyExact(
 						t1, tupleFromTypes( list2 ), env, need, have, open,
-						noWiden(), symtab );
+						noWiden() );
 				} else if ( ! isTuple1 && isTuple2 ) {
 					// combine entirety of list1, then unify
 					return unifyExact(
 						tupleFromTypes( list1 ), t2, env, need, have, open,
-						noWiden(), symtab );
+						noWiden() );
 				}
 
 				if ( ! unifyExact(
-					t1, t2, env, need, have, open, noWiden(), symtab )
+					t1, t2, env, need, have, open, noWiden() )
 				) return false;
 
@@ -1104,5 +1097,5 @@
 				return unifyExact(
 						t1, tupleFromTypes( list2 ), env, need, have, open,
-						noWiden(), symtab );
+						noWiden() );
 			} else if ( crnt2 != list2.end() ) {
 				// try unifying empty tuple with ttype
@@ -1113,5 +1106,5 @@
 				return unifyExact(
 						tupleFromTypes( list1 ), t2, env, need, have, open,
-						noWiden(), symtab );
+						noWiden() );
 			}
 
@@ -1132,5 +1125,5 @@
 			auto types2 = flatten( flat2 );
 
-			result = unifyList( types, types2, tenv, need, have, open, symtab );
+			result = unifyList( types, types2, tenv, need, have, open );
 		}
 
@@ -1156,8 +1149,8 @@
 			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
 			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-			ast::OpenVarSet & open, const ast::SymbolTable & symtab
+			ast::OpenVarSet & open
 	) {
 		ast::ptr<ast::Type> common;
-		return unify( type1, type2, env, need, have, open, symtab, common );
+		return unify( type1, type2, env, need, have, open, common );
 	}
 
@@ -1165,5 +1158,5 @@
 			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
 			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-			ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
+			ast::OpenVarSet & open, ast::ptr<ast::Type> & common
 	) {
 		ast::OpenVarSet closed;
@@ -1171,5 +1164,5 @@
 		findOpenVars( type2, open, closed, need, have, FirstOpen );
 		return unifyInexact(
-			type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
+			type1, type2, env, need, have, open, WidenMode{ true, true }, common );
 	}
 
@@ -1177,5 +1170,5 @@
 			const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
 			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
-			WidenMode widen, const ast::SymbolTable & symtab
+			WidenMode widen
 	) {
 		if ( type1->qualifiers != type2->qualifiers ) return false;
@@ -1193,12 +1186,12 @@
 			return env.bindVarToVar(
 				var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
-				open, widen, symtab );
+				open, widen );
 		} else if ( isopen1 ) {
-			return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab );
+			return env.bindVar( var1, type2, entry1->second, need, have, open, widen );
 		} else if ( isopen2 ) {
-			return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
+			return env.bindVar( var2, type1, entry2->second, need, have, open, widen );
 		} else {
 			return ast::Pass<Unify_new>::read(
-				type1, type2, env, need, have, open, widen, symtab );
+				type1, type2, env, need, have, open, widen );
 		}
 	}
@@ -1207,5 +1200,5 @@
 			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
 			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
+			const ast::OpenVarSet & open, WidenMode widen,
 			ast::ptr<ast::Type> & common
 	) {
@@ -1221,5 +1214,5 @@
 		ast::ptr< ast::Type > t2_(t2);
 
-		if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
+		if ( unifyExact( t1, t2, env, need, have, open, widen ) ) {
 			// if exact unification on unqualified types, try to merge qualifiers
 			if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
@@ -1231,5 +1224,5 @@
 			}
 
-		} else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) {
+		} else if (( common = commonType( t1, t2, env, need, have, open, widen ))) {
 			// no exact unification, but common type
 			auto c = shallowCopy(common.get());
Index: src/ResolvExpr/Unify.h
===================================================================
--- src/ResolvExpr/Unify.h	(revision bccd70a18277379d29bc911ade6a08acf9c36dbd)
+++ src/ResolvExpr/Unify.h	(revision b5e3a8068dfee9cd536827ae412ffa5a94be810f)
@@ -59,28 +59,28 @@
 	const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
 	ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-	ast::OpenVarSet & open, const ast::SymbolTable & symtab );
+	ast::OpenVarSet & open );
 
 bool unify(
 	const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
 	ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-	ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
+	ast::OpenVarSet & open, ast::ptr<ast::Type> & common );
 
 bool unifyExact(
 	const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
 	ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
-	WidenMode widen, const ast::SymbolTable & symtab );
+	WidenMode widen );
 
 bool unifyInexact(
 	const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
 	ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-	const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
+	const ast::OpenVarSet & open, WidenMode widen, 
 	ast::ptr<ast::Type> & common );
 
 bool typesCompatible(
-	const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
+	const ast::Type *, const ast::Type *, 
 	const ast::TypeEnvironment & env = {} );
 
 bool typesCompatibleIgnoreQualifiers(
-	const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
+	const ast::Type *, const ast::Type *,
 	const ast::TypeEnvironment & env = {} );
 
