Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 6de43b6499d8447e9107e8c7e176bd09fe406847)
+++ src/ResolvExpr/CommonType.cc	(revision 000178a875fc503fd49fa68233685aeea90aff8f)
@@ -61,29 +61,20 @@
 	};
 
-	Type * handleReference( ReferenceType * refType, Type * other, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {
-		Type * result = nullptr, * common = nullptr;
+	Type * handleReference( Type * t1, Type * t2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {
+		Type * common = nullptr;
 		AssertionSet have, need;
 		OpenVarSet newOpen( openVars );
 		// need unify to bind type variables
-		if ( unify( refType->get_base(), other, env, have, need, newOpen, indexer, common ) ) {
-			// std::cerr << "unify success" << std::endl;
-			if ( widenSecond ) {
-				// std::cerr << "widen second" << std::endl;
-				if ( widenFirst || other->get_qualifiers() <= refType->get_qualifiers() ) {
-					result = new ReferenceType( refType->get_qualifiers(), common ); // refType->clone();
-					result->get_qualifiers() |= other->get_qualifiers();
-				}
-			} else if ( widenFirst ) {
-				// std::cerr << "widen first" << std::endl;
-				if ( widenSecond || refType->get_qualifiers() <= other->get_qualifiers() ) {
-					result = common;
-					result->get_qualifiers() |= refType->get_qualifiers();
-				}
-			}
-		} else {
-			// std::cerr << "exact unify failed: " << refType << " " << other << std::endl;
-		}
-		// std::cerr << "common type of reference [" << refType << "] and non-reference [" << other << "] is [" << result << "]" << std::endl;
-		return result;
+		if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) {
+			// 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;
+				common->get_qualifiers() |= t1->get_qualifiers();
+				common->get_qualifiers() |= t2->get_qualifiers();
+				return common;
+			}
+		}
+		// std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
+		return nullptr;
 	}
 
@@ -99,8 +90,17 @@
 
 			// special case where one type has a reference depth of 1 larger than the other
-			if ( diff > 0 ) {
-				return handleReference( strict_dynamic_cast<ReferenceType *>( type1 ), type2, widenFirst, widenSecond, indexer, env, openVars );
-			} else if ( diff < 0 ) {
-				return handleReference( strict_dynamic_cast<ReferenceType *>( type2 ), type1, widenSecond, widenFirst, indexer, env, openVars );
+			if ( diff > 0 || diff < 0 ) {
+				Type * result = nullptr;
+				if ( ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ) ) {
+					// formal is reference, so result should be reference
+					result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars );
+					if ( result ) result = new ReferenceType( ref1->get_qualifiers(), result );
+				} else {
+					// formal is value, so result should be value
+					ReferenceType * ref2 = strict_dynamic_cast< ReferenceType * > ( type2 );
+					result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars );
+				}
+				// std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
+				return result;
 			}
 			// otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
