Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 661e7b01f8a9a2c15670b1615d96ea489f11fbe8)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 2870cb69f7deb12ee9dee9619f2038492fbd5628)
@@ -1281,4 +1281,11 @@
 				// count one safe conversion for each value that is thrown away
 				thisCost.incSafe( discardedValues );
+
+				// See Aaron Moss, page 47; this reasoning does not hold since implicit conversions
+				// can create the same resolution issue. The C intrinsic interpretations are pruned
+				// immediately for the lowest cost option regardless of result type. Related code in
+				// postvisit (UntypedExpr).
+				// Cast expression costs are updated now to use the general rules.
+				/*
 				// select first on argument cost, then conversion cost
 				if ( cand->cost < minExprCost || ( cand->cost == minExprCost && thisCost < minCastCost ) ) {
@@ -1289,7 +1296,14 @@
 				// ambigious case, still output candidates to print in error message
 				if ( cand->cost == minExprCost && thisCost == minCastCost ) {
+				*/
+				cand->cost += thisCost;
+				if (cand->cost < minExprCost) {
+					minExprCost = cand->cost;
+					matches.clear();
+				}
+				if (cand->cost == minExprCost) {
 					CandidateRef newCand = std::make_shared<Candidate>(
 						restructureCast( cand->expr, toType, castExpr->isGenerated ),
-						copy( cand->env ), std::move( open ), std::move( need ), cand->cost + thisCost);
+						copy( cand->env ), std::move( open ), std::move( need ), cand->cost);
 					// currently assertions are always resolved immediately so this should have no effect.
 					// if this somehow changes in the future (e.g. delayed by indeterminate return type)
