Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 1d2b64f538b2e524e418c78785233364f63db708)
+++ src/Tuples/TupleExpansion.cc	(revision d5556a3ceec1d963a2e9c0fccbfe2ff51b6eb263)
@@ -194,4 +194,5 @@
 				new CommaExpr( new CommaExpr( assignUnq, assignFinished ), var->clone() ) );
 			condExpr->set_result( var->get_result()->clone() );
+			condExpr->set_env( maybeClone( unqExpr->get_env() ) );
 			decls[id] = condExpr;
 		}
@@ -202,16 +203,11 @@
 	Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) {
 		assnExpr = safe_dynamic_cast< TupleAssignExpr * >( Parent::mutate( assnExpr ) );
-		CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
-		std::list< Statement * > & stmts = compoundStmt->get_kids();
-		for ( ObjectDecl * obj : assnExpr->get_tempDecls() ) {
-			stmts.push_back( new DeclStmt( noLabels, obj ) );
-		}
-		TupleExpr * tupleExpr = new TupleExpr( assnExpr->get_assigns() );
-		assert( tupleExpr->get_result() );
-		stmts.push_back( new ExprStmt( noLabels, tupleExpr ) );
-		assnExpr->get_tempDecls().clear();
-		assnExpr->get_assigns().clear();
+		StmtExpr * ret = assnExpr->get_stmtExpr();
+		assnExpr->set_stmtExpr( nullptr );
+		// move env to StmtExpr
+		ret->set_env( assnExpr->get_env() );
+		assnExpr->set_env( nullptr );
 		delete assnExpr;
-		return new StmtExpr( compoundStmt );
+		return ret;
 	}
 
@@ -221,4 +217,5 @@
 		if ( ! typeMap.count( mangleName ) ) {
 			// generate struct type to replace tuple type
+			// xxx - should fix this to only generate one tuple struct for each number of type parameters
 			StructDecl * decl = new StructDecl( "_tuple_type_" + mangleName );
 			decl->set_body( true );
@@ -247,4 +244,6 @@
 		tupleExpr->set_tuple( nullptr );
 		unsigned int idx = tupleExpr->get_index();
+		TypeSubstitution * env = tupleExpr->get_env();
+		tupleExpr->set_env( nullptr );
 		delete tupleExpr;
 
@@ -253,16 +252,19 @@
 		assert( structDecl->get_members().size() > idx );
 		Declaration * member = *std::next(structDecl->get_members().begin(), idx);
-		return new MemberExpr( safe_dynamic_cast< DeclarationWithType * >( member ), tuple );
-	}
-
-	Expression * replaceTupleExpr( Type * result, const std::list< Expression * > & exprs ) {
+		MemberExpr * memExpr = new MemberExpr( safe_dynamic_cast< DeclarationWithType * >( member ), tuple );
+		memExpr->set_env( env );
+		return memExpr;
+	}
+
+	Expression * replaceTupleExpr( Type * result, const std::list< Expression * > & exprs, TypeSubstitution * env ) {
 		if ( result->isVoid() ) {
 			// void result - don't need to produce a value for cascading - just output a chain of comma exprs
 			assert( ! exprs.empty() );
 			std::list< Expression * >::const_iterator iter = exprs.begin();
-			Expression * expr = *iter++;
+			Expression * expr = new CastExpr( *iter++ );
 			for ( ; iter != exprs.end(); ++iter ) {
-				expr = new CommaExpr( expr, *iter );
-			}
+				expr = new CommaExpr( expr, new CastExpr( *iter ) );
+			}
+			expr->set_env( env );
 			return expr;
 		} else {
@@ -274,5 +276,7 @@
 				inits.push_back( new SingleInit( expr ) );
 			}
-			return new CompoundLiteralExpr( result, new ListInit( inits ) );
+			Expression * expr = new CompoundLiteralExpr( result, new ListInit( inits ) );
+			expr->set_env( env );
+			return expr;
 		}
 	}
@@ -284,11 +288,13 @@
 		std::list< Expression * > exprs = tupleExpr->get_exprs();
 		assert( result );
+		TypeSubstitution * env = tupleExpr->get_env();
 
 		// remove data from shell and delete it
 		tupleExpr->set_result( nullptr );
 		tupleExpr->get_exprs().clear();
+		tupleExpr->set_env( nullptr );
 		delete tupleExpr;
 
-		return replaceTupleExpr( result, exprs );
+		return replaceTupleExpr( result, exprs, env );
 	}
 
