Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision 753bf60ca62fc9174f95acb81a59eeac48c7c86e)
+++ src/Tuples/Explode.h	(revision da4818339a1056832238bbf1af3a1252de5a2ed3)
@@ -44,13 +44,15 @@
 	template<typename OutputIterator>
 	void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
+			const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 
 			const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
-		*out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };
+		*out++ = ResolvExpr::Alternative{ expr, env, openVars, need, 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& ) {
+			const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 
+			const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
 		ea.exprs.emplace_back( expr );
-		/// xxx -- merge environment, cost?
+		/// xxx -- merge environment, openVars, need, cost?
 	}
 
@@ -68,5 +70,5 @@
 					// distribute reference cast over all components
 					append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
-						alt.env, alt.cost, alt.cvtCost );
+						alt.env, alt.openVars, alt.need, 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)
@@ -102,5 +104,6 @@
 		} else {
 			// atomic (non-tuple) type - output a clone of the expression in a new alternative
-			append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost );
+			append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,  
+				alt.cost, alt.cvtCost );
 		}
 	}
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 753bf60ca62fc9174f95acb81a59eeac48c7c86e)
+++ src/Tuples/TupleAssignment.cc	(revision da4818339a1056832238bbf1af3a1252de5a2ed3)
@@ -62,9 +62,21 @@
 		struct Matcher {
 		  public:
-			Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const
-				ResolvExpr::AltList& rhs );
+			Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 
+				const ResolvExpr::AltList& rhs );
 			virtual ~Matcher() {}
+			
 			virtual void match( std::list< Expression * > &out ) = 0;
 			ObjectDecl * newObject( UniqueName & namer, Expression * expr );
+
+			void combineState( const ResolvExpr::Alternative& alt ) {
+				compositeEnv.simpleCombine( alt.env );
+				ResolvExpr::mergeOpenVars( openVars, alt.openVars );
+				need.insert( alt.need.begin(), alt.need.end() );
+			}
+
+			void combineState( const ResolvExpr::AltList& alts ) {
+				for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); }
+			}
+			
 			ResolvExpr::AltList lhs, rhs;
 			TupleAssignSpotter &spotter;
@@ -72,4 +84,6 @@
 			std::list< ObjectDecl * > tmpDecls;
 			ResolvExpr::TypeEnvironment compositeEnv;
+			ResolvExpr::OpenVarSet openVars;
+			ResolvExpr::AssertionSet need;
 		};
 
@@ -245,16 +259,18 @@
 		}
 
-		// extract expressions from the assignment alternatives to produce a list of assignments that
-		// together form a single alternative
+		// extract expressions from the assignment alternatives to produce a list of assignments 
+		// that together form a single alternative
 		std::list< Expression *> solved_assigns;
 		for ( ResolvExpr::Alternative & alt : current ) {
 			solved_assigns.push_back( alt.expr->clone() );
-		}
-		// combine assignment environments into combined expression environment
-		simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv );
+			matcher->combineState( alt );
+		}
+		
 		// xxx -- was push_front
-		currentFinder.get_alternatives().push_back( ResolvExpr::Alternative(
-			new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv,
-			ResolvExpr::sumCost( current ) + matcher->baseCost ) );
+		currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{
+			new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 
+			matcher->openVars, 
+			ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 
+			ResolvExpr::sumCost( current ) + matcher->baseCost } );
 	}
 
@@ -263,6 +279,6 @@
 	: lhs(lhs), rhs(rhs), spotter(spotter),
 	  baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
-		simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv );
-		simpleCombineEnvironments( rhs.begin(), rhs.end(), compositeEnv );
+		combineState( lhs ); 
+		combineState( rhs );
 	}
 
