Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 7cf8006687e5fe7356f0e97aabe15c2884ff7f77)
+++ src/GenPoly/Box.cc	(revision f6aa89cedbf067f470de7318a0b73c33e7624bb7)
@@ -100,9 +100,4 @@
 			/// wraps a function application with a new temporary for the out-parameter return value
 			Expression *addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg );
-			/// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
-			void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params );
-			/// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
-			/// If `doClone` is set to false, will not clone interior types
-			Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
 			/// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
 			Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg );
@@ -450,4 +445,8 @@
 		}
 
+		/// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
+		/// If `doClone` is set to false, will not clone interior types
+		Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true );
+
 		Pass1::Pass1() : tempNamer( "_temp" ) {}
 
@@ -572,5 +571,5 @@
 			// a polymorphic return type may need to be added to the argument list
 			if ( polyRetType ) {
-				Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
+				Type *concRetType = replaceWithConcrete( polyRetType, env );
 				passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
 				++fnArg; // skip the return parameter in the argument list
@@ -620,13 +619,15 @@
 		}
 
-		void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
+		/// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
+		void replaceParametersWithConcrete( std::list< Expression* >& params, TypeSubstitution const * env ) {
 			for ( Expression * const param : params ) {
 				TypeExpr *paramType = dynamic_cast< TypeExpr* >( param );
 				assertf(paramType, "Aggregate parameters should be type expressions");
-				paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
-			}
-		}
-
-		Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
+				paramType->set_type( replaceWithConcrete( paramType->get_type(), env, false ) );
+			}
+		}
+
+		// See forward definition.
+		Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone ) {
 			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
 				Type *concrete = env->lookup( typeInst->get_name() );
@@ -639,5 +640,5 @@
 					structType = structType->clone();
 				}
-				replaceParametersWithConcrete( appExpr, structType->get_parameters() );
+				replaceParametersWithConcrete( structType->get_parameters(), env );
 				return structType;
 			} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
@@ -645,5 +646,5 @@
 					unionType = unionType->clone();
 				}
-				replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
+				replaceParametersWithConcrete( unionType->get_parameters(), env );
 				return unionType;
 			}
@@ -653,5 +654,5 @@
 		Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) {
 			assert( env );
-			Type *concrete = replaceWithConcrete( appExpr, dynType );
+			Type *concrete = replaceWithConcrete( dynType, env );
 			// add out-parameter for return value
 			return addRetParam( appExpr, concrete, arg );
@@ -1115,5 +1116,5 @@
 			arg = appExpr->get_args().begin();
 
-			Type *concRetType = replaceWithConcrete( appExpr, dynRetType );
+			Type *concRetType = replaceWithConcrete( dynRetType, env );
 			passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)
 			addInferredParams( appExpr, function, arg, exprTyVars );
