Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 4d7e8f593a41f7ffbbd2f33e5bfbe0332ef7f736)
+++ src/GenPoly/Box.cc	(revision 48ca586c3584dc8753b203bdf1cb413dcd98c33e)
@@ -70,6 +70,13 @@
 		  private:
 			void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
+			/// wraps a function application with a new temporary for the out-parameter return value
 			Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
-			Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, 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 *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );
 			Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
 			void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
@@ -385,11 +392,38 @@
 		}
 
-		Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
-			ResolvExpr::EqvClass eqvClass;
+		void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
+			for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
+				TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
+				assert(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 ) {
+			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
+				Type *concrete = env->lookup( typeInst->get_name() );
+				if ( concrete == 0 ) {
+					throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
+				} // if
+				return concrete;
+			} else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
+				if ( doClone ) {
+					structType = structType->clone();
+				}
+				replaceParametersWithConcrete( appExpr, structType->get_parameters() );
+				return structType;
+			} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
+				if ( doClone ) {
+					unionType = unionType->clone();
+				}
+				replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
+				return unionType;
+			}
+			return type;
+		}
+
+		Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
 			assert( env );
-			Type *concrete = env->lookup( typeName );
-			if ( concrete == 0 ) {
-				throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
-			} // if
+			Type *concrete = replaceWithConcrete( appExpr, polyType );
 			return addRetParam( appExpr, function, concrete, arg );
 		}
@@ -787,5 +821,5 @@
 
 			if ( ReferenceToType *polyType = isPolyRet( function ) ) {
-				ret = addPolyRetParam( appExpr, function, polyType->get_name(), arg );
+				ret = addPolyRetParam( appExpr, function, polyType, arg );
 			} else if ( needsAdapter( function, scopeTyVars ) ) {
 				// std::cerr << "needs adapter: ";
