Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 92360603d942184e66e5f92706ecc75c6b04f121)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 74b007ba1f2facc85656ade19a8bab1d56bb0a82)
@@ -633,4 +633,10 @@
 		AssertionSet newNeed;
 		//AssertionParentSet needParents;
+		PRINT(
+			std::cerr << "env is: " << std::endl;
+			newAlt.env.print( std::cerr, 0 );
+			std::cerr << std::endl;
+		)
+
 		inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
 //	PRINT(
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 92360603d942184e66e5f92706ecc75c6b04f121)
+++ src/ResolvExpr/ConversionCost.cc	(revision 74b007ba1f2facc85656ade19a8bab1d56bb0a82)
@@ -77,5 +77,5 @@
 
 	Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
-		std::cerr << "convert to reference cost..." << std::endl;
+		// std::cerr << "convert to reference cost..." << std::endl;
 		if ( diff > 0 ) {
 			// TODO: document this
@@ -92,5 +92,5 @@
 			ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
 			if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
-				std::cerr << "converting between references" << std::endl;
+				// std::cerr << "converting between references" << std::endl;
 				if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
 					return Cost::safe;
@@ -104,5 +104,5 @@
 				} // if
 			} else {
-				std::cerr << "reference to rvalue conversion" << std::endl;
+				// std::cerr << "reference to rvalue conversion" << std::endl;
 				ConversionCost converter( dest, indexer, env );
 				src->accept( converter );
@@ -113,7 +113,7 @@
 			assert( diff == -1 && destAsRef );
 			if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
-				std::cerr << "converting compatible base type" << std::endl;
+				// std::cerr << "converting compatible base type" << std::endl;
 				if ( src->get_lvalue() ) {
-					std::cerr << "lvalue to reference conversion" << std::endl;
+					// std::cerr << "lvalue to reference conversion" << std::endl;
 					// lvalue-to-reference conversion:  cv lvalue T => cv T &
 					if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) {
@@ -125,5 +125,5 @@
 					} // if
 				} else if ( destAsRef->get_base()->get_const() ) {
-					std::cerr << "rvalue to const ref conversion" << std::endl;
+					// std::cerr << "rvalue to const ref conversion" << std::endl;
 					// rvalue-to-const-reference conversion: T => const T &
 					return Cost::safe;
@@ -134,5 +134,5 @@
 				} // if
 			} // if
-			std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl;
+			// std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl;
 		}
 		return Cost::infinity;
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 92360603d942184e66e5f92706ecc75c6b04f121)
+++ src/SymTab/Autogen.cc	(revision 74b007ba1f2facc85656ade19a8bab1d56bb0a82)
@@ -156,13 +156,4 @@
 	}
 
-	/// true if the aggregate's layout is dynamic
-	template< typename AggrDecl >
-	bool hasDynamicLayout( AggrDecl * aggregateDecl ) {
-		for ( TypeDecl * param : aggregateDecl->get_parameters() ) {
-			if ( param->isComplete() ) return true;
-		}
-		return false;
-	}
-
 	/// generate a function decl from a name and type. Nesting depth determines whether
 	/// the declaration is static or not; optional paramter determines if declaration is intrinsic
@@ -310,5 +301,5 @@
 
 	/// generates a single struct member operation (constructor call, destructor call, assignment call)
-	void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
+	void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ) {
 		InitTweak::InitExpander srcParam( src );
 
@@ -320,5 +311,5 @@
 	/// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies
 	template<typename Iterator>
-	void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
+	void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ) {
 		for ( ; member != end; ++member ) {
 			if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
@@ -356,5 +347,5 @@
 
 				Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
-				makeStructMemberOp( dstParam, srcselect, field, func, isDynamicLayout, forward );
+				makeStructMemberOp( dstParam, srcselect, field, func, forward );
 			} // if
 		} // for
@@ -364,5 +355,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, bool isDynamicLayout ) {
+	void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) {
 		FunctionType * ftype = func->get_functionType();
 		std::list<DeclarationWithType*> & params = ftype->get_parameters();
@@ -390,9 +381,9 @@
 					// matching parameter, initialize field with copy ctor
 					Expression *srcselect = new VariableExpr(*parameter);
-					makeStructMemberOp( dstParam, srcselect, field, func, isDynamicLayout );
+					makeStructMemberOp( dstParam, srcselect, field, func );
 					++parameter;
 				} else {
 					// no matching parameter, initialize field with default ctor
-					makeStructMemberOp( dstParam, NULL, field, func, isDynamicLayout );
+					makeStructMemberOp( dstParam, NULL, field, func );
 				}
 			}
@@ -410,5 +401,4 @@
 		// Make function polymorphic in same parameters as generic struct, if applicable
 		const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
-		bool isDynamicLayout = hasDynamicLayout( aggregateDecl );  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
 
 		// generate each of the functions based on the supplied FuncData objects
@@ -436,7 +426,7 @@
 			// destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
 			if ( ! CodeGen::isDestructor( dcl->get_name() ) ) {
-				makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout );
+				makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl );
 			} else {
-				makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false );
+				makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, false );
 			}
 			if ( CodeGen::isAssignment( dcl->get_name() ) ) {
@@ -474,5 +464,5 @@
 				memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), Type::StorageClasses(), LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
 				FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
-				makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, isDynamicLayout );
+				makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor );
 				declsToAdd.push_back( ctor );
 			}
