Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 4ac402ddad18fa0baca5b47593a1b262b3702fa0)
+++ src/ResolvExpr/ConversionCost.cc	(revision fc12f0538e95e9c017d414a9a9c10748cc02bacd)
@@ -21,24 +21,8 @@
 
 #include "ResolvExpr/Cost.h"             // for Cost
-#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
 #include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
 #include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
-#include "SymTab/Indexer.h"              // for Indexer
-#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
-#include "SynTree/Type.h"                // for Type, BasicType, TypeInstType
-
 
 namespace ResolvExpr {
-#if 0
-	const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0,  0 };
-	const Cost Cost::infinity =  Cost{ -1, -1, -1, -1, -1,  1, -1 };
-	const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0,  0 };
-	const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0,  0 };
-	const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0,  0 };
-	const Cost Cost::sign =      Cost{  0,  0,  0,  1,  0,  0,  0 };
-	const Cost Cost::var =       Cost{  0,  0,  0,  0,  1,  0,  0 };
-	const Cost Cost::spec =      Cost{  0,  0,  0,  0,  0, -1,  0 };
-	const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  0,  1 };
-#endif
 
 #if 0
@@ -47,155 +31,4 @@
 #define PRINT(x)
 #endif
-
-	Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
-			const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
-		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
-			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
-			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
-				if ( eqvClass->type ) {
-					return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
-				} else {
-					return Cost::infinity;
-				}
-			} else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
-				PRINT( std::cerr << " found" << std::endl; )
-				const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
-				// all typedefs should be gone by this point
-				assert( type );
-				if ( type->base ) {
-					return conversionCost( src, type->base, srcIsLvalue, indexer, env )
-						+ Cost::safe;
-				} // if
-			} // if
-			PRINT( std::cerr << " not found" << std::endl; )
-		} // if
-		PRINT(
-			std::cerr << "src is ";
-			src->print( std::cerr );
-			std::cerr << std::endl << "dest is ";
-			dest->print( std::cerr );
-			std::cerr << std::endl << "env is" << std::endl;
-			env.print( std::cerr, 8 );
-		)
-		if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
-			PRINT( std::cerr << "compatible!" << std::endl; )
-			return Cost::zero;
-		} else if ( dynamic_cast< const VoidType * >( dest ) ) {
-			return Cost::safe;
-		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
-			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
-				return ptrsAssignable( t1, t2, env );
-			});
-		} else {
-			PassVisitor<ConversionCost> converter(
-				dest, srcIsLvalue, indexer, env,
-				(Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
-					conversionCost );
-			src->accept( converter );
-			if ( converter.pass.get_cost() == Cost::infinity ) {
-				return Cost::infinity;
-			} else {
-				return converter.pass.get_cost() + Cost::zero;
-			} // if
-		} // if
-	}
-
-	static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
-			int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
-		PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
-		if ( diff > 0 ) {
-			// TODO: document this
-			Cost cost = convertToReferenceCost(
-				strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
-				diff-1, indexer, env, func );
-			cost.incReference();
-			return cost;
-		} else if ( diff < -1 ) {
-			// TODO: document this
-			Cost cost = convertToReferenceCost(
-				src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
-				diff+1, indexer, env, func );
-			cost.incReference();
-			return cost;
-		} else if ( diff == 0 ) {
-			const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
-			const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
-			if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
-				PRINT( std::cerr << "converting between references" << std::endl; )
-				Type::Qualifiers tq1 = srcAsRef->base->tq;
-				Type::Qualifiers tq2 = destAsRef->base->tq;
-				if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
-					PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
-					if ( tq1 == tq2 ) {
-						// types are the same
-						return Cost::zero;
-					} else {
-						// types are the same, except otherPointer has more qualifiers
-						return Cost::safe;
-					}
-				} else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
-					int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
-					PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
-					if ( assignResult > 0 ) {
-						return Cost::safe;
-					} else if ( assignResult < 0 ) {
-						return Cost::unsafe;
-					} // if
-				} // if
-			} else {
-				PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
-				PassVisitor<ConversionCost> converter(
-					dest, srcIsLvalue, indexer, env,
-					(Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
-						conversionCost );
-				src->accept( converter );
-				return converter.pass.get_cost();
-			} // if
-		} else {
-			const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
-			assert( diff == -1 && destAsRef );
-			PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
-			if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
-				PRINT( std::cerr << "converting compatible base type" << std::endl; )
-				if ( srcIsLvalue ) {
-					PRINT(
-						std::cerr << "lvalue to reference conversion" << std::endl;
-						std::cerr << src << " => " << destAsRef << std::endl;
-					)
-					// lvalue-to-reference conversion:  cv lvalue T => cv T &
-					if ( src->tq == destAsRef->base->tq ) {
-						return Cost::reference; // cost needs to be non-zero to add cast
-					} if ( src->tq < destAsRef->base->tq ) {
-						return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
-					} else {
-						return Cost::unsafe;
-					} // if
-				} else if ( destAsRef->base->get_const() ) {
-					PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
-					// rvalue-to-const-reference conversion: T => const T &
-					return Cost::safe;
-				} else {
-					PRINT( std::cerr << "rvalue to non-const reference conversion" << std::endl; )
-					// rvalue-to-reference conversion: T => T &
-					return Cost::unsafe;
-				} // if
-			} // if
-			PRINT( std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; )
-		}
-		return Cost::infinity;
-	}
-
-	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
-			const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
-		int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
-		Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
-		PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
-		return cost;
-	}
-
-	ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
-		: dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
-	}
 
 	// GENERATED START, DO NOT EDIT
