Index: src/ResolvExpr/SatisfyAssertions.cpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.cpp	(revision 46da46b804c2acd6916c888202a57186f41df8a8)
+++ src/ResolvExpr/SatisfyAssertions.cpp	(revision 0c840fc175421beff77fdd02802dd0b5c1da973c)
@@ -143,5 +143,5 @@
 	};
 
-
+	enum AssertionResult {Fail, Skip, Success} ;
 
 	/// Binds a single assertion, updating satisfaction state
@@ -164,8 +164,8 @@
 
 	/// Satisfy a single assertion
-	bool satisfyAssertion( ast::AssertionList::value_type & assn, SatState & sat, bool skipUnbound = false) {
+	AssertionResult satisfyAssertion( ast::AssertionList::value_type & assn, SatState & sat, bool skipUnbound = false) {
 		// skip unused assertions
 		static unsigned int cnt = 0;
-		if ( ! assn.second.isUsed ) return true;
+		if ( ! assn.second.isUsed ) return AssertionResult::Success;
 
 		if (assn.first->var->name[1] == '|') std::cerr << ++cnt << std::endl;
@@ -186,5 +186,5 @@
 			if (thisArgType.as<ast::PointerType>()) otypeKey = Mangle::Encoding::pointer;
 			else if (!isUnboundType(thisArgType)) otypeKey = Mangle::mangle(thisArgType, Mangle::Type | Mangle::NoGenericParams);
-			else if (skipUnbound) return false;
+			else if (skipUnbound) return AssertionResult::Skip;
 
 			candidates = sat.symtab.specialLookupId(kind, otypeKey);
@@ -251,10 +251,10 @@
 		// break if no satisfying match
 		if ( matches.empty() ) matches = std::move(inexactMatches);
-		if ( matches.empty() ) return false;
+		if ( matches.empty() ) return AssertionResult::Fail;
 
 		// defer if too many satisfying matches
 		if ( matches.size() > 1 ) {
 			sat.deferred.emplace_back( assn.first, assn.second, std::move( matches ) );
-			return true;
+			return AssertionResult::Success;
 		}
 
@@ -267,5 +267,5 @@
 
 		bindAssertion( assn.first, assn.second, sat.cand, match, sat.inferred );
-		return true;
+		return AssertionResult::Success;
 	}
 
@@ -456,14 +456,6 @@
 				for ( auto & assn : sat.need ) {
 					// fail early if any assertion is not satisfiable
-					if ( ! satisfyAssertion( assn, sat, !next.empty() ) ) {
-						next.emplace_back(assn);
-						// goto nextSat;
-					}
-				}
-				// success
-				if (next.empty()) break;
-				// fail if nothing resolves
-				else if (next.size() == sat.need.size()) {
-					// if (allowConversion) {
+					auto result = satisfyAssertion( assn, sat, !next.empty() );
+					if ( result == AssertionResult::Fail ) {
 						Indenter tabs{ 3 };
 						std::ostringstream ss;
@@ -471,15 +463,17 @@
 						print( ss, *sat.cand, ++tabs );
 						ss << (tabs-1) << "Could not satisfy assertion:\n";
-						ast::print( ss, next[0].first, tabs );
+						ast::print( ss, assn.first, tabs );
 
 						errors.emplace_back( ss.str() );
 						goto nextSat;
-					// }
-
-					// else {
-					//	allowConversion = true;
-					//	continue;
-					// }
-				}
+					}
+					else if ( result == AssertionResult::Skip ) {
+						next.emplace_back(assn);
+						// goto nextSat;
+					}
+				}
+				// success
+				if (next.empty()) break;
+
 				sat.need = std::move(next);
 			}
