Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision a32cfc9003ca64a94d1135465f24c0a7d67ad69c)
+++ src/CodeGen/GenType.cc	(revision fae2cf81166d513474477d031cd43819b7f1f2fa)
@@ -237,5 +237,4 @@
 	void GenType::visit( TupleType * tupleType ) {
 		assertf( ! genC, "Tuple types should not reach code generation." );
-		Visitor::visit( tupleType );
 		unsigned int i = 0;
 		std::ostringstream os;
@@ -245,5 +244,5 @@
 			os << genType( t, "", pretty, genC, lineMarks ) << (i == tupleType->size() ? "" : ", ");
 		}
-		os << "]";
+		os << "] ";
 		typeString = os.str() + typeString;
 	}
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision a32cfc9003ca64a94d1135465f24c0a7d67ad69c)
+++ src/InitTweak/FixInit.cc	(revision fae2cf81166d513474477d031cd43819b7f1f2fa)
@@ -619,5 +619,15 @@
 
 		Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
-			stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
+			// function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
+			// since temporaries can be shared across sub-expressions, e.g.
+			//   [A, A] f();
+			//   g([A] x, [A] y);
+			//   f(g());
+			// f is executed once, so the return temporary is shared across the tuple constructors for x and y.
+			std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
+			for ( Statement *& stmt : stmts ) {
+				stmt = stmt->acceptMutator( *this );
+			} // for
+			// stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
 			assert( stmtExpr->get_result() );
 			Type * result = stmtExpr->get_result();
