Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
+++ src/SynTree/ApplicationExpr.cc	(revision 6c3a988fe7dbaec419f8cc1c6be3085432447a99)
@@ -24,5 +24,5 @@
 
 ParamEntry::ParamEntry( const ParamEntry &other ) :
-		decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) {
+		decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ), inferParams( new InferredParams( *other.inferParams ) ) {
 }
 
@@ -34,4 +34,5 @@
 	formalType = maybeClone( other.formalType );
 	expr = maybeClone( other.expr );
+	*inferParams = *other.inferParams;
 	return *this;
 }
@@ -62,4 +63,16 @@
 }
 
+void printInferParams( const InferredParams & inferParams, std::ostream &os, int indent, int level ) {
+	if ( ! inferParams.empty() ) {
+		os << std::string(indent, ' ') << "with inferred parameters " << level << ":" << std::endl;
+		for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
+			os << std::string(indent+2, ' ');
+			Declaration::declFromId( i->second.decl )->printShort( os, indent+2 );
+			os << std::endl;
+			printInferParams( *i->second.inferParams, os, indent+2, level+1 );
+		} // for
+	} // if
+}
+
 void ApplicationExpr::print( std::ostream &os, int indent ) const {
 	os << "Application of" << std::endl << std::string(indent+2, ' ');
@@ -69,12 +82,5 @@
 		printAll( args, os, indent+2 );
 	} // if
-	if ( ! inferParams.empty() ) {
-		os << std::string(indent, ' ') << "with inferred parameters:" << std::endl;
-		for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
-			os << std::string(indent+2, ' ');
-			Declaration::declFromId( i->second.decl )->printShort( os, indent+2 );
-			os << std::endl;
-		} // for
-	} // if
+	printInferParams( inferParams, os, indent+2, 0 );
 	Expression::print( os, indent );
 }
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
+++ src/SynTree/Expression.h	(revision 6c3a988fe7dbaec419f8cc1c6be3085432447a99)
@@ -54,9 +54,12 @@
 };
 
+struct ParamEntry;
+typedef std::map< UniqueId, ParamEntry > InferredParams;
+
 /// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
 /// but subject to decay-to-pointer and type parameter renaming
 struct ParamEntry {
-	ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
-	ParamEntry( UniqueId decl, Type *actualType, Type *formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ) {}
+	ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ), inferParams( new InferredParams ) {}
+	ParamEntry( UniqueId decl, Type *actualType, Type *formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ), inferParams( new InferredParams ) {}
 	ParamEntry( const ParamEntry &other );
 	~ParamEntry();
@@ -67,7 +70,6 @@
 	Type *formalType;
 	Expression* expr;
-};
-
-typedef std::map< UniqueId, ParamEntry > InferredParams;
+	std::unique_ptr< InferredParams > inferParams;
+};
 
 /// ApplicationExpr represents the application of a function to a set of parameters.  This is the result of running an
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
+++ src/SynTree/TupleExpr.cc	(revision 6c3a988fe7dbaec419f8cc1c6be3085432447a99)
@@ -58,5 +58,5 @@
 TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) : tuple( tuple ), index( index )  {
 	TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
-	assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d", type->size(), index );
+	assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() );
 	set_result( (*std::next( type->get_types().begin(), index ))->clone() );
 	get_result()->set_isLvalue( type->get_isLvalue() );
