Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 8135d4c79504a6c3047246007261186efa5ba4c9)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 377e33ff2917fc6ab3c81961f9ad20de243c895e)
@@ -286,5 +286,54 @@
 	}
 
-	Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
+	Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
+		PRINT(
+			std::cerr << std::endl << "converting ";
+			actualType->print( std::cerr, 8 );
+			std::cerr << std::endl << " to ";
+			formalType->print( std::cerr, 8 );
+			std::cerr << std::endl << "environment is: ";
+			env.print( std::cerr, 8 );
+			std::cerr << std::endl;
+		)
+		Cost convCost = conversionCost( actualType, formalType, indexer, env );
+		PRINT(
+			std::cerr << std::endl << "cost is" << convCost << std::endl;
+		)
+		if ( convCost == Cost::infinity ) {
+			return convCost;
+		}
+		convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
+		return convCost;
+	}
+
+	Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
+		Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
+		// if ( convCost != Cost::zero ) {
+
+		// xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
+		// pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
+		// previous line.
+		Cost tmpCost = convCost;
+		tmpCost.incPoly( -tmpCost.get_polyCost() );
+		if ( tmpCost != Cost::zero ) {
+			Type *newType = formalType->clone();
+			env.apply( newType );
+			actualExpr = new CastExpr( actualExpr, newType );
+			// xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly
+			// inconsistent, once this is fixed it should be possible to resolve the cast.
+			// xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing.
+
+			// AlternativeFinder finder( indexer, env );
+			// finder.findWithAdjustment( actualExpr );
+			// assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." );
+			// assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." );
+			// Alternative & alt = finder.get_alternatives().front();
+			// delete actualExpr;
+			// actualExpr = alt.expr->clone();
+		}
+		return convCost;
+	}
+
+	Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
 		ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
 		PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
@@ -304,5 +353,4 @@
 				actualType->print( std::cerr, 8 );
 			)
-			Cost actualCost = Cost::zero;
 			if ( formal == formals.end() ) {
 				if ( function->get_isVarArgs() ) {
@@ -325,20 +373,5 @@
 				std::cerr << std::endl;
 			)
-			Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
-			PRINT(
-				std::cerr << std::endl << "cost is" << newCost << std::endl;
-			)
-
-			if ( newCost == Cost::infinity ) {
-				return newCost;
-			}
-			convCost += newCost;
-			actualCost += newCost;
-			if ( actualCost != Cost::zero ) {
-				Type *newType = formalType->clone();
-				alt.env.apply( newType );
-				*actualExpr = new CastExpr( *actualExpr, newType );
-			}
-			convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) );
+			convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
 			++formal; // can't be in for-loop update because of the continue
 		}
@@ -348,19 +381,5 @@
 
 		for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
-			PRINT(
-				std::cerr << std::endl << "converting ";
-				assert->second.actualType->print( std::cerr, 8 );
-				std::cerr << std::endl << " to ";
-				assert->second.formalType->print( std::cerr, 8 );
-			)
-			Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
-			PRINT(
-				std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
-			)
-			if ( newCost == Cost::infinity ) {
-				return newCost;
-			}
-			convCost += newCost;
-			convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) );
+			convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
 		}
 
@@ -776,5 +795,5 @@
 		// compute conversionsion costs
 		for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
-			Cost cvtCost = computeConversionCost( *withFunc, indexer );
+			Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );
 
 			PRINT(
@@ -895,6 +914,10 @@
 				// count one safe conversion for each value that is thrown away
 				thisCost.incSafe( discardedValues );
-
-				candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
+				Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
+				// xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
+				// Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
+
+				// inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
+				candidates.emplace_back( std::move( newAlt ) );
 			} // if
 		} // for
@@ -1139,4 +1162,7 @@
 						ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
 						newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
+						// convert both options to the conditional result type
+						newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
+						newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
 						newAlt.expr = newExpr;
 						inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
