Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 1d29d46e76ca8eeebab3a2ad22aea33afbb42f87)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 32bcef7b779622307d3d7995752cbbd55567540b)
@@ -211,5 +211,17 @@
 	}
 
-	// std::unordered_map< Expression *, UniqueExpr * > ;
+	void AlternativeFinder::addAnonConversions( const Alternative & alt ) {
+		// adds anonymous member interpretations whenever an aggregate value type is seen.
+		Expression * expr = alt.expr->clone();
+		std::unique_ptr< Expression > manager( expr ); // RAII for expr
+		alt.env.apply( expr->get_result() );
+		if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) {
+			NameExpr nameExpr( "" );
+			addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
+		} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) {
+			NameExpr nameExpr( "" );
+			addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
+		} // if
+	}
 
 	template< typename StructOrUnionType >
@@ -220,8 +232,10 @@
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
+
 		for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
 			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
 				alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
 				renameTypes( alternatives.back().expr );
+				addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
 			} else {
 				assert( false );
@@ -730,4 +744,5 @@
 		if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; }
 
+		// compute conversionsion costs
 		for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
 			Cost cvtCost = computeConversionCost( *withFunc, indexer );
@@ -751,4 +766,9 @@
 			} // if
 		} // for
+		// function may return struct or union value, in which case we need to add alternatives for implicit conversions to each of the anonymous members
+		for ( const Alternative & alt : alternatives ) {
+			addAnonConversions( alt );
+		}
+
 		candidates.clear();
 		candidates.splice( candidates.end(), alternatives );
@@ -885,11 +905,5 @@
 			)
 			renameTypes( alternatives.back().expr );
-			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
-				NameExpr nameExpr( "" );
-				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
-			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
-				NameExpr nameExpr( "" );
-				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
-			} // if
+			addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
 		} // for
 	}
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 1d29d46e76ca8eeebab3a2ad22aea33afbb42f87)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 32bcef7b779622307d3d7995752cbbd55567540b)
@@ -78,4 +78,6 @@
 		void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
 
+		/// Adds alternatives for anonymous members
+		void addAnonConversions( const Alternative & alt );
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
 		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
