Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 0f19f5e5507e9dee674ac823dabb5c0e9702f2c5)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 7d01cf444a023daf487ab6160ac3de9182d41088)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:52:08 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jul 25 22:37:46 2019
-// Update Count     : 37
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:35:00 2019
+// Update Count     : 38
 //
 
@@ -377,5 +377,6 @@
 	}
 
-	Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
+	Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
 		PRINT(
 			std::cerr << std::endl << "converting ";
@@ -387,5 +388,5 @@
 			std::cerr << std::endl;
 		)
-		Cost convCost = conversionCost( actualType, formalType, indexer, env );
+		Cost convCost = conversionCost( actualType, formalType, actualIsLvalue, indexer, env );
 		PRINT(
 			std::cerr << std::endl << "cost is " << convCost << std::endl;
@@ -402,5 +403,6 @@
 
 	Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
-		Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
+		Cost convCost = computeConversionCost(
+			actualExpr->result, formalType, actualExpr->get_lvalue(), indexer, env );
 
 		// if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
@@ -1212,6 +1214,6 @@
 			unify( castExpr->result, alt.expr->result, alt.env, needAssertions,
 				haveAssertions, openVars, indexer );
-			Cost thisCost = castCost( alt.expr->result, castExpr->result, indexer,
-				alt.env );
+			Cost thisCost = castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(),
+				indexer, alt.env );
 			PRINT(
 				std::cerr << "working on cast with result: " << castExpr->result << std::endl;
@@ -1640,5 +1642,6 @@
 				// xxx - do some inspecting on this line... why isn't result bound to initAlt.type?
 
-				Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv );
+				Cost thisCost = castCost( alt.expr->result, toType, alt.expr->get_lvalue(),
+					indexer, newEnv );
 				if ( thisCost != Cost::infinity ) {
 					// count one safe conversion for each value that is thrown away
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 0f19f5e5507e9dee674ac823dabb5c0e9702f2c5)
+++ src/ResolvExpr/CastCost.cc	(revision 7d01cf444a023daf487ab6160ac3de9182d41088)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 06:57:43 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb  2 15:34:36 2016
-// Update Count     : 7
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:12:00 2019
+// Update Count     : 8
 //
 
@@ -37,5 +37,6 @@
 	struct CastCost_old : public ConversionCost {
 	  public:
-		CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
+		CastCost_old( const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
 
 		using ConversionCost::previsit;
@@ -45,9 +46,10 @@
 	};
 
-	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
-					return castCost( src, eqvClass->type, indexer, env );
+					return castCost( src, eqvClass->type, srcIsLvalue, indexer, env );
 				} else {
 					return Cost::infinity;
@@ -57,5 +59,5 @@
 				const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
 				if ( type->base ) {
-					return castCost( src, type->base, indexer, env ) + Cost::safe;
+					return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe;
 				} // if
 			} // if
@@ -78,11 +80,11 @@
 		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
+			return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
 				return ptrsCastable( t1, t2, env, indexer );
 			});
 		} else {
 			PassVisitor<CastCost_old> converter(
-				dest, indexer, env,
-				(Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
+				dest, srcIsLvalue, indexer, env,
+				(Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & ))
 					castCost );
 			src->accept( converter );
@@ -96,6 +98,7 @@
 	}
 
-	CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
-		: ConversionCost( dest, indexer, env, costFunc ) {
+	CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+		: ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) {
 	}
 
@@ -106,5 +109,5 @@
 			cost = Cost::unsafe;
 		} else {
-			cost = conversionCost( basicType, dest, indexer, env );
+			cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env );
 		} // if
 	}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 0f19f5e5507e9dee674ac823dabb5c0e9702f2c5)
+++ src/ResolvExpr/ConversionCost.cc	(revision 7d01cf444a023daf487ab6160ac3de9182d41088)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 07:06:19 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Jun 24 13:33:00 2019
-// Update Count     : 26
+// Last Modified On : Mon Aug 12 10:21:00 2019
+// Update Count     : 27
 //
 
@@ -46,10 +46,11 @@
 #endif
 
-	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
 			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
-					return conversionCost( src, eqvClass->type, indexer, env );
+					return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
 				} else {
 					return Cost::infinity;
@@ -61,5 +62,6 @@
 				assert( type );
 				if ( type->base ) {
-					return conversionCost( src, type->base, indexer, env ) + Cost::safe;
+					return conversionCost( src, type->base, srcIsLvalue, indexer, env )
+						+ Cost::safe;
 				} // if
 			} // if
@@ -81,11 +83,11 @@
 		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
