Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 4aaac8a1188ef819fde364b9580989ada6a02e5c)
+++ src/GenPoly/GenPoly.cc	(revision 5a1ae14d260cbaf6348528c6b1ae616bd9df9b31)
@@ -48,8 +48,9 @@
 		}
 
-		bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env) {
-			for (auto &param : params) {
-				auto paramType = param.strict_as<ast::TypeExpr>();
-				if (isPolyType(paramType->type, env)) return true;
+		bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env ) {
+			for ( auto &param : params ) {
+				auto paramType = param.as<ast::TypeExpr>();
+				assertf( paramType, "Aggregate parameters should be type expressions" );
+				if ( isPolyType( paramType->type, env ) ) return true;
 			}
 			return false;
@@ -62,4 +63,13 @@
 				assertf(paramType, "Aggregate parameters should be type expressions");
 				if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
+			}
+			return false;
+		}
+
+		bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TypeVarMap & typeVars, const ast::TypeSubstitution * env ) {
+			for ( auto & param : params ) {
+				auto paramType = param.as<ast::TypeExpr>();
+				assertf( paramType, "Aggregate parameters should be type expressions" );
+				if ( isPolyType( paramType->type, typeVars, env ) ) return true;
 			}
 			return false;
@@ -185,19 +195,4 @@
 	}
 
-	const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
-		type = replaceTypeInst( type, env );
-
-		if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
-			if ( tyVars.contains( typeInst->typeString() ) ) return type;
-		} else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
-			return isPolyType( arrayType->base, env );
-		} else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
-			if ( hasPolyParams( structType->params, env ) ) return type;
-		} else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
-			if ( hasPolyParams( unionType->params, env ) ) return type;
-		}
-		return nullptr;
-	}
-
 const ast::Type * isPolyType( const ast::Type * type,
 		const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
@@ -207,9 +202,9 @@
 		if ( typeVars.contains( *inst ) ) return type;
 	} else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) {
-		return isPolyType( array->base, subst );
+		return isPolyType( array->base, typeVars, subst );
 	} else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) {
-		if ( hasPolyParams( sue->params, subst ) ) return type;
+		if ( hasPolyParams( sue->params, typeVars, subst ) ) return type;
 	} else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) {
-		if ( hasPolyParams( sue->params, subst ) ) return type;
+		if ( hasPolyParams( sue->params, typeVars, subst ) ) return type;
 	}
 	return nullptr;
