Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision b6fd7517dcd49accffbb4e92357f4fec8890b879)
@@ -41,4 +41,5 @@
 #include "Common/utility.h"
 #include "InitTweak/InitTweak.h"
+#include "InitTweak/GenInit.h"
 #include "ResolveTypeof.h"
 
@@ -207,7 +208,8 @@
 	}
 
+	// std::unordered_map< Expression *, UniqueExpr * > ;
+
 	template< typename StructOrUnionType >
 	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
-
 		// by this point, member must be a name expr
 		NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
@@ -434,5 +436,5 @@
 		// flatten actuals so that each actual has an atomic (non-tuple) type
 		AltList exploded;
-		Tuples::explode( actuals, back_inserter( exploded ) );
+		Tuples::explode( actuals, indexer, back_inserter( exploded ) );
 
 		AltList::iterator actualExpr = exploded.begin();
@@ -1055,16 +1057,21 @@
 
 	void AlternativeFinder::visit( UniqueExpr *unqExpr ) {
+		// this won't work because the unqExprs wont share an expression anymore...
 		AlternativeFinder finder( indexer, env );
 		finder.findWithAdjustment( unqExpr->get_expr() );
 		for ( Alternative & alt : finder.alternatives ) {
-			// xxx - it's possible that this won't always do the right thing, i.e. two UniqueExprs
-			// with the same ID may resolve to different expressions. If this ever happens, it might be necessary
-			// to try to select an alternative here (i.e. error is there is not a unique min-cost expression).
-			// One other thought is to to resolve each ID once and map the IDs to resolved expressions,
-			// but this isn't as simple as it sounds since the alternative is not selected here, meaning it might
-			// require complicated tracking throughout the system.
-
-			// brand the new UniqueExprs with the same id so that they are recognized as the same expression by the expansion pass
-			alternatives.push_back( Alternative( new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ), env, Cost::zero ) );
+			// xxx - attach a resolved ConstructorInit node?
+			// xxx - is it possible to make the objDecl's type const?
+			static UniqueName tempNamer( "_unq_expr_" );
+			ObjectDecl * objDecl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, alt.expr->get_result()->clone(), nullptr );
+			// must be done on two lines because genCtorInit accesses objDecl's fields
+			objDecl->set_init( InitTweak::genCtorInit( objDecl ) );
+
+			UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
+			newUnqExpr->set_object( objDecl );
+
+			resolveObject( indexer, objDecl );
+
+			alternatives.push_back( Alternative( newUnqExpr, env, Cost::zero ) );
 		}
 	}
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/ResolvExpr/AlternativeFinder.h	(revision b6fd7517dcd49accffbb4e92357f4fec8890b879)
@@ -95,4 +95,6 @@
 	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
 
+	void resolveObject( const SymTab::Indexer & indexer, ObjectDecl * objectDecl );
+
 	template< typename InputIterator, typename OutputIterator >
 	void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/ResolvExpr/Resolver.cc	(revision b6fd7517dcd49accffbb4e92357f4fec8890b879)
@@ -35,5 +35,6 @@
 	class Resolver : public SymTab::Indexer {
 	  public:
-		Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
+		Resolver() : SymTab::Indexer( false ) {}
+		Resolver( const SymTab::Indexer & indexer ) : SymTab::Indexer( indexer ) {}
 
 		virtual void visit( FunctionDecl *functionDecl );
@@ -68,7 +69,7 @@
 	  void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
 	  void fallbackInit( ConstructorInit * ctorInit );
-		Type * functionReturn;
-		Type *initContext;
-		Type *switchType;
+		Type * functionReturn = nullptr;
+		Type *initContext = nullptr;
+		Type *switchType = nullptr;
 		bool inEnumDecl = false;
 	};
@@ -532,4 +533,9 @@
 	}
 
+	void resolveObject( const SymTab::Indexer & indexer, ObjectDecl * objectDecl ) {
+		Resolver resolver( indexer );
+		objectDecl->accept( resolver );
+	}
+
 	void Resolver::visit( ConstructorInit *ctorInit ) {
 		// xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
