Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision a465caff623c39b44749b156091c82701114e584)
+++ src/SymTab/Autogen.cc	(revision 04273e9e7c52353f38bcd37e425ecf90e764d3e0)
@@ -173,13 +173,7 @@
 	}
 
-	void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
-		if ( isGeneric ) {
-			// rewrite member type in terms of the type variables on this operator
-			field = field->clone();
-			genericSubs.apply( field );
-
-			if ( src ) {
-				genericSubs.apply( src );
-			}
+	void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) {
+		if ( isDynamicLayout && src ) {
+			genericSubs.apply( src );
 		}
 
@@ -197,5 +191,5 @@
 		genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
 
-		if ( isGeneric && returnVal ) {
+		if ( isDynamicLayout && returnVal ) {
 			UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
 			derefRet->get_args().push_back( new VariableExpr( returnVal ) );
@@ -206,5 +200,5 @@
 
 	template<typename Iterator>
-	void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
+	void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) {
 		for ( ; member != end; ++member ) {
 			if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
@@ -242,5 +236,5 @@
 
 				Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
-				makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric, forward );
+				makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout, forward );
 			} // if
 		} // for
@@ -250,5 +244,5 @@
 	/// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.
 	template<typename Iterator>
-	void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
+	void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout ) {
 		FunctionType * ftype = func->get_functionType();
 		std::list<DeclarationWithType*> & params = ftype->get_parameters();
@@ -276,9 +270,9 @@
 					// matching parameter, initialize field with copy ctor
 					Expression *srcselect = new VariableExpr(*parameter);
-					makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric );
+					makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout );
 					++parameter;
 				} else {
 					// no matching parameter, initialize field with default ctor
-					makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isGeneric );
+					makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isDynamicLayout );
 				}
 			}
@@ -290,10 +284,10 @@
 
 		// Make function polymorphic in same parameters as generic struct, if applicable
-		bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
+		bool isDynamicLayout = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
 		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;
+			if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true;
 			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
 			assignType->get_forall().push_back( typeParam );
@@ -355,5 +349,5 @@
 			FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType->clone(), new CompoundStmt( noLabels ), true, false );
 			ctor->fixUniqueId();
-			makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isGeneric );
+			makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isDynamicLayout );
 			memCtors.push_back( ctor );
 		}
@@ -361,11 +355,11 @@
 
 		// generate appropriate calls to member ctor, assignment
-		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isGeneric );
-		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isGeneric );
-		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isGeneric );
+		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isDynamicLayout );
+		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isDynamicLayout );
+		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isDynamicLayout );
 		// needs to do everything in reverse, so pass "forward" as false
-		makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isGeneric, false );
-
-		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+		makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isDynamicLayout, false );
+
+		if ( ! isDynamicLayout ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
 
 		declsToAdd.push_back( assignDecl );
@@ -380,9 +374,9 @@
 
 		// Make function polymorphic in same parameters as generic union, if applicable
-		bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
+		bool isDynamicLayout = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
 		std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
 		std::list< Expression* > unionParams;  // List of matching parameters to put on types
 		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
-			isGeneric = true;
+			if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true;
 			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
 			assignType->get_forall().push_back( typeParam );
@@ -420,5 +414,5 @@
 
 		makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
-		if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
+		if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
 		else assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
 
