Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision b940dc71b9b64989729859feb28dab18705ea7e3)
+++ src/GenPoly/Specialize.cc	(revision 64eae5636740bd0793ff27432eb02ade2386bec3)
@@ -194,4 +194,21 @@
 	}
 
+	/// restructures arg to match the structure of a single formal parameter. Assumes that atomic types are compatible (as the Resolver should have ensured this)
+	template< typename OutIterator >
+	void matchOneFormal( Expression * arg, unsigned & idx, Type * formal, OutIterator out ) {
+		if ( TupleType * tupleType = dynamic_cast< TupleType * >( formal ) ) {
+			std::list< Expression * > exprs;
+			for ( Type * t : *tupleType ) {
+				matchOneFormal( arg, idx, t, back_inserter( exprs ) );
+			}
+			*out++ = new TupleExpr( exprs );
+		} else {
+			*out++ = new TupleIndexExpr( arg->clone(), idx++ );
+		}
+	}
+
+	/// restructures the ttype argument to match the structure of the formal parameters of the actual function.
+	// [begin, end) are the formal parameters.
+	// args is the list of arguments currently given to the actual function, the last of which needs to be restructured.
 	template< typename Iterator >
 	void fixLastArg( std::list< Expression * > & args, Iterator begin, Iterator end ) {
@@ -203,7 +220,7 @@
 		unsigned idx = 0;
 		for ( ; begin != end; ++begin ) {
-			// DeclarationWithType * formal = *begin;
-			// Type * formalType = formal->get_type();
-			args.push_back( new TupleIndexExpr( last->clone(), idx++ ) );
+			DeclarationWithType * formal = *begin;
+			Type * formalType = formal->get_type();
+			matchOneFormal( last, idx, formalType, back_inserter( args ) );
 		}
 		delete last;
@@ -238,6 +255,7 @@
 
 		for ( DeclarationWithType* param : thunkFunc->get_functionType()->get_parameters() ) {
+			// walk the parameters to the actual function alongside the parameters to the thunk to find the location where the ttype parameter begins to satisfy parameters in the actual function.
+			assert( begin != end );
 			++begin;
-			assert( begin != end );
 
 			// std::cerr << "thunk param: " << param << std::endl;
