Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision a378ca76d6b82f7b2aac7ab0f7502529cab85dfb)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 373d0b56d2f2649a0e148b14c5fe0e1df5a847b9)
@@ -453,13 +453,4 @@
 			return false;
 		}
-
-		AggregateDecl * getAggr( Type * t ) {
-			if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
-				return inst->baseStruct;
-			} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
-				return inst->baseUnion;
-			}
-			assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );
-		}
 	}
 
@@ -469,5 +460,5 @@
 		if ( isGenericType( memberExpr->aggregate->result ) ) {
 			// find the location of the member
-			AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
+			AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();
 			std::list< Declaration * > & members = aggr->members;
 			memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) );
@@ -479,5 +470,5 @@
 		if ( memberIndex != -1 ) {
 			// using the location from the generic type, find the member in the instantiation and rebuild the member expression
-			AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
+			AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();
 			assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." );
 			Declaration * member = *std::next( aggr->members.begin(), memberIndex );
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision a378ca76d6b82f7b2aac7ab0f7502529cab85dfb)
+++ src/SynTree/ReferenceToType.cc	(revision 373d0b56d2f2649a0e148b14c5fe0e1df5a847b9)
@@ -70,4 +70,6 @@
 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; }
 
+AggregateDecl * StructInstType::getAggr() { return baseStruct; }
+
 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseStruct );
@@ -101,4 +103,6 @@
 
 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; }
+
+AggregateDecl * UnionInstType::getAggr() { return baseUnion; }
 
 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision a378ca76d6b82f7b2aac7ab0f7502529cab85dfb)
+++ src/SynTree/Type.h	(revision 373d0b56d2f2649a0e148b14c5fe0e1df5a847b9)
@@ -178,4 +178,6 @@
 	virtual bool isComplete() const { return true; }
 
+	virtual AggregateDecl * getAggr() {	assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); }
+
 	virtual Type *clone() const = 0;
 	virtual void accept( Visitor & v ) = 0;
@@ -405,4 +407,6 @@
 	virtual bool isComplete() const override;
 
+	virtual AggregateDecl * getAggr() override;
+
 	/// Looks up the members of this struct named "name" and places them into "foundDecls".
 	/// Clones declarations into "foundDecls", caller responsible for freeing
@@ -436,4 +440,6 @@
 
 	virtual bool isComplete() const override;
+
+	virtual AggregateDecl * getAggr() override;
 
 	/// looks up the members of this union named "name" and places them into "foundDecls"
