Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision bd4f2e9b269f4ba6094575b830cab685e3a1d075)
+++ src/Tuples/Explode.h	(revision 62194cbf579b5084c2ebfafd9003eb7b9cb0fa7b)
@@ -16,10 +16,12 @@
 #pragma once
 
-#include <iterator>                  // for back_inserter, back_insert_iterator
+#include <iterator>                     // for back_inserter, back_insert_iterator
+#include <utility>                      // for forward
 
-#include "ResolvExpr/Alternative.h"  // for Alternative, AltList
-#include "SynTree/Expression.h"      // for Expression, UniqueExpr, AddressExpr
-#include "SynTree/Type.h"            // for TupleType, Type
-#include "Tuples.h"                  // for maybeImpure
+#include "ResolvExpr/Alternative.h"     // for Alternative, AltList
+#include "ResolvExpr/ExplodedActual.h"  // for ExplodedActual
+#include "SynTree/Expression.h"         // for Expression, UniqueExpr, AddressExpr
+#include "SynTree/Type.h"               // for TupleType, Type
+#include "Tuples.h"                     // for maybeImpure
 
 namespace SymTab {
@@ -39,16 +41,32 @@
 	}
 
+	/// Append alternative to an OutputIterator of Alternatives
+	template<typename OutputIterator>
+	void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 
+			const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
+		*out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };
+	}
+
+	/// Append alternative to an ExplodedActual
+	static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 
+			const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
+		ea.exprs.emplace_back( expr );
+		/// xxx -- merge environment, cost?
+	}
+
 	/// helper function used by explode
-	template< typename OutputIterator >
-	void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
+	template< typename Output >
+	void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, 
+			const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) {
 		if ( isTupleAssign ) {
 			// tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
 			if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
 				ResolvExpr::AltList alts;
-				explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
+				explodeUnique( 
+					castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
 				for ( ResolvExpr::Alternative & alt : alts ) {
 					// distribute reference cast over all components
-					alt.expr = distributeReference( alt.expr );
-					*out++ = alt;
+					append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 
+						alt.env, alt.cost, alt.cvtCost );
 				}
 				// in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
@@ -61,5 +79,5 @@
 				// can open tuple expr and dump its exploded components
 				for ( Expression * expr : tupleExpr->get_exprs() ) {
-					explodeUnique( expr, alt, indexer, out, isTupleAssign );
+					explodeUnique( expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
 				}
 			} else {
@@ -77,5 +95,5 @@
 				for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
 					TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
-					explodeUnique( idx, alt, indexer, out, isTupleAssign );
+					explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign );
 					delete idx;
 				}
@@ -84,25 +102,28 @@
 		} else {
 			// atomic (non-tuple) type - output a clone of the expression in a new alternative
-			*out++ = ResolvExpr::Alternative( expr->clone(), alt.env, alt.cost, alt.cvtCost );
+			append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost );
 		}
 	}
 
 	/// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
-	template< typename OutputIterator >
-	void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
-		explodeUnique( alt.expr, alt, indexer, out, isTupleAssign );
+	template< typename Output >
+	void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, 
+			Output&& out, bool isTupleAssign = false ) {
+		explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
 	}
 
 	// explode list of alternatives
-	template< typename AltIterator, typename OutputIterator >
-	void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
+	template< typename AltIterator, typename Output >
+	void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, 
+			Output&& out, bool isTupleAssign = false ) {
 		for ( ; altBegin != altEnd; ++altBegin ) {
-			explode( *altBegin, indexer, out, isTupleAssign );
+			explode( *altBegin, indexer, std::forward<Output>(out), isTupleAssign );
 		}
 	}
 
-	template< typename OutputIterator >
-	void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
-		explode( alts.begin(), alts.end(), indexer, out, isTupleAssign );
+	template< typename Output >
+	void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out, 
+			bool isTupleAssign = false ) {
+		explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
 	}
 } // namespace Tuples
