Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 408d460b6eee7c0426d19f157e42b5879e8af665)
+++ src/GenPoly/Box.cc	(revision 98735ef93efbdeff0d764e4f0c39fc14c31e1f6b)
@@ -1399,5 +1399,5 @@
 				delete memberExpr;
 				return fieldLoc;
-			} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
+			} else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
 				// union members are all at offset zero, so build appropriately-dereferenced variable
 				Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 408d460b6eee7c0426d19f157e42b5879e8af665)
+++ src/SymTab/Validate.cc	(revision 98735ef93efbdeff0d764e4f0c39fc14c31e1f6b)
@@ -382,5 +382,5 @@
 		// it's not a semantic error if the struct is not found, just an implicit forward declaration
 		if ( st ) {
-			assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
+			//assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
 			structInst->set_baseStruct( st );
 		} // if
@@ -659,4 +659,25 @@
 	}
 
+	/// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only)
+	TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) {
+		TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() );
+
+		if ( src->get_kind() == TypeDecl::Any ) {
+			// just include assignment operator assertion
+			TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst );
+			FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false );
+			assignFunctionType->get_returnVals().push_back(
+				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) );
+			assignFunctionType->get_parameters().push_back(
+				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) );
+			assignFunctionType->get_parameters().push_back(
+				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) );
+			FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false );
+			dst->get_assertions().push_back( assignAssert );
+		}
+
+		return dst;
+	}
+
 	Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
 		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
@@ -666,9 +687,12 @@
 		std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
 		std::list< Expression* > structParams;  // List of matching parameters to put on types
+		TypeSubstitution genericSubs; // Substitutions to make to member types of struct
 		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
 			isGeneric = true;
-			TypeDecl *typeParam = (*param)->clone();
+			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
 			assignType->get_forall().push_back( typeParam );
-			structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
+			TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam );
+			genericSubs.add( (*param)->get_name(), newParamType );
+			structParams.push_back( new TypeExpr( newParamType ) );
 		}
 
@@ -701,10 +725,24 @@
 				}
 
-				if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
-					makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
-					if ( isGeneric ) makeArrayAssignment( srcParam, returnVal, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
+				if ( isGeneric ) {
+					// rewrite member type in terms of the type variables on this operator
+					DeclarationWithType *fixedMember = dwt->clone();
+					genericSubs.apply( fixedMember );
+
+					// assign to both destination and return value
+					if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
+						makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
+						makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
+					} else {
+						makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
+						makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
+					} // if
 				} else {
-					makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
-					if ( isGeneric ) makeScalarAssignment( srcParam, returnVal, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
+					// assign to destination
+					if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
+						makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
+					} else {
+						makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
+					} // if
 				} // if
 			} // if
@@ -724,5 +762,5 @@
 		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
 			isGeneric = true;
-			TypeDecl *typeParam = (*param)->clone();
+			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
 			assignType->get_forall().push_back( typeParam );
 			unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
