Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
+++ src/Tuples/TupleAssignment.cc	(revision 77971f6131006ff573ba5422c4d83b41b7c5e612)
@@ -179,5 +179,5 @@
 
 		// explode the lhs so that each field of the tuple-valued-expr is assigned.
-		explode( lhsAlt, back_inserter(lhs) );
+		explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs) );
 		// and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed
 		if ( isCast ) {
@@ -204,5 +204,5 @@
 	TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
 		// explode the rhs so that each field of the tuple-valued-expr is assigned.
-		explode( std::next(alts.begin(), 1), alts.end(), back_inserter(rhs) );
+		explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs) );
 	}
 
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
+++ src/Tuples/TupleExpansion.cc	(revision 77971f6131006ff573ba5422c4d83b41b7c5e612)
@@ -141,5 +141,4 @@
 
 	Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) {
-		static UniqueName tempNamer( "_unq_expr_" );
 		unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) );
 		if ( ! decls.count( unqExpr->get_id() ) ) {
@@ -160,10 +159,6 @@
 			// }
 
-			// xxx - attach a resolved ConstructorInit node?
-			// xxx - is it possible to make the objDecl's type const?
-			ObjectDecl * objDecl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), nullptr );
-			// must be done on two lines because genCtorInit accesses objDecl's fields
-			objDecl->set_init( InitTweak::genCtorInit( objDecl ) );
-
+			ObjectDecl * objDecl = unqExpr->get_object();
+			unqExpr->set_object( nullptr );
 			decls[unqExpr->get_id()] = objDecl;
 			addDeclaration( objDecl );
Index: src/Tuples/Tuples.h
===================================================================
--- src/Tuples/Tuples.h	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
+++ src/Tuples/Tuples.h	(revision 77971f6131006ff573ba5422c4d83b41b7c5e612)
@@ -20,4 +20,5 @@
 #include <vector>
 #include "ResolvExpr/AlternativeFinder.h"
+#include "ResolvExpr/Resolver.h"
 
 #include "SynTree/Expression.h"
@@ -48,9 +49,9 @@
 	/// helper function used by explode
 	template< typename OutputIterator >
-	void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, OutputIterator out ) {
+	void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out ) {
 		Type * res = expr->get_result();
 		if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
 			ResolvExpr::AltList alts;
-			explodeUnique( addrExpr->get_arg(), alt, back_inserter( alts ) );
+			explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ) );
 			for ( ResolvExpr::Alternative & alt : alts ) {
 				// distribute '&' over all components
@@ -62,5 +63,5 @@
 				// can open tuple expr and dump its exploded components
 				for ( Expression * expr : tupleExpr->get_exprs() ) {
-					explodeUnique( expr, alt, out );
+					explodeUnique( expr, alt, indexer, out );
 				}
 			} else {
@@ -68,10 +69,13 @@
 				Expression * arg = expr->clone();
 				if ( Tuples::maybeImpure( arg ) ) {
-					// expressions which may contain side effects require a single unique instance of the expression
+					// expressions which may contain side effects require a single unique instance of the expression.
+					// resolve the UniqueExpr (which should be relatively cheap, since the argument is already resolved)
+					// so that its accompanying object is properly constructed and destructed.
 					arg = new UniqueExpr( arg );
+					arg = ResolvExpr::resolveInVoidContext( arg, indexer );
 				}
 				for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
 					TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
-					explodeUnique( idx, alt, out );
+					explodeUnique( idx, alt, indexer, out );
 					delete idx;
 				}
@@ -86,19 +90,19 @@
 	/// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
 	template< typename OutputIterator >
-	void explode( const ResolvExpr::Alternative &alt, OutputIterator out ) {
-		explodeUnique( alt.expr, alt, out );
+	void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out ) {
+		explodeUnique( alt.expr, alt, indexer, out );
 	}
 
 	// explode list of alternatives
 	template< typename AltIterator, typename OutputIterator >
-	void explode( AltIterator altBegin, AltIterator altEnd, OutputIterator out ) {
+	void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out ) {
 		for ( ; altBegin != altEnd; ++altBegin ) {
-			explode( *altBegin, out );
+			explode( *altBegin, indexer, out );
 		}
 	}
 
 	template< typename OutputIterator >
-	void explode( const ResolvExpr::AltList & alts, OutputIterator out ) {
-		explode( alts.begin(), alts.end(), out );
+	void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out ) {
+		explode( alts.begin(), alts.end(), indexer, out );
 	}
 } // namespace Tuples
