Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 453b586b335eda3abcfceef3d1f00b177fa613c4)
+++ src/GenPoly/Lvalue.cc	(revision fae90d5f4e6f14db5c582aeb2a6ec9c0dbc21e73)
@@ -279,5 +279,6 @@
 			// pointer casts in the right places.
 
-			// need to reorganize this so that depth difference is the determining factor in what code is run, rather than whether something is reference type or not.
+			// Note: reference depth difference is the determining factor in what code is run, rather than whether something is
+			// reference type or not, since conversion still needs to occur when both types are references that differ in depth.
 
 			Type * destType = castExpr->result;
@@ -303,5 +304,5 @@
 				PRINT( std::cerr << "made temp: " << temp << std::endl; )
 				stmtsToAddBefore.push_back( new DeclStmt( temp ) );
-				for ( int i = 0; i < depth1-1; i++ ) {
+				for ( int i = 0; i < depth1-1; i++ ) { // xxx - maybe this should be diff-1? check how this works with reference type for srcType
 					ObjectDecl * newTemp = ObjectDecl::newObject( tempNamer.newName(), new ReferenceType( Type::Qualifiers(), temp->type->clone() ), new SingleInit( new AddressExpr( new VariableExpr( temp ) ) ) );
 					PRINT( std::cerr << "made temp" << i << ": " << newTemp << std::endl; )
@@ -318,4 +319,5 @@
 			}
 
+			// handle conversion between different depths
 			PRINT (
 				if ( depth1 || depth2 ) {
@@ -369,154 +371,4 @@
 				return castExpr;
 			}
-
-			// // conversion to reference type
-			// if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->result ) ) {
-			// 	(void)refType;
-			// 	if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( castExpr->arg->result ) ) {
-			// 		// nothing to do if casting from reference to reference.
-			// 		(void)otherRef;
-			// 		PRINT( std::cerr << "convert reference to reference -- nop" << std::endl; )
-			// 		if ( isIntrinsicReference( castExpr->arg ) ) {
-			// 			Expression * callExpr = castExpr->arg;
-			// 			PRINT(
-			// 				std::cerr << "but arg is deref -- &" << std::endl;
-			// 				std::cerr << callExpr << std::endl;
-			// 			)
-			// 			callExpr = new AddressExpr( callExpr ); // this doesn't work properly for multiple casts
-			// 			delete callExpr->result;
-			// 			callExpr->set_result( refType->clone() );
-			// 			// move environment out to new top-level
-			// 			callExpr->env = castExpr->env;
-			// 			castExpr->arg = nullptr;
-			// 			castExpr->env = nullptr;
-			// 			delete castExpr;
-			// 			return callExpr;
-			// 		}
-			// 		int depth1 = refType->referenceDepth();
-			// 		int depth2 = otherRef->referenceDepth();
-			// 		int diff = depth1-depth2;
-			// 		if ( diff == 0 ) {
-			// 			// conversion between references of the same depth
-			// 			assertf( depth1 == depth2, "non-intrinsic reference with cast of reference to reference not yet supported: %d %d %s", depth1, depth2, toString( castExpr ).c_str() );
-			// 			PRINT( std::cerr << castExpr << std::endl; )
-			// 			return castExpr;
-			// 		} else if ( diff < 0 ) {
-			// 			// conversion from reference to reference with less depth (e.g. int && -> int &): add dereferences
-			// 			Expression * ret = castExpr->arg;
-			// 			for ( int i = 0; i < diff; ++i ) {
-			// 				ret = mkDeref( ret );
-			// 			}
-			// 			ret->env = castExpr->env;
-			// 			delete ret->result;
-			// 			ret->result = castExpr->result;
-			// 			ret->result->set_lvalue( true ); // ensure result is lvalue
-			// 			castExpr->env = nullptr;
-			// 			castExpr->arg = nullptr;
-			// 			castExpr->result = nullptr;
-			// 			delete castExpr;
-			// 			return ret;
-			// 		} else if ( diff > 0 ) {
-			// 			// conversion from reference to reference with more depth (e.g. int & -> int &&): add address-of
-			// 			Expression * ret = castExpr->arg;
-			// 			for ( int i = 0; i < diff; ++i ) {
-			// 				ret = new AddressExpr( ret );
-			// 			}
-			// 			ret->env = castExpr->env;
-			// 			delete ret->result;
-			// 			ret->result = castExpr->result;
-			// 			castExpr->env = nullptr;
-			// 			castExpr->arg = nullptr;
-			// 			castExpr->result = nullptr;
-			// 			delete castExpr;
-			// 			return ret;
-			// 		}
-
-			// 		assertf( depth1 == depth2, "non-intrinsic reference with cast of reference to reference not yet supported: %d %d %s", depth1, depth2, toString( castExpr ).c_str() );
-			// 		PRINT( std::cerr << castExpr << std::endl; )
-			// 		return castExpr;
-			// 	} else if ( castExpr->arg->result->get_lvalue() ) {
-			// 		// conversion from lvalue to reference
-			// 		// xxx - keep cast, but turn into pointer cast??
-			// 		// xxx - memory
-			// 		PRINT(
-			// 			std::cerr << "convert lvalue to reference -- &" << std::endl;
-			// 			std::cerr << castExpr->arg << std::endl;
-			// 		)
-			// 		AddressExpr * ret = new AddressExpr( castExpr->arg );
-			// 		if ( refType->base->get_qualifiers() != castExpr->arg->result->get_qualifiers() ) {
-			// 			// must keep cast if cast-to type is different from the actual type
-			// 			castExpr->arg = ret;
-			// 			return castExpr;
-			// 		}
-			// 		ret->env = castExpr->env;
-			// 		delete ret->result;
-			// 		ret->result = castExpr->result;
-			// 		castExpr->env = nullptr;
-			// 		castExpr->arg = nullptr;
-			// 		castExpr->result = nullptr;
-			// 		delete castExpr;
-			// 		return ret;
-			// 	} else {
-			// 		// rvalue to reference conversion -- introduce temporary
-			// 		// know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g.
-			// 		//   (int &&&)3;
-			// 		// becomes
-			// 		//   int __ref_tmp_0 = 3;
-			// 		//   int & __ref_tmp_1 = _&_ref_tmp_0;
-			// 		//   int && __ref_tmp_2 = &__ref_tmp_1;
-			// 		//   &__ref_tmp_2;
-
-			// 		static UniqueName tempNamer( "__ref_tmp_" );
-			// 		ObjectDecl * temp = ObjectDecl::newObject( tempNamer.newName(), castExpr->arg->result->clone(), new SingleInit( castExpr->arg ) );
-			// 		stmtsToAddBefore.push_back( new DeclStmt( temp ) );
-			// 		auto depth = castExpr->result->referenceDepth();
-			// 		for ( int i = 0; i < depth-1; i++ ) {
-			// 			ObjectDecl * newTemp = ObjectDecl::newObject( tempNamer.newName(), new ReferenceType( Type::Qualifiers(), temp->type->clone() ), new SingleInit( new AddressExpr( new VariableExpr( temp ) ) ) );
-			// 			stmtsToAddBefore.push_back( new DeclStmt( newTemp ) );
-			// 			temp = newTemp;
-			// 		}
-			// 		Expression * ret = new AddressExpr( new VariableExpr( temp ) );
-			// 		// for ( int i = 0; i < depth; ++i ) {
-			// 		// 	ret = mkDeref( ret );
-			// 		// }
-			// 		ret->result = castExpr->result;
-			// 		ret->result->set_lvalue( true ); // ensure result is lvalue
-			// 		ret->env = castExpr->env;
-			// 		castExpr->arg = nullptr;
-			// 		castExpr->env = nullptr;
-			// 		castExpr->result = nullptr;
-			// 		delete castExpr;
-			// 		return ret;
-			// 	}
-			// } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->arg->result ) ) {
-			// 	(void)refType;
-			// 	// conversion from reference to rvalue
-			// 	PRINT(
-			// 		std::cerr << "convert reference to rvalue -- *" << std::endl;
-			// 		std::cerr << "was = " << castExpr << std::endl;
-			// 	)
-			// 	Expression * ret = castExpr->arg;
-			// 	TypeSubstitution * env = castExpr->env;
-			// 	castExpr->set_env( nullptr );
-			// 	if ( ! isIntrinsicReference( ret ) ) {
-			// 		// dereference if not already dereferenced
-			// 		ret = mkDeref( ret );
-			// 	}
-			// 	if ( ResolvExpr::typesCompatibleIgnoreQualifiers( castExpr->result, castExpr->arg->result->stripReferences(), SymTab::Indexer() ) ) {
-			// 		// can remove cast if types are compatible, changing expression type to value type
-			// 		ret->result = castExpr->result->clone();
-			// 		ret->result->set_lvalue( true );  // ensure result is lvalue
-			// 		castExpr->arg = nullptr;
-			// 		delete castExpr;
-			// 	} else {
-			// 		// must keep cast if types are different
-			// 		castExpr->arg = ret;
-			// 		ret = castExpr;
-			// 	}
-			// 	ret->set_env( env );
-			// 	PRINT( std::cerr << "now: " << ret << std::endl; )
-			// 	return ret;
-			// }
-			// return castExpr;
 		}
 
