Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 722617d490808c780a86a748504d8dec075c2103)
+++ src/ResolvExpr/Resolver.cc	(revision 1d2b64f538b2e524e418c78785233364f63db708)
@@ -36,6 +36,14 @@
 	  public:
 		Resolver() : SymTab::Indexer( false ) {}
-
-		using SymTab::Indexer::visit;
+		Resolver( const SymTab:: Indexer & other ) : SymTab::Indexer( other ) {
+			if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
+				functionReturn = res->functionReturn;
+				initContext = res->initContext;
+				inEnumDecl = res->inEnumDecl;
+			}
+		}
+
+		typedef SymTab::Indexer Parent;
+		using Parent::visit;
 		virtual void visit( FunctionDecl *functionDecl ) override;
 		virtual void visit( ObjectDecl *functionDecl ) override;
@@ -192,5 +200,5 @@
 			initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
 		}
-		SymTab::Indexer::visit( objectDecl );
+		Parent::visit( objectDecl );
 		if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
 			// delete newly created signed int type
@@ -212,10 +220,10 @@
 	void Resolver::visit( ArrayType * at ) {
 		handlePtrType( at );
-		Visitor::visit( at );
+		Parent::visit( at );
 	}
 
 	void Resolver::visit( PointerType * pt ) {
 		handlePtrType( pt );
-		Visitor::visit( pt );
+		Parent::visit( pt );
 	}
 
@@ -225,5 +233,5 @@
 			typeDecl->set_base( new_type );
 		} // if
-		SymTab::Indexer::visit( typeDecl );
+		Parent::visit( typeDecl );
 	}
 
@@ -238,21 +246,19 @@
 		ValueGuard< Type * > oldFunctionReturn( functionReturn );
 		functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
-		SymTab::Indexer::visit( functionDecl );
+		Parent::visit( functionDecl );
 	}
 
 	void Resolver::visit( EnumDecl * enumDecl ) {
 		// in case we decide to allow nested enums
-		bool oldInEnumDecl = inEnumDecl;
+		ValueGuard< bool > oldInEnumDecl( inEnumDecl );
 		inEnumDecl = true;
-		SymTab::Indexer::visit( enumDecl );
-		inEnumDecl = oldInEnumDecl;
+		Parent::visit( enumDecl );
 	}
 
 	void Resolver::visit( ExprStmt *exprStmt ) {
-		if ( exprStmt->get_expr() ) {
-			Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
-			delete exprStmt->get_expr();
-			exprStmt->set_expr( newExpr );
-		} // if
+		assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
+		Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
+		delete exprStmt->get_expr();
+		exprStmt->set_expr( newExpr );
 	}
 
@@ -277,5 +283,5 @@
 		delete ifStmt->get_condition();
 		ifStmt->set_condition( newExpr );
-		Visitor::visit( ifStmt );
+		Parent::visit( ifStmt );
 	}
 
@@ -284,9 +290,9 @@
 		delete whileStmt->get_condition();
 		whileStmt->set_condition( newExpr );
-		Visitor::visit( whileStmt );
+		Parent::visit( whileStmt );
 	}
 
 	void Resolver::visit( ForStmt *forStmt ) {
-		SymTab::Indexer::visit( forStmt );
+		Parent::visit( forStmt );
 
 		if ( forStmt->get_condition() ) {
@@ -318,5 +324,5 @@
 
 	void Resolver::visit( CaseStmt *caseStmt ) {
-		Visitor::visit( caseStmt );
+		Parent::visit( caseStmt );
 	}
 
@@ -482,11 +488,11 @@
 			} else {
 				// missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
-				Visitor::visit( listInit );
+				Parent::visit( listInit );
 			}
 		} else {
 			assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext )
-			        || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) );
+			        || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) );
 			// basic types are handled here
-			Visitor::visit( listInit );
+			Parent::visit( listInit );
 		}
 
@@ -554,4 +560,17 @@
 	}
 
+	// needs to be callable from outside the resolver, so this is a standalone function
+	void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) {
+		assert( ctorInit );
+		Resolver resolver( indexer );
+		ctorInit->accept( resolver );
+	}
+
+	void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) {
+		assert( stmtExpr );
+		Resolver resolver( indexer );
+		stmtExpr->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
Index: src/ResolvExpr/Resolver.h
===================================================================
--- src/ResolvExpr/Resolver.h	(revision 722617d490808c780a86a748504d8dec075c2103)
+++ src/ResolvExpr/Resolver.h	(revision 1d2b64f538b2e524e418c78785233364f63db708)
@@ -25,4 +25,6 @@
 	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
 	Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
+	void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
+	void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
 } // namespace ResolvExpr
 
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 722617d490808c780a86a748504d8dec075c2103)
+++ 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 );
 			});
