Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/Tuples/TupleAssignment.cc	(revision 1d2b64f538b2e524e418c78785233364f63db708)
@@ -23,4 +23,5 @@
 #include "Common/SemanticError.h"
 #include "InitTweak/InitTweak.h"
+#include "InitTweak/GenInit.h"
 
 #include <functional>
@@ -47,7 +48,10 @@
 			virtual ~Matcher() {}
 			virtual void match( std::list< Expression * > &out ) = 0;
+			ObjectDecl * newObject( UniqueName & namer, Expression * expr );
 			ResolvExpr::AltList lhs, rhs;
 			TupleAssignSpotter &spotter;
+			ResolvExpr::Cost baseCost;
 			std::list< ObjectDecl * > tmpDecls;
+			ResolvExpr::TypeEnvironment compositeEnv;
 		};
 
@@ -146,5 +150,5 @@
 				finder.findWithAdjustment(*i);
 			} catch (...) {
-				return; // xxx - no match should not mean failure, it just means this particular tuple assignment isn't valid
+				return; // no match should not mean failure, it just means this particular tuple assignment isn't valid
 			}
 			// prune expressions that don't coincide with
@@ -161,12 +165,14 @@
 			solved_assigns.push_back( alt.expr->clone() );
 		}
-		// xxx - need to do this??
-		ResolvExpr::TypeEnvironment compositeEnv;
-		simpleCombineEnvironments( current.begin(), current.end(), compositeEnv );
-		currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), compositeEnv, ResolvExpr::sumCost( current ) ) );
-	}
-
-	TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter) {
+		// combine assignment environments into combined expression environment
+		simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv );
+		currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, ResolvExpr::sumCost( current  ) + matcher->baseCost ) );
+	}
+
+	TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter), baseCost( ResolvExpr::sumCost( alts ) ) {
 		assert( ! alts.empty() );
+		// combine argument environments into combined expression environment
+		simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
+
 		ResolvExpr::Alternative lhsAlt = alts.front();
 		// peel off the cast that exists on ctor/dtor expressions
@@ -217,7 +223,24 @@
 	}
 
-	ObjectDecl * newObject( UniqueName & namer, Expression * expr ) {
+	// removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator.
+	// xxx - maybe this should happen in alternative finder for every StmtExpr?
+	// xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv
+	struct EnvRemover : public Visitor {
+		virtual void visit( ExprStmt * stmt ) {
+			delete stmt->get_expr()->get_env();
+			stmt->get_expr()->set_env( nullptr );
+			Visitor::visit( stmt );
+		}
+	};
+
+	ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) {
 		assert( expr->has_result() && ! expr->get_result()->isVoid() );
-		return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
+		ObjectDecl * ret = new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
+		ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
+		ret->set_init( ctorInit );
+		ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
+		EnvRemover rm; // remove environments from subexpressions of StmtExprs
+		ctorInit->accept( rm );
+		return ret;
 	}
 
@@ -244,8 +267,8 @@
 			std::list< ObjectDecl * > ltmp;
 			std::list< ObjectDecl * > rtmp;
-			std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( ResolvExpr::Alternative & alt ){
+			std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), [&]( ResolvExpr::Alternative & alt ){
 				return newObject( lhsNamer, alt.expr );
 			});
-			std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( ResolvExpr::Alternative & alt ){
+			std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), [&]( ResolvExpr::Alternative & alt ){
 				return newObject( rhsNamer, alt.expr );
 			});
