Index: src/GenPoly/InstantiateGeneric.cpp
===================================================================
--- src/GenPoly/InstantiateGeneric.cpp	(revision a21aaff5ca37cddc33fe13bba97ba6f4d7b0e9a8)
+++ src/GenPoly/InstantiateGeneric.cpp	(revision 30bf6bf3677858106dafefcbfae7eff10d078623)
@@ -42,4 +42,10 @@
 
 using type_vector = ast::vector< ast::TypeExpr >;
+
+template<typename C, typename V>
+bool contains( C const & container, V const & value ) {
+	return std::any_of( container.begin(), container.end(),
+			[value]( auto& element ){ return element == value; } );
+}
 
 /// Abstracts type equality for a list of parameter types.
@@ -423,5 +429,5 @@
 }
 
-struct GenericInstantiator final :
+class GenericInstantiator final :
 		public ast::WithCodeLocation,
 		public ast::WithConstTypeSubstitution,
@@ -444,4 +450,7 @@
 	/// member from an instantiation.
 	int memberIndex = -1;
+	/// The polymorphic types we are currently instantiating.
+	ast::vector<ast::Decl> instantiating;
+public:
 
 	GenericInstantiator() :
@@ -597,15 +606,20 @@
 			);
 
-			// Forward declare before recursion. (TODO: Only when needed, #199.)
+			// Insert the declaration so it doesn't create it again,
 			insert( inst, typeSubs, newDecl );
-			if ( AggrDecl const * forwardDecl = ast::asForward( newDecl ) ) {
-				declsToAddBefore.push_back( forwardDecl );
-			}
+			// ... but mark this declaration as one we are working on.
+			auto guard = makeFuncGuard(
+				[this, newDecl](){ instantiating.push_back( newDecl ); },
+				[this](){ instantiating.pop_back(); } );
 			// Recursively instantiate members:
 			concDecl = strict_dynamic_cast<AggrDecl const *>(
 				newDecl->accept( *visitor ) );
-			// Must occur before declaration is added so
-			// that member instantiation appear first.
+
+			// Produce the declaration after its members are instantiated.
 			declsToAddBefore.push_back( concDecl );
+		} else if ( contains( instantiating, concDecl ) ) {
+			if ( AggrDecl const * forwardDecl = ast::asForward( concDecl ) ) {
+				declsToAddBefore.push_back( forwardDecl );
+			}
 		}
 		return new ast::SueInstType<AggrDecl>( concDecl, inst->qualifiers );