@@ -319,186 +152,4 @@
 	);
 
-	void ConversionCost::postvisit( const VoidType * ) {
-		cost = Cost::infinity;
-	}
-
-	// refactor for code resue
-	void ConversionCost::conversionCostFromBasicToBasic(const BasicType * src, const BasicType * dest) {
-		int tableResult = costMatrix[ src->kind ][ dest->kind ];
-		if ( tableResult == -1 ) {
-			cost = Cost::unsafe;
-		} else {
-			cost = Cost::zero;
-			cost.incSafe( tableResult );
-			cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
-		} // if
-	} // ConversionCost::conversionCostFromBasicToBasic
-
-	void ConversionCost::postvisit(const BasicType * basicType) {
-		if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
-			conversionCostFromBasicToBasic(basicType, destAsBasic);
-		} else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * >( dest ) ) {
-			const EnumDecl * base_enum = enumInst->baseEnum;
-			if ( const Type * base = base_enum->base ) {
-				if ( const BasicType * enumBaseAstBasic = dynamic_cast< const BasicType *> (base) ) {
-					conversionCostFromBasicToBasic(basicType, enumBaseAstBasic);
-				} else {
-					cost = Cost::infinity;
-				} // if
-			} else {
-				cost = Cost::unsafe;
-			} // if
-		} // if
-		// no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
-	}
-
-	void ConversionCost::postvisit( const PointerType * pointerType ) {
-		if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
-			PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
-			Type::Qualifiers tq1 = pointerType->base->tq;
-			Type::Qualifiers tq2 = destAsPtr->base->tq;
-			if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
-				PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
-				if ( tq1 == tq2 ) {
-					// types are the same
-					cost = Cost::zero;
-				} else {
-					// types are the same, except otherPointer has more qualifiers
-					cost = Cost::safe;
-				} // if
-			} else {
-				int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
-				PRINT( std::cerr << " :: " << assignResult << std::endl; )
-				if ( assignResult > 0 && tq1 <= tq2 ) {
-					// xxx - want the case where qualifiers are added to be more expensive than the case where qualifiers are the same. Is 1 safe vs. 2 safe correct?
-					if ( tq1 == tq2 ) {
-						cost = Cost::safe;
-					} else if ( tq1 < tq2 ) {
-						cost = Cost::safe+Cost::safe;
-					}
-				} else if ( assignResult < 0 ) {
-					cost = Cost::unsafe;
-				} // if
-				// assignResult == 0 means Cost::Infinity
-			} // if
-			// case case for zero_t because it should not be possible to convert pointers to zero_t.
-		} // if
-	}
-
-	void ConversionCost::postvisit( const ArrayType * ) {}
-
-	void ConversionCost::postvisit( const ReferenceType * refType ) {
-		// Note: dest can never be a reference, since it would have been caught in an earlier check
-		assert( ! dynamic_cast< const ReferenceType * >( dest ) );
-		// convert reference to rvalue: cv T1 & => T2
-		// recursively compute conversion cost from T1 to T2.
-		// cv can be safely dropped because of 'implicit dereference' behavior.
-		cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
-		if ( refType->base->tq == dest->tq ) {
-			cost.incReference();  // prefer exact qualifiers
-		} else if ( refType->base->tq < dest->tq ) {
-			cost.incSafe(); // then gaining qualifiers
-		} else {
-			cost.incUnsafe(); // lose qualifiers as last resort
-		}
-		PRINT( std::cerr << refType << " ==> " << dest << " " << cost << std::endl; )
-	}
-
-	void ConversionCost::postvisit( const FunctionType * ) {}
-
-	void ConversionCost::postvisit( const EnumInstType * enumInst) {
-		const EnumDecl * enumDecl = enumInst -> baseEnum;
-		if ( const Type * enumType = enumDecl -> base ) { // if it is a typed enum
-			cost = costFunc( enumType, dest, srcIsLvalue, indexer, env );
-		} else {
-			static Type::Qualifiers q;
-			static BasicType integer( q, BasicType::SignedInt );
-			cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
-		} // if
-		if ( cost < Cost::unsafe ) {
-				cost.incSafe();
-		} // if
-	}
-
-	void ConversionCost::postvisit( const TraitInstType * ) {}
-
-	void ConversionCost::postvisit( const TypeInstType * inst ) {
-		if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
-			cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env );
-		} else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
-			if ( inst->name == destAsInst->name ) {
-				cost = Cost::zero;
-			}
-		} else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
-			const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
-			// all typedefs should be gone by this point
-			assert( type );
-			if ( type->base ) {
-				cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
-			} // if
-		} // if
-	}
-
-	void ConversionCost::postvisit( const TupleType * tupleType ) {
-		Cost c = Cost::zero;
-		if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
-			std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
-			std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
-			while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
-				Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
-				if ( newCost == Cost::infinity ) {
-					return;
-				} // if
-				c += newCost;
-			} // while
-			if ( destIt != destAsTuple->types.end() ) {
-				cost = Cost::infinity;
-			} else {
-				cost = c;
-			} // if
-		} // if
-	}
-
-	void ConversionCost::postvisit( const VarArgsType * ) {
-		if ( dynamic_cast< const VarArgsType * >( dest ) ) {
-			cost = Cost::zero;
-		}
-	}
-
-	void ConversionCost::postvisit( const ZeroType * ) {
-		if ( dynamic_cast< const ZeroType * >( dest ) ) {
-			cost = Cost::zero;
-		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
-			// copied from visit(BasicType *) for signed int, but +1 for safe conversions
-			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
-			if ( tableResult == -1 ) {
-				cost = Cost::unsafe;
-			} else {
-				cost = Cost::zero;
-				cost.incSafe( tableResult + 1 );
-				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
-			} // if
-		} else if ( dynamic_cast< const PointerType * >( dest ) ) {
-			cost = Cost::zero;
-			cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
-		} // if
-	}
-
-	void ConversionCost::postvisit( const OneType * ) {
-		if ( dynamic_cast< const OneType * >( dest ) ) {
-			cost = Cost::zero;
-		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
-			// copied from visit(BasicType *) for signed int, but +1 for safe conversions
-			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
-			if ( tableResult == -1 ) {
-				cost = Cost::unsafe;
-			} else {
-				cost = Cost::zero;
-				cost.incSafe( tableResult + 1 );
-				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
-			} // if
-		} // if
-	}
-
 namespace {
 	# warning For overload resolution between the two versions.
