Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision a16764a6fbfe44300fc8834400a31c89befda091)
+++ src/GenPoly/Specialize.cc	(revision ee612482decbbc67bb9fee72d67d75ee9a661708)
@@ -200,26 +200,4 @@
 	}
 
-	struct EnvTrimmer {
-		TypeSubstitution * env, * newEnv;
-		EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
-		void previsit( TypeDecl * tyDecl ) {
-			// transfer known bindings for seen type variables
-			if ( Type * t = env->lookup( tyDecl->name ) ) {
-				newEnv->add( tyDecl->name, t );
-			}
-		}
-	};
-
-	/// reduce environment to just the parts that are referenced in a given expression
-	TypeSubstitution * trimEnv( ApplicationExpr * expr, TypeSubstitution * env ) {
-		if ( env ) {
-			TypeSubstitution * newEnv = new TypeSubstitution();
-			PassVisitor<EnvTrimmer> trimmer( env, newEnv );
-			expr->accept( trimmer );
-			return newEnv;
-		}
-		return nullptr;
-	}
-
 	/// Generates a thunk that calls `actual` with type `funType` and returns its address
 	Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
@@ -265,5 +243,5 @@
 		}
 
-		appExpr->set_env( trimEnv( appExpr, env ) );
+		appExpr->env = TypeSubstitution::newFromExpr( appExpr, env );
 		if ( inferParams ) {
 			appExpr->get_inferParams() = *inferParams;
