Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 1cdfa82ab4efb64ed6273f4e8e3993bc8895a419)
@@ -1238,5 +1238,5 @@
 	}
 
-	Expression * restructureCast( Expression * argExpr, Type * toType ) {
+	Expression * restructureCast( Expression * argExpr, Type * toType, bool isGenerated ) {
 		if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) {
 			// Argument expression is a tuple and the target type is not void and not a reference type.
@@ -1253,5 +1253,5 @@
 				// cast each component
 				TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
-				componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) );
+				componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) );
 			}
 			assert( componentExprs.size() > 0 );
@@ -1260,5 +1260,7 @@
 		} else {
 			// handle normally
-			return new CastExpr( argExpr, toType->clone() );
+			CastExpr * ret = new CastExpr( argExpr, toType->clone() );
+			ret->isGenerated = isGenerated;
+			return ret;
 		}
 	}
@@ -1304,5 +1306,5 @@
 				// count one safe conversion for each value that is thrown away
 				thisCost.incSafe( discardedValues );
-				Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env,
+				Alternative newAlt( restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), alt.env,
 					alt.cost, thisCost );
 				inferParameters( needAssertions, haveAssertions, newAlt, openVars,
@@ -1727,5 +1729,5 @@
 					// count one safe conversion for each value that is thrown away
 					thisCost.incSafe( discardedValues );
-					Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
+					Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
 					inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
 				}
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
+++ src/ResolvExpr/CommonType.cc	(revision 1cdfa82ab4efb64ed6273f4e8e3993bc8895a419)
@@ -28,4 +28,9 @@
 
 // #define DEBUG
+#ifdef DEBUG
+#define PRINT(x) x
+#else
+#define PRINT(x)
+#endif
 
 namespace ResolvExpr {
@@ -70,7 +75,11 @@
 		// need unify to bind type variables
 		if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) {
-			// std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
+			PRINT(
+				std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
+			)
 			if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
-				// std::cerr << "widen okay" << std::endl;
+				PRINT(
+					std::cerr << "widen okay" << std::endl;
+				)
 				common->get_qualifiers() |= t1->get_qualifiers();
 				common->get_qualifiers() |= t2->get_qualifiers();
@@ -78,5 +87,7 @@
 			}
 		}
-		// std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
+		PRINT(
+			std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
+		)
 		return nullptr;
 	}
@@ -90,9 +101,11 @@
 			int diff = depth1-depth2;
 			// TODO: should it be possible for commonType to generate complicated conversions? I would argue no, only conversions that involve types of the same reference level or a difference of 1 should be allowed.
-			if ( diff > 1 || diff < -1 ) return nullptr;
+			// if ( diff > 1 || diff < -1 ) return nullptr;
 
 			// special case where one type has a reference depth of 1 larger than the other
 			if ( diff > 0 || diff < 0 ) {
-				// std::cerr << "reference depth diff: " << diff << std::endl;
+				PRINT(
+					std::cerr << "reference depth diff: " << diff << std::endl;
+				)
 				Type * result = nullptr;
 				ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 );
@@ -109,8 +122,12 @@
 				if ( result && ref1 ) {
 					// formal is reference, so result should be reference
-					// std::cerr << "formal is reference; result should be reference" << std::endl;
+					PRINT(
+						std::cerr << "formal is reference; result should be reference" << std::endl;
+					)
 					result = new ReferenceType( ref1->get_qualifiers(), result );
 				}
-				// std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
+				PRINT(
+					std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
+				)
 				return result;
 			}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
+++ src/ResolvExpr/ConversionCost.cc	(revision 1cdfa82ab4efb64ed6273f4e8e3993bc8895a419)
@@ -276,7 +276,6 @@
 			// xxx - not positive this is correct, but appears to allow casting int => enum
 			cost = Cost::unsafe;
-		} else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
-			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.
 	}
 
@@ -310,6 +309,5 @@
 				// assignResult == 0 means Cost::Infinity
 			} // if
-		} else if ( dynamic_cast< ZeroType * >( dest ) ) {
-			cost = Cost::unsafe;
+			// case case for zero_t because it should not be possible to convert pointers to zero_t.
 		} // if
 	}
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
+++ src/ResolvExpr/Resolver.cc	(revision 1cdfa82ab4efb64ed6273f4e8e3993bc8895a419)
@@ -60,4 +60,5 @@
 		void previsit( TypeDecl *typeDecl );
 		void previsit( EnumDecl * enumDecl );
+		void previsit( StaticAssertDecl * assertDecl );
 
 		void previsit( ArrayType * at );
@@ -365,4 +366,8 @@
 	}
 
+	void Resolver::previsit( StaticAssertDecl * assertDecl ) {
+		findIntegralExpression( assertDecl->condition, indexer );
+	}
+
 	void Resolver::previsit( ExprStmt *exprStmt ) {
 		visit_children = false;