+			return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
 				return ptrsAssignable( t1, t2, env );
 			});
 		} else {
 			PassVisitor<ConversionCost> converter(
-				dest, indexer, env,
-				(Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
+				dest, srcIsLvalue, indexer, env,
+				(Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
 					conversionCost );
 			src->accept( converter );
@@ -98,14 +100,19 @@
 	}
 
-	static Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
+			int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
 		if ( diff > 0 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
+			Cost cost = convertToReferenceCost(
+				strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
+				diff-1, indexer, env, func );
 			cost.incReference();
 			return cost;
 		} else if ( diff < -1 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
+			Cost cost = convertToReferenceCost(
+				src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
+				diff+1, indexer, env, func );
 			cost.incReference();
 			return cost;
@@ -138,6 +145,6 @@
 				PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
 				PassVisitor<ConversionCost> converter(
-					dest, indexer, env,
-					(Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
+					dest, srcIsLvalue, indexer, env,
+					(Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
 						conversionCost );
 				src->accept( converter );
@@ -150,5 +157,6 @@
 			if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
 				PRINT( std::cerr << "converting compatible base type" << std::endl; )
-				if ( src->get_lvalue() ) {
+				assert( src->get_lvalue() == srcIsLvalue );
+				if ( srcIsLvalue ) {
 					PRINT(
 						std::cerr << "lvalue to reference conversion" << std::endl;
@@ -178,13 +186,14 @@
 	}
 
-	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
+			const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
-		Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
+		Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
 		PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
 		return cost;
 	}
 
-	ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
-		: dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
+	ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+		: dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
 	}
 
@@ -371,5 +380,5 @@
 		// recursively compute conversion cost from T1 to T2.
 		// cv can be safely dropped because of 'implicit dereference' behavior.
-		cost = costFunc( refType->base, dest, indexer, env );
+		cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
 		if ( refType->base->tq == dest->tq ) {
 			cost.incReference();  // prefer exact qualifiers
@@ -403,5 +412,5 @@
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
-		cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
+		cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
 		if ( cost < Cost::unsafe ) {
 			cost.incSafe();
@@ -413,5 +422,5 @@
 	void ConversionCost::postvisit( const TypeInstType * inst ) {
 		if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
-			cost = costFunc( eqvClass->type, dest, indexer, env );
+			cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env );
 		} else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
@@ -423,5 +432,5 @@
 			assert( type );
 			if ( type->base ) {
-				cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
+				cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
 			} // if
 		} // if
@@ -434,5 +443,5 @@
 			std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
 			while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
-				Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env );
+				Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
 				if ( newCost == Cost::infinity ) {
 					return;
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision 0f19f5e5507e9dee674ac823dabb5c0e9702f2c5)
+++ src/ResolvExpr/ConversionCost.h	(revision 7d01cf444a023daf487ab6160ac3de9182d41088)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 09:37:28 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Jun 24 10:00:00 2019
-// Update Count     : 5
+// Last Modified On : Thu Aug  8 16:13:00 2019
+// Update Count     : 6
 //
 
@@ -33,8 +33,11 @@
 	class TypeEnvironment;
 
-	typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
+	typedef std::function<Cost(const Type *, const Type *, bool,
+		const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
+
 	struct ConversionCost : public WithShortCircuiting {
 	  public:
-		ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
+		ConversionCost( const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
 
 		Cost get_cost() const { return cost; }
@@ -59,4 +62,5 @@
 	  protected:
 		const Type * dest;
+		bool srcIsLvalue;
 		const SymTab::Indexer &indexer;
 		Cost cost;
@@ -66,5 +70,6 @@
 
 	typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
-	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
 
 // Some function pointer types, differ in return type.
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision 0f19f5e5507e9dee674ac823dabb5c0e9702f2c5)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 7d01cf444a023daf487ab6160ac3de9182d41088)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Fri Oct 05 13:46:00 2018
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 10 16:10:37 2019
-// Update Count     : 2
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:47:00 2019
+// Update Count     : 3
 //
 
@@ -156,6 +156,7 @@
 			for ( const auto& assn : x.assns ) {
 				// compute conversion cost from satisfying decl to assertion
+				assert( !assn.match.adjType->get_lvalue() );
 				k += computeConversionCost(
-					assn.match.adjType, assn.decl->get_type(), indexer, x.env );
+					assn.match.adjType, assn.decl->get_type(), false, indexer, x.env );
 
 				// mark vars+specialization cost on function-type assertions
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision 0f19f5e5507e9dee674ac823dabb5c0e9702f2c5)
+++ src/ResolvExpr/typeops.h	(revision 7d01cf444a023daf487ab6160ac3de9182d41088)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 07:28:22 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Feb  8 09:30:34 2019
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:36:00 2019
+// Update Count     : 5
 //
 
@@ -80,5 +80,6 @@
 
 	// in CastCost.cc
-	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 	Cost castCost(
 		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
@@ -86,5 +87,6 @@
 
 	// in ConversionCost.cc
-	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 	Cost conversionCost(
 		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
@@ -92,5 +94,5 @@
 
 	// in AlternativeFinder.cc
-	Cost computeConversionCost( Type * actualType, Type * formalType,
+	Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
 		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 
