Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
+++ src/SynTree/ReferenceToType.cc	(revision f006f010a16b044c89b41fdeb2442986671eb5dc)
@@ -56,4 +56,6 @@
 	}
 } // namespace
+
+StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct ) : Parent( tq, baseStruct->get_name() ), baseStruct( baseStruct ) {}
 
 std::string StructInstType::typeString() const { return "struct"; }
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
+++ src/SynTree/Type.h	(revision f006f010a16b044c89b41fdeb2442986671eb5dc)
@@ -234,4 +234,5 @@
   public:
 	StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {}
+	StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct );
 	StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
 
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 6eb89484ef2c58941d8905aad3ee756b10460cf9)
+++ src/Tuples/TupleExpansion.cc	(revision f006f010a16b044c89b41fdeb2442986671eb5dc)
@@ -18,11 +18,32 @@
 #include <cassert>
 #include "Tuples.h"
-#include "GenPoly/PolyMutator.h"
+#include "GenPoly/DeclMutator.h"
+#include "SynTree/Mutator.h"
 #include "SynTree/Statement.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SymTab/Mangler.h"
+#include "Common/ScopedMap.h"
 
 namespace Tuples {
-	class TupleAssignExpander : public GenPoly::PolyMutator {
+	class TupleAssignExpander : public Mutator {
 	public:
 		virtual Expression * mutate( TupleAssignExpr * tupleExpr );
+	};
+
+	class TupleTypeReplacer : public GenPoly::DeclMutator {
+	  public:
+		typedef GenPoly::DeclMutator Parent;
+
+		virtual Type * mutate( TupleType * tupleType );
+
+		virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
+			typeMap.beginScope();
+			stmt = Parent::mutate( stmt );
+			typeMap.endScope();
+			return stmt;
+		}
+	  private:
+		ScopedMap< std::string, StructDecl * > typeMap;
 	};
 
@@ -30,4 +51,7 @@
 		TupleAssignExpander expander;
 		mutateAll( translationUnit, expander );
+
+		TupleTypeReplacer replacer;
+		replacer.mutateDeclarationList( translationUnit );
 	}
 
@@ -47,4 +71,22 @@
 	}
 
+	Type * TupleTypeReplacer::mutate( TupleType * tupleType ) {
+		std::string mangleName = SymTab::Mangler::mangleType( tupleType );
+		TupleType * newType = safe_dynamic_cast< TupleType * > ( Parent::mutate( tupleType ) );
+		if ( ! typeMap.count( mangleName ) ) {
+			// generate struct type to replace tuple type
+			StructDecl * decl = new StructDecl( "_tuple_type_" + mangleName );
+			decl->set_body( true );
+			int cnt = 0;
+			for ( Type * t : *newType ) {
+				decl->get_members().push_back( new ObjectDecl( "field_"+std::to_string(++cnt), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, t->clone(), nullptr ) );
+			}
+			typeMap[mangleName] = decl;
+			addDeclaration( decl );
+		}
+		delete newType;
+		return new StructInstType( newType->get_qualifiers(), typeMap[mangleName] );
+	}
+
 } // namespace Tuples
 
