Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 793335167c5347f27e76d8ab9f3434b795a6602d)
+++ src/SynTree/Expression.cc	(revision cce94296a61149881755d331f2f292f92c7f6c5c)
@@ -524,4 +524,5 @@
 
 ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
+	set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment
 	delete callExpr;
 	deleteAll( tempDecls );
@@ -533,4 +534,5 @@
 	os <<  "Implicit Copy Constructor Expression: " << std::endl;
 	assert( callExpr );
+	os << std::string( indent+2, ' ' );
 	callExpr->print( os, indent + 2 );
 	os << std::endl << std::string( indent, ' ' ) << "with temporaries:" << std::endl;
@@ -584,4 +586,5 @@
 	os << std::string( indent+2, ' ' );
 	initializer->print( os, indent + 2 );
+	Expression::print( os, indent );
 }
 
@@ -603,4 +606,5 @@
 	os << " ... ";
 	high->print( os, indent );
+	Expression::print( os, indent );
 }
 
@@ -614,11 +618,25 @@
 	}
 }
-StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {}
+StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
+	cloneAll( other.returnDecls, returnDecls );
+	cloneAll( other.dtors, dtors );
+}
 StmtExpr::~StmtExpr() {
 	delete statements;
+	deleteAll( dtors );
+	deleteAll( returnDecls );
 }
 void StmtExpr::print( std::ostream &os, int indent ) const {
 	os << "Statement Expression: " << std::endl << std::string( indent, ' ' );
 	statements->print( os, indent+2 );
+	if ( ! returnDecls.empty() ) {
+		os << std::string( indent+2, ' ' ) << "with returnDecls: ";
+		printAll( returnDecls, os, indent+2 );
+	}
+	if ( ! dtors.empty() ) {
+		os << std::string( indent+2, ' ' ) << "with dtors: ";
+		printAll( dtors, os, indent+2 );
+	}
+	Expression::print( os, indent );
 }
 
@@ -644,7 +662,8 @@
 	get_expr()->print( os, indent+2 );
 	if ( get_object() ) {
-		os << " with decl: ";
+		os << std::string( indent+2, ' ' ) << "with decl: ";
 		get_object()->printShort( os, indent+2 );
 	}
+	Expression::print( os, indent );
 }
 
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 793335167c5347f27e76d8ab9f3434b795a6602d)
+++ src/SynTree/Expression.h	(revision cce94296a61149881755d331f2f292f92c7f6c5c)
@@ -543,11 +543,6 @@
 
 	std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
-	void set_tempDecls( std::list< ObjectDecl * > newValue ) { tempDecls = newValue; }
-
 	std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
-	void set_returnDecls( std::list< ObjectDecl * > newValue ) { returnDecls = newValue; }
-
 	std::list< Expression * > & get_dtors() { return dtors; }
-	void set_dtors( std::list< Expression * > newValue ) { dtors = newValue; }
 
 	virtual ImplicitCopyCtorExpr *clone() const { return new ImplicitCopyCtorExpr( *this ); }
@@ -706,6 +701,6 @@
 	virtual ~TupleAssignExpr();
 
-	std::list< Expression * > & get_assigns() { return assigns; }
-	std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
+	TupleAssignExpr * set_stmtExpr( StmtExpr * newValue ) { stmtExpr = newValue; return this; }
+	StmtExpr * get_stmtExpr() const { return stmtExpr; }
 
 	virtual TupleAssignExpr *clone() const { return new TupleAssignExpr( *this ); }
@@ -714,6 +709,5 @@
 	virtual void print( std::ostream &os, int indent = 0 ) const;
   private:
-	std::list< Expression * > assigns; // assignment expressions that use tempDecls
-	std::list< ObjectDecl * > tempDecls; // temporaries for address of lhs exprs
+	StmtExpr * stmtExpr = nullptr;
 };
 
@@ -728,4 +722,7 @@
 	StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
 
+	std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
+	std::list< Expression * > & get_dtors() { return dtors; }
+
 	virtual StmtExpr *clone() const { return new StmtExpr( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -734,4 +731,6 @@
 private:
 	CompoundStmt * statements;
+	std::list< ObjectDecl * > returnDecls; // return variable(s) for stmt expression
+	std::list< Expression * > dtors; // destructor(s) for return variable(s)
 };
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 793335167c5347f27e76d8ab9f3434b795a6602d)
+++ src/SynTree/Mutator.cc	(revision cce94296a61149881755d331f2f292f92c7f6c5c)
@@ -325,4 +325,5 @@
 	mutateAll( impCpCtorExpr->get_tempDecls(), *this );
 	mutateAll( impCpCtorExpr->get_returnDecls(), *this );
+	mutateAll( impCpCtorExpr->get_dtors(), *this );
 	return impCpCtorExpr;
 }
@@ -373,6 +374,5 @@
 Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
 	assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
