Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 207c7e1ddfd88d45fb9f62e00f173daf5b443541)
+++ src/SymTab/Validate.cc	(revision 0157ca7bcce204f62e0267dbebe739efb705eca2)
@@ -114,5 +114,5 @@
 		LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
 	  private:
-  		using Indexer::visit;
+  		using Parent::visit;
 		void visit( StructInstType *structInst ) final;
 		void visit( UnionInstType *unionInst ) final;
@@ -131,11 +131,12 @@
 
 	/// Replaces array and function types in forall lists by appropriate pointer type
-	class Pass3 : public Indexer {
+	class Pass3 final : public Indexer {
 		typedef Indexer Parent;
 	  public:
+	  	using Parent::visit;
 		Pass3( const Indexer *indexer );
 	  private:
-		virtual void visit( ObjectDecl *object );
-		virtual void visit( FunctionDecl *func );
+		virtual void visit( ObjectDecl *object ) override;
+		virtual void visit( FunctionDecl *func ) override;
 
 		const Indexer *indexer;
@@ -375,12 +376,12 @@
 	}
 
-	void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
-		Parent::visit( contextInst );
-		if ( contextInst->get_name() == "sized" ) {
+	void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
+		Parent::visit( traitInst );
+		if ( traitInst->get_name() == "sized" ) {
 			// "sized" is a special trait with no members - just flick the sized status on for the type variable
-			if ( contextInst->get_parameters().size() != 1 ) {
-				throw SemanticError( "incorrect number of context parameters: ", contextInst );
+			if ( traitInst->get_parameters().size() != 1 ) {
+				throw SemanticError( "incorrect number of trait parameters: ", traitInst );
 			}
-			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );
+			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
 			TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
 			TypeDecl * decl = inst->get_baseType();
@@ -389,27 +390,33 @@
 			return;
 		}
-		TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
-		if ( ! ctx ) {
-			throw SemanticError( "use of undeclared context " + contextInst->get_name() );
-		} // if
-		for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
-			for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
-				if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
-					cloneAll( otherCtx->get_members(), contextInst->get_members() );
-				} else {
-					contextInst->get_members().push_back( (*assert )->clone() );
-				} // if
+		TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
+		if ( ! traitDecl ) {
+			throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
+		} // if
+		if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
+			throw SemanticError( "incorrect number of trait parameters: ", traitInst );
+		} // if
+
+		for ( TypeDecl * td : traitDecl->get_parameters() ) {
+			for ( DeclarationWithType * assert : td->get_assertions() ) {
+				traitInst->get_members().push_back( assert->clone() );
 			} // for
 		} // for
 
-		if ( ctx->get_parameters().size() != contextInst->get_parameters().size() ) {
-			throw SemanticError( "incorrect number of context parameters: ", contextInst );
-		} // if
-
-		// need to clone members of the context for ownership purposes
+		// need to clone members of the trait for ownership purposes
 		std::list< Declaration * > members;
-		std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
-
-		applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
+		std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
+
+		applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
+
+		// need to carry over the 'sized' status of each decl in the instance
+		for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
+			TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( std::get<1>(p) );
+			if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
+				TypeDecl * formalDecl = std::get<0>(p);
+				TypeDecl * instDecl = inst->get_baseType();
+				if ( formalDecl->get_sized() ) instDecl->set_sized( true );
+			}
+		}
 	}
 
@@ -457,25 +464,26 @@
 	}
 
-	/// Fix up assertions
-	void forallFixer( Type *func ) {
-		for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
+	/// Fix up assertions - flattens assertion lists, removing all trait instances
+	void forallFixer( Type * func ) {
+		for ( TypeDecl * type : func->get_forall() ) {
 			std::list< DeclarationWithType * > toBeDone, nextRound;
-			toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
+			toBeDone.splice( toBeDone.end(), type->get_assertions() );
 			while ( ! toBeDone.empty() ) {
-				for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
-					if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
-						for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
-							DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
-							assert( dwt );
+				for ( DeclarationWithType * assertion : toBeDone ) {
+					if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
+						// expand trait instance into all of its members
+						for ( Declaration * member : traitInst->get_members() ) {
+							DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
 							nextRound.push_back( dwt->clone() );
 						}
-						delete ctx;
+						delete traitInst;
 					} else {
+						// pass assertion through
 						FixFunction fixer;
-						*assertion = (*assertion )->acceptMutator( fixer );
+						assertion = assertion->acceptMutator( fixer );
 						if ( fixer.get_isVoid() ) {
 							throw SemanticError( "invalid type void in assertion of function ", func );
 						}
-						(*type )->get_assertions().push_back( *assertion );
+						type->get_assertions().push_back( assertion );
 					} // if
 				} // for
