Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 92360603d942184e66e5f92706ecc75c6b04f121)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 0b5d8710a6dbc15de5d91976d128755d05fc1f7d)
@@ -166,4 +166,6 @@
 		/// Should not make use of type environment to replace types of function parameter and return values.
 		bool inFunctionType = false;
+		/// Index of current member, used to recreate MemberExprs with the member from an instantiation
+		int memberIndex = -1;
 		GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
 
@@ -171,5 +173,9 @@
 		Type* postmutate( UnionInstType *inst );
 
-		void premutate( __attribute__((unused)) FunctionType * ftype ) {
+		// fix MemberExprs to use the member from the instantiation
+		void premutate( MemberExpr * memberExpr );
+		Expression * postmutate( MemberExpr * memberExpr );
+
+		void premutate( FunctionType * ) {
 			GuardValue( inFunctionType );
 			inFunctionType = true;
@@ -418,4 +424,52 @@
 	}
 
+	namespace {
+		bool isGenericType( Type * t ) {
+			if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
+				return ! inst->parameters.empty();
+			} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
+				return ! inst->parameters.empty();
+			}
+			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() );
+		}
+	}
+
+	void GenericInstantiator::premutate( MemberExpr * memberExpr ) {
+		GuardValue( memberIndex );
+		memberIndex = -1;
+		if ( isGenericType( memberExpr->aggregate->result ) ) {
+			// find the location of the member
+			AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
+			std::list< Declaration * > & members = aggr->members;
+			memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) );
+			assertf( memberIndex < (int)members.size(), "Could not find member %s in generic type %s", toString( memberExpr->member ).c_str(), toString( memberExpr->aggregate ).c_str() );
+		}
+	}
+
+	Expression * GenericInstantiator::postmutate( MemberExpr * memberExpr ) {
+		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 );
+			assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." );
+			Declaration * member = *std::next( aggr->members.begin(), memberIndex );
+			assertf( member->name == memberExpr->member->name, "Instantiation has different member order than the generic type. %s / %s", toString( member ).c_str(), toString( memberExpr->member ).c_str() );
+			DeclarationWithType * field = safe_dynamic_cast< DeclarationWithType * >( member );
+			MemberExpr * ret = new MemberExpr( field, memberExpr->aggregate->clone() );
+			std::swap( ret->env, memberExpr->env );
+			delete memberExpr;
+			return ret;
+		}
+		return memberExpr;
+	}
+
 	void GenericInstantiator::beginScope() {
 		instantiations.beginScope();
