Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 760ba6722ab5edcb4d7c884be81fbda47db05c7e)
+++ src/GenPoly/InstantiateGeneric.cc	(revision b95fe406ae5fdb4a6c73a33d6416be39215e2e53)
@@ -27,4 +27,5 @@
 #include "Common/utility.h"            // for deleteAll, cloneAll
 #include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
+#include "ResolvExpr/typeops.h"
 #include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
 #include "ScrubTyVars.h"               // for ScrubTyVars
@@ -151,4 +152,12 @@
 		return gt;
 	}
+
+	/// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator
+	struct FixDtypeStatic final {
+		Expression * postmutate( MemberExpr * memberExpr );
+
+		template<typename AggrInst>
+		Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr );
+	};
 
 	/// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
@@ -198,6 +207,13 @@
 
 	void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
+		PassVisitor<FixDtypeStatic> fixer;
 		PassVisitor<GenericInstantiator> instantiator;
+
+		mutateAll( translationUnit, fixer );
 		mutateAll( translationUnit, instantiator );
+	}
+
+	bool isDtypeStatic( const std::list< TypeDecl* >& baseParams ) {
+		return std::all_of( baseParams.begin(), baseParams.end(), []( TypeDecl * td ) { return ! td->isComplete(); } );
 	}
 
@@ -479,4 +495,29 @@
 	}
 
+	template< typename AggrInst >
+	Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) {
+		// need to cast dtype-static member expressions to their actual type before that type is erased.
+		auto & baseParams = *inst->get_baseParameters();
+		if ( isDtypeStatic( baseParams ) ) {
+			if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) {
+				// type of member and type of expression differ, so add cast to actual type
+				return new CastExpr( memberExpr, memberExpr->result->clone() );
+			}
+		}
+		return memberExpr;
+	}
+
+	Expression * FixDtypeStatic::postmutate( MemberExpr * memberExpr ) {
+		Type * aggrType = memberExpr->aggregate->result;
+		if ( isGenericType( aggrType ) ) {
+			if ( StructInstType * inst = dynamic_cast< StructInstType * >( aggrType ) ) {
+				return fixMemberExpr( inst, memberExpr );
+			} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( aggrType ) ) {
+				return fixMemberExpr( inst, memberExpr );
+			}
+		}
+		return memberExpr;
+	}
+
 } // namespace GenPoly
 
