Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 5c4d27f29930c3ac488913ca34878f36a647f694)
+++ src/SymTab/Autogen.h	(revision b95fe406ae5fdb4a6c73a33d6416be39215e2e53)
@@ -56,10 +56,10 @@
 	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
 	template< typename OutputIterator >
-	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
+	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
 
 	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
 	/// optionally returns a statement which must be inserted prior to the containing loop, if there is one
 	template< typename OutputIterator >
-	Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false ) {
+	Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
 		bool isReferenceCtorDtor = false;
 		if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
@@ -68,5 +68,5 @@
 			fname = "?=?";
 			dstParam = new AddressExpr( dstParam );
-			addCast = false;
+			addCast = nullptr;
 			isReferenceCtorDtor = true;
 		}
@@ -83,6 +83,5 @@
 			// remove lvalue as a qualifier, this can change to
 			//   type->get_qualifiers() = Type::Qualifiers();
-			assert( type );
-			Type * castType = type->clone();
+			Type * castType = addCast->clone();
 			castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
 			// castType->set_lvalue( true ); // xxx - might not need this
@@ -115,9 +114,15 @@
 	/// If forward is true, loop goes from 0 to N-1, else N-1 to 0
 	template< typename OutputIterator >
-	void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
+	void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
 		static UniqueName indexName( "_index" );
 
 		// for a flexible array member nothing is done -- user must define own assignment
-		if ( ! array->get_dimension() ) return ;
+		if ( ! array->get_dimension() ) return;
+
+		if ( addCast ) {
+			// peel off array layer from cast
+			ArrayType * at = strict_dynamic_cast< ArrayType * >( addCast );
+			addCast = at->base;
+		}
 
 		Expression * begin, * end, * update, * cmp;
@@ -171,5 +176,5 @@
 
 	template< typename OutputIterator >
-	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
+	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
 		if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
 			genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
@@ -191,5 +196,9 @@
 		if ( isUnnamedBitfield( obj ) ) return;
 
-		bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) );
+		Type * addCast = nullptr;
+		if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ) ) {
+			assert( dstParam->result );
+			addCast = dstParam->result;
+		}
 		std::list< Statement * > stmts;
 		genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward );
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 5c4d27f29930c3ac488913ca34878f36a647f694)
+++ src/SymTab/Validate.cc	(revision b95fe406ae5fdb4a6c73a33d6416be39215e2e53)
@@ -124,5 +124,5 @@
 
 	/// Associates forward declarations of aggregates with their definitions
-	struct LinkReferenceToTypes final : public WithIndexer {
+	struct LinkReferenceToTypes final : public WithIndexer, public WithGuards {
 		LinkReferenceToTypes( const Indexer *indexer );
 		void postvisit( TypeInstType *typeInst );
@@ -137,4 +137,9 @@
 		void postvisit( UnionDecl *unionDecl );
 		void postvisit( TraitDecl * traitDecl );
+
+		void previsit( StructDecl *structDecl );
+		void previsit( UnionDecl *unionDecl );
+
+		void renameGenericParams( std::list< TypeDecl * > & params );
 
 	  private:
@@ -147,4 +152,6 @@
 		ForwardStructsType forwardStructs;
 		ForwardUnionsType forwardUnions;
+		/// true if currently in a generic type body, so that type parameter instances can be renamed appropriately
+		bool inGeneric = false;
 	};
 
@@ -561,4 +568,30 @@
 	}
 
+	void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {
+		// rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.
+		//   forall(otype T)
+		//   struct Box {
+		//     T x;
+		//   };
+		//   forall(otype T)
+		//   void f(Box(T) b) {
+		//     ...
+		//   }
+		// The T in Box and the T in f are different, so internally the naming must reflect that.
+		GuardValue( inGeneric );
+		inGeneric = ! params.empty();
+		for ( TypeDecl * td : params ) {
+			td->name = "__" + td->name + "_generic_";
+		}
+	}
+
+	void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {
+		renameGenericParams( structDecl->parameters );
+	}
+
+	void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {
+		renameGenericParams( unionDecl->parameters );
+	}
+
 	void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
 		// visit struct members first so that the types of self-referencing members are updated properly
@@ -588,4 +621,6 @@
 
 	void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
+		// ensure generic parameter instances are renamed like the base type
+		if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
 		if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
 			if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