-	mutateAll( assignExpr->get_tempDecls(), *this );
-	mutateAll( assignExpr->get_assigns(), *this );
+	assignExpr->set_stmtExpr( maybeMutate( assignExpr->get_stmtExpr(), *this ) );
 	return assignExpr;
 }
@@ -381,4 +381,6 @@
 	stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
 	stmtExpr->set_statements( maybeMutate( stmtExpr->get_statements(), *this ) );
+	mutateAll( stmtExpr->get_returnDecls(), *this );
+	mutateAll( stmtExpr->get_dtors(), *this );
 	return stmtExpr;
 }
@@ -503,4 +505,5 @@
 Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
 	ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
+	ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) );
 	ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
 	return ctorInit;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision 793335167c5347f27e76d8ab9f3434b795a6602d)
+++ src/SynTree/TupleExpr.cc	(revision cce94296a61149881755d331f2f292f92c7f6c5c)
@@ -87,41 +87,31 @@
 }
 
-
-TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ), assigns( assigns ), tempDecls( tempDecls ) {
+TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ) {
+	// convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments
 	set_result( Tuples::makeTupleType( assigns ) );
+	CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
+	std::list< Statement * > & stmts = compoundStmt->get_kids();
+	for ( ObjectDecl * obj : tempDecls ) {
+		stmts.push_back( new DeclStmt( noLabels, obj ) );
+	}
+	TupleExpr * tupleExpr = new TupleExpr( assigns );
+	assert( tupleExpr->get_result() );
+	stmts.push_back( new ExprStmt( noLabels, tupleExpr ) );
+	stmtExpr = new StmtExpr( compoundStmt );
 }
 
 TupleAssignExpr::TupleAssignExpr( const TupleAssignExpr &other ) : Expression( other ) {
-	cloneAll( other.assigns, assigns );
-	cloneAll( other.tempDecls, tempDecls );
-
-	// clone needs to go into assigns and replace tempDecls
-	VarExprReplacer::DeclMap declMap;
-	std::list< ObjectDecl * >::const_iterator origit = other.tempDecls.begin();
-	for ( ObjectDecl * temp : tempDecls ) {
-		assert( origit != other.tempDecls.end() );
-		ObjectDecl * origTemp = *origit++;
-		assert( origTemp );
-		assert( temp->get_name() == origTemp->get_name() );
-		declMap[ origTemp ] = temp;
-	}
-	if ( ! declMap.empty() ) {
-		VarExprReplacer replacer( declMap );
-		for ( Expression * assn : assigns ) {
-			assn->accept( replacer );
-		}
-	}
+	assert( other.stmtExpr );
+	stmtExpr = other.stmtExpr->clone();
 }
 
 TupleAssignExpr::~TupleAssignExpr() {
-	deleteAll( assigns );
-	// deleteAll( tempDecls );
+	delete stmtExpr;
 }
 
 void TupleAssignExpr::print( std::ostream &os, int indent ) const {
-	os << "Tuple Assignment Expression, with temporaries:" << std::endl;
-	printAll( tempDecls, os, indent+4 );
-	os << std::string( indent+2, ' ' ) << "with assignments: " << std::endl;
-	printAll( assigns, os, indent+4 );
+	os << "Tuple Assignment Expression, with stmt expr:" << std::endl;
+	os << std::string( indent+2, ' ' );
+	stmtExpr->print( os, indent+4 );
 	Expression::print( os, indent );
 }
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 793335167c5347f27e76d8ab9f3434b795a6602d)
+++ src/SynTree/Visitor.cc	(revision cce94296a61149881755d331f2f292f92c7f6c5c)
@@ -276,4 +276,5 @@
 	acceptAll( impCpCtorExpr->get_tempDecls(), *this );
 	acceptAll( impCpCtorExpr->get_returnDecls(), *this );
+	acceptAll( impCpCtorExpr->get_dtors(), *this );
 }
 
@@ -317,6 +318,5 @@
 void Visitor::visit( TupleAssignExpr *assignExpr ) {
 	maybeAccept( assignExpr->get_result(), *this );
-	acceptAll( assignExpr->get_tempDecls(), *this );
-	acceptAll( assignExpr->get_assigns(), *this );
+	maybeAccept( assignExpr->get_stmtExpr(), *this );
 }
 
@@ -324,4 +324,6 @@
 	maybeAccept( stmtExpr->get_result(), *this );
 	maybeAccept( stmtExpr->get_statements(), *this );
+	acceptAll( stmtExpr->get_returnDecls(), *this );
+	acceptAll( stmtExpr->get_dtors(), *this );
 }
 
@@ -425,4 +427,5 @@
 void Visitor::visit( ConstructorInit *ctorInit ) {
 	maybeAccept( ctorInit->get_ctor(), *this );
+	maybeAccept( ctorInit->get_dtor(), *this );
 	maybeAccept( ctorInit->get_init(), *this );
 }
