Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -815,9 +815,10 @@
 
 	Expression * restructureCast( Expression * argExpr, Type * toType ) {
-		if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
-			// Argument expression is a tuple and the target type is not void. Cast each member of the tuple
-			// to its corresponding target type, producing the tuple of those cast expressions. If there are
-			// more components of the tuple than components in the target type, then excess components do not
-			// come out in the result expression (but UniqueExprs ensure that side effects will still be done).
+		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.
+			// Cast each member of the tuple to its corresponding target type, producing the tuple of those
+			// cast expressions. If there are more components of the tuple than components in the target type,
+			// then excess components do not come out in the result expression (but UniqueExprs ensure that
+			// side effects will still be done).
 			if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
 				// expressions which may contain side effects require a single unique instance of the expression.
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/ResolvExpr/CommonType.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -81,13 +81,18 @@
 		CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
 
-		ReferenceType * refType1 = dynamic_cast< ReferenceType * >( type1 );
-		ReferenceType * refType2 = dynamic_cast< ReferenceType * >( type2 );
-		if ( (refType1 || refType2) && (! refType1 || ! refType2) ) {
-			// handle the case where exactly one of the types is a reference type specially
-			if ( refType1 ) {
-				return handleReference( refType1, type2, widenFirst, widenSecond, indexer, env, openVars );
-			} else if ( refType2 ) {
-				return handleReference( refType2, type1, widenSecond, widenFirst, indexer, env, openVars );
-			}
+		int depth1 = type1->referenceDepth();
+		int depth2 = type2->referenceDepth();
+		if ( depth1 > 0 || depth2 > 0 ) {
+			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;
+
+			// special case where one type has a reference depth of 1 larger than the other
+			if ( diff > 0 ) {
+				return handleReference( safe_dynamic_cast<ReferenceType *>( type1 ), type2, widenFirst, widenSecond, indexer, env, openVars );
+			} else if ( diff < 0 ) {
+				return handleReference( safe_dynamic_cast<ReferenceType *>( type2 ), type1, widenSecond, widenFirst, indexer, env, openVars );
+			}
+			// otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
 		}
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/ResolvExpr/Unify.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -377,4 +377,6 @@
 				} // if
 			} else {
+				common = type1->clone();
+				common->get_qualifiers() = tq1 | tq2;
 				result = true;
 			} // if
