Index: src/AST/DeclReplacer.hpp
===================================================================
--- src/AST/DeclReplacer.hpp	(revision 0442f93f72585f41b3db5dd2c13dddf3b0cb3ca9)
+++ src/AST/DeclReplacer.hpp	(revision 065867274d8bd8d2dc7817a83c4af363d233de03)
@@ -18,21 +18,26 @@
 #include <unordered_map>
 
-#include "Node.hpp"
+namespace ast {
+	class DeclWithType;
+	class Expr;
+	class Node;
+	class TypeDecl;
+}
 
 namespace ast {
-	class DeclWithType;
-	class TypeDecl;
-	class Expr;
 
-	namespace DeclReplacer {
-		using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >;
-		using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >;
-		using ExprMap = std::unordered_map< const DeclWithType *, const Expr * >;
+namespace DeclReplacer {
 
-		const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false );
-		const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false );
-		const Node * replace( const Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
-		const Node * replace( const Node * node, const ExprMap & exprMap);
-	}
+using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >;
+using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >;
+using ExprMap = std::unordered_map< const DeclWithType *, const Expr * >;
+
+const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false );
+const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false );
+const Node * replace( const Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
+const Node * replace( const Node * node, const ExprMap & exprMap);
+
+}
+
 }
 
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 0442f93f72585f41b3db5dd2c13dddf3b0cb3ca9)
+++ src/AST/Util.cpp	(revision 065867274d8bd8d2dc7817a83c4af363d233de03)
@@ -83,4 +83,23 @@
 }
 
+/// Check that the MemberExpr has an aggregate type and matching member.
+void memberMatchesAggregate( const MemberExpr * expr ) {
+	const Type * aggrType = expr->aggregate->result->stripReferences();
+	const AggregateDecl * decl = nullptr;
+	if ( auto inst = dynamic_cast<const StructInstType *>( aggrType ) ) {
+		decl = inst->base;
+	} else if ( auto inst = dynamic_cast<const UnionInstType *>( aggrType ) ) {
+		decl = inst->base;
+	}
+	assertf( decl, "Aggregate of member not correct type." );
+
+	for ( auto aggrMember : decl->members ) {
+		if ( expr->member == aggrMember ) {
+			return;
+		}
+	}
+	assertf( false, "Member not found." );
+}
+
 struct InvariantCore {
 	// To save on the number of visits: this is a kind of composed core.
@@ -108,4 +127,9 @@
 	}
 
+	void previsit( const MemberExpr * node ) {
+		previsit( (const ParseNode *)node );
+		memberMatchesAggregate( node );
+	}
+
 	void postvisit( const Node * node ) {
 		no_strong_cycles.postvisit( node );
Index: src/Validate/HoistStruct.cpp
===================================================================
--- src/Validate/HoistStruct.cpp	(revision 0442f93f72585f41b3db5dd2c13dddf3b0cb3ca9)
+++ src/Validate/HoistStruct.cpp	(revision 065867274d8bd8d2dc7817a83c4af363d233de03)
@@ -18,6 +18,8 @@
 #include <sstream>
 
+#include "AST/DeclReplacer.hpp"
 #include "AST/Pass.hpp"
 #include "AST/TranslationUnit.hpp"
+#include "AST/Vector.hpp"
 
 namespace Validate {
@@ -51,4 +53,6 @@
 	template<typename AggrDecl>
 	AggrDecl const * postAggregate( AggrDecl const * );
+	template<typename InstType>
+	InstType const * preCollectionInstType( InstType const * type );
 
 	ast::AggregateDecl const * parent = nullptr;
@@ -66,4 +70,22 @@
 	qualifiedName( decl, ss );
 	return ss.str();
+}
+
+void extendParams( ast::vector<ast::TypeDecl> & dstParams,
+		ast::vector<ast::TypeDecl> const & srcParams ) {
+	if ( srcParams.empty() ) return;
+
+	ast::DeclReplacer::TypeMap newToOld;
+	ast::vector<ast::TypeDecl> params;
+	for ( ast::ptr<ast::TypeDecl> const & srcParam : srcParams ) {
+		ast::TypeDecl * dstParam = ast::deepCopy( srcParam.get() );
+		dstParam->init = nullptr;
+		newToOld.emplace( srcParam, dstParam );
+		for ( auto assertion : dstParam->assertions ) {
+			assertion = ast::DeclReplacer::replace( assertion, newToOld );
+		}
+		params.emplace_back( dstParam );
+	}
+	spliceBegin( dstParams, params );
 }
 
@@ -74,9 +96,9 @@
 		mut->parent = parent;
 		mut->name = qualifiedName( mut );
-		return mut;
-	} else {
-		GuardValue( parent ) = decl;
-		return decl;
-	}
+		extendParams( mut->params, parent->params );
+		decl = mut;
+	}
+	GuardValue( parent ) = decl;
+	return decl;
 }
 
@@ -112,4 +134,36 @@
 }
 
+ast::AggregateDecl const * commonParent(
+		ast::AggregateDecl const * lhs, ast::AggregateDecl const * rhs ) {
+	for ( auto outer = lhs ; outer ; outer = outer->parent ) {
+		for ( auto inner = rhs ; inner ; inner = inner->parent ) {
+			if ( outer == inner ) {
+				return outer;
+			}
+		}
+	}
+	return nullptr;
+}
+
+template<typename InstType>
+InstType const * HoistStructCore::preCollectionInstType( InstType const * type ) {
+    if ( !type->base->parent ) return type;
+    if ( type->base->params.empty() ) return type;
+
+    InstType * mut = ast::mutate( type );
+    ast::AggregateDecl const * parent =
+        commonParent( this->parent, mut->base->parent );
+    assert( parent );
+
+    std::vector<ast::ptr<ast::Expr>> args;
+    for ( const ast::ptr<ast::TypeDecl> & param : parent->params ) {
+        args.emplace_back( new ast::TypeExpr( param->location,
+            new ast::TypeInstType( param )
+        ) );
+    }
+    spliceBegin( mut->params, args );
+    return mut;
+}
+
 template<typename InstType>
 InstType const * preInstType( InstType const * type ) {
@@ -121,9 +175,9 @@
 
 ast::StructInstType const * HoistStructCore::previsit( ast::StructInstType const * type ) {
-	return preInstType( type );
+	return preInstType( preCollectionInstType( type ) );
 }
 
 ast::UnionInstType const * HoistStructCore::previsit( ast::UnionInstType const * type ) {
-	return preInstType( type );
+	return preInstType( preCollectionInstType( type ) );
 }
 
