Index: src/GenPoly/Lvalue.cpp
===================================================================
--- src/GenPoly/Lvalue.cpp	(revision ed96731e0151e86950bd43918f4c4873b82f0102)
+++ src/GenPoly/Lvalue.cpp	(revision d945be90bbec358aebe471da2789f819771bcd52)
@@ -315,5 +315,4 @@
 		SemanticWarning( expr->arg->location,
 			Warning::RvalueToReferenceConversion, toCString( expr->arg ) );
-
 
 		// allowing conversion in the rvalue to const ref case
@@ -366,8 +365,7 @@
 			ret = new ast::AddressExpr( ret->location, ret );
 		}
-		if ( expr->arg->get_lvalue() &&
-				!ResolvExpr::typesCompatible(
-					srcType,
-					strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
+		if ( !ResolvExpr::typesCompatible(
+				srcType,
+				strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
 			// Must keep cast if cast-to type is different from the actual type.
 			return ast::mutate_field( expr, &ast::CastExpr::arg, ret );
@@ -384,5 +382,5 @@
 		}
 		// Must keep cast if types are different.
-		if ( !ResolvExpr::typesCompatibleIgnoreQualifiers(
+		if ( !ResolvExpr::typesCompatible(
 				dstType->stripReferences(),
 				srcType->stripReferences() ) ) {
@@ -397,25 +395,18 @@
 	} else {
 		assert( 0 == diff );
-		// Remove useless generated casts.
-		if ( expr->isGenerated == ast::GeneratedFlag::GeneratedCast &&
-				ResolvExpr::typesCompatible(
+		// Must keep cast if types are different. (Or it is explicit.)
+		if ( ast::ExplicitCast == expr->isGenerated ||
+				!ResolvExpr::typesCompatible(
 					expr->result,
 					expr->arg->result ) ) {
-			PRINT(
-				std::cerr << "types are compatible, removing cast: " << expr << '\n';
-				std::cerr << "-- " << expr->result << '\n';
-				std::cerr << "-- " << expr->arg->result << std::endl;
-			)
-			auto argAsEnum = expr->arg.as<ast::EnumInstType>();
-			auto resultAsEnum = expr->result.as<ast::EnumInstType>();
-			if (argAsEnum && resultAsEnum) {
-				if (argAsEnum->base->name != resultAsEnum->base->name) {
-					return expr;
-				}
-			}
-			return ast::mutate_field( expr->arg.get(),
-					&ast::Expr::env, expr->env.get() );
-		}
-		return expr;
+			return expr;
+		}
+		PRINT(
+			std::cerr << "types are compatible, removing cast: " << expr << '\n';
+			std::cerr << "-- " << expr->result << '\n';
+			std::cerr << "-- " << expr->arg->result << std::endl;
+		)
+		return ast::mutate_field( expr->arg.get(),
+				&ast::Expr::env, expr->env.get() );
 	}
 }
