Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 579263a52ab065d42a5208e15e3d707dd0d03798)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
@@ -809,4 +809,30 @@
 	}
 
+	Expression * restructureCast( Expression * argExpr, Type * toType ) {
+		if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
+			// Argument expression is a tuple and the target type is not void. Cast each member of the tuple
+			// to its corresponding target type, producing the tuple of those cast expressions. If there are
+			// more components of the tuple than components in the target type, then excess components do not
+			// come out in the result expression (but UniqueExprs ensure that side effects will still be done).
+			if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
+				// expressions which may contain side effects require a single unique instance of the expression.
+				argExpr = new UniqueExpr( argExpr );
+			}
+			std::list< Expression * > componentExprs;
+			for ( unsigned int i = 0; i < toType->size(); i++ ) {
+				// cast each component
+				TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
+				componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) );
+			}
+			delete argExpr;
+			assert( componentExprs.size() > 0 );
+			// produce the tuple of casts
+			return new TupleExpr( componentExprs );
+		} else {
+			// handle normally
+			return new CastExpr( argExpr, toType->clone() );
+		}
+	}
+
 	void AlternativeFinder::visit( CastExpr *castExpr ) {
 		Type *& toType = castExpr->get_result();
@@ -840,28 +866,5 @@
 				thisCost += Cost( 0, 0, discardedValues );
 
-				Expression * argExpr = i->expr->clone();
-				if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) {
-					// Argument expression is a tuple and the target type is not void. Cast each member of the tuple
-					// to its corresponding target type, producing the tuple of those cast expressions. If there are
-					// more components of the tuple than components in the target type, then excess components do not
-					// come out in the result expression (but UniqueExprs ensure that side effects will still be done).
-					if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
-						// expressions which may contain side effects require a single unique instance of the expression.
-						argExpr = new UniqueExpr( argExpr );
-					}
-					std::list< Expression * > componentExprs;
-					for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) {
-						// cast each component
-						TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
-						componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) );
-					}
-					delete argExpr;
-					assert( componentExprs.size() > 0 );
-					// produce the tuple of casts
-					candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) );
-				} else {
-					// handle normally
-					candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) );
-				}
+				candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
 			} // if
 		} // for
@@ -1183,31 +1186,39 @@
 
 	void AlternativeFinder::visit( UntypedInitExpr *initExpr ) {
-		AlternativeFinder finder( indexer, env );
-		finder.findWithAdjustment( initExpr->get_expr() );
-		// handle each option like a cast -- should probably push this info into AltFinder as a kind of expression, both to keep common code close and to have less 'reach-in', but more 'push-in'
+		// handle each option like a cast
 		AltList candidates;
-		std::cerr << "untyped init expr: " << initExpr << std::endl;
+		PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; )
 		// O(N^2) checks of d-types with e-types
-		for ( Alternative & alt : finder.get_alternatives() ) {
-			for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
+		for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
+			Type * toType = resolveTypeof( initAlt.type, indexer );
+			SymTab::validateType( toType, &indexer );
+			adjustExprType( toType, env, indexer );
+			// Ideally the call to findWithAdjustment could be moved out of the loop, but unfortunately it currently has to occur inside or else
+			// polymorphic return types are not properly bound to the initialization type, since return type variables are only open for the duration of resolving
+			// the UntypedExpr. This is only actually an issue in initialization contexts that allow more than one possible initialization type, but it is still suboptimal.
+			AlternativeFinder finder( indexer, env );
+			finder.targetType = toType;
+			finder.findWithAdjustment( initExpr->get_expr() );
+			for ( Alternative & alt : finder.get_alternatives() ) {
+				TypeEnvironment newEnv( alt.env );
 				AssertionSet needAssertions, haveAssertions;
-				OpenVarSet openVars;
-				std::cerr << "  " << initAlt.type << " " << initAlt.designation << std::endl;
+				OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
+				PRINT( std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl; )
 				// It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
 				// cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
 				// that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
 				// to.
-				int discardedValues = alt.expr->get_result()->size() - initAlt.type->size();
+				int discardedValues = alt.expr->get_result()->size() - toType->size();
 				if ( discardedValues < 0 ) continue;
 				// xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
 				// allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
 				// unification run for side-effects
-				unify( initAlt.type, alt.expr->get_result(), alt.env, needAssertions, haveAssertions, openVars, indexer );
-
-				Cost thisCost = castCost( alt.expr->get_result(), initAlt.type, indexer, alt.env );
+				unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
+
+				Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv );
 				if ( thisCost != Cost::infinity ) {
 					// count one safe conversion for each value that is thrown away
 					thisCost += Cost( 0, 0, discardedValues );
-					candidates.push_back( Alternative( new InitExpr( alt.expr->clone(), initAlt.type->clone(), initAlt.designation->clone() ), alt.env, alt.cost, thisCost ) );
+					candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
 				}
 			}
Index: src/ResolvExpr/CurrentObject.cc
===================================================================
--- src/ResolvExpr/CurrentObject.cc	(revision 579263a52ab065d42a5208e15e3d707dd0d03798)
+++ src/ResolvExpr/CurrentObject.cc	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
@@ -22,4 +22,5 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Type.h"
+#include "SynTree/TypeSubstitution.h"
 
 #if 0
@@ -32,12 +33,15 @@
 	long long int getConstValue( ConstantExpr * constExpr ) {
 		if ( BasicType * basicType = dynamic_cast< BasicType * >( constExpr->get_result() ) ) {
-			if ( basicType->get_kind() == BasicType::Char || basicType->get_kind() == BasicType::SignedChar || basicType->get_kind() == BasicType::UnsignedChar ) {
-				assertf( constExpr->get_constant()->get_value().size() == 3, "constant value with unusual length: %s", constExpr->get_constant()->get_value().c_str() );
-				return constExpr->get_constant()->get_value()[1];
+			if ( basicType->isInteger() ) {
+				return constExpr->get_constant()->get_ival();
 			} else {
-				return stoll( constExpr->get_constant()->get_value() );
-			}
+				assertf( false, "Non-integer constant expression in getConstValue", toString( constExpr ).c_str() ); // xxx - might be semantic error
+			}
+		} else if ( dynamic_cast< OneType * >( constExpr->get_result() ) ) {
+			return 1;
+		} else if ( dynamic_cast< ZeroType * >( constExpr->get_result() ) ) {
+			return 0;
 		} else {
-			assertf( false, "unhandled type on getConstValue %s", constExpr->get_result() );
+			assertf( false, "unhandled type on getConstValue %s", toString( constExpr->get_result() ).c_str() ); // xxx - might be semantic error
 		}
 	}
@@ -56,4 +60,24 @@
 	std::ostream & operator<<( std::ostream & out, Indenter & indent ) {
 		return out << std::string(indent.indent, ' ');
+	}
+
+	template< typename AggrInst >
+	TypeSubstitution makeGenericSubstitution( AggrInst * inst ) {
+		assert( inst );
+		assert( inst->get_baseParameters() );
+		std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
+		std::list< Expression * > typeSubs = inst->get_parameters();
+		TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
+		return subs;
+	}
+
+	TypeSubstitution makeGenericSubstitution( Type * type ) {
+		if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {
+			return makeGenericSubstitution( inst );
+		} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {
+			return makeGenericSubstitution( inst );
+		} else {
+			return TypeSubstitution();
+		}
 	}
 
@@ -135,10 +159,10 @@
 		void setSize( Expression * expr ) {
 			if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
-				size = getConstValue( constExpr ); // xxx - if not a constant expression, it's not simple to determine how long the array actually is, which is necessary for initialization to be done correctly -- fix this
+				size = getConstValue( constExpr );
 				PRINT( std::cerr << "array type with size: " << size << std::endl; )
 			}	else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
-				setSize( castExpr->get_arg() );
+				setSize( castExpr->get_arg() ); // xxx - need to perform the conversion specified by the cast
 			} else {
-				assertf( false, "unhandled expression in setSize: %s", toString( expr ).c_str() );
+				assertf( false, "unhandled expression in setSize: %s", toString( expr ).c_str() ); // xxx - if not a constant expression, it's not simple to determine how long the array actually is, which is necessary for initialization to be done correctly -- fix this
 			}
 		}
@@ -231,14 +255,17 @@
 	class AggregateIterator : public MemberIterator {
 	public:
-		typedef std::list<Declaration *>::iterator iterator;
-		const char * kind = ""; // for debug
-		ReferenceToType * inst = nullptr;
-		AggregateDecl * decl = nullptr;
+		typedef std::list<Declaration *> MemberList;
+		typedef MemberList::const_iterator iterator;
+		std::string kind = ""; // for debug
+		std::string name;
+		Type * inst = nullptr;
+		const MemberList & members;
 		iterator curMember;
-		bool atbegin = true; // false at first {small,big}Step -- this struct type is only added to the possibilities at the beginning
+		bool atbegin = true; // false at first {small,big}Step -- this aggr type is only added to the possibilities at the beginning
 		Type * curType = nullptr;
 		MemberIterator * memberIter = nullptr;
-
-		AggregateIterator( const char * kind, ReferenceToType * inst, AggregateDecl * decl ) : kind( kind ), inst( inst ), decl( decl ), curMember( decl->get_members().begin() ) {
+		mutable TypeSubstitution sub;
+
+		AggregateIterator( const std::string & kind, const std::string & name, Type * inst, const MemberList & members ) : kind( kind ), name( name ), inst( inst ), members( members ), curMember( members.begin() ), sub( makeGenericSubstitution( inst ) ) {
 			init();
 		}
@@ -249,6 +276,6 @@
 
 		bool init() {
-			PRINT( std::cerr << "--init()--" << std::endl; )
-			if ( curMember != decl->get_members().end() ) {
+			PRINT( std::cerr << "--init()--" << members.size() << std::endl; )
+			if ( curMember != members.end() ) {
 				if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( *curMember ) ) {
 					PRINT( std::cerr << "incremented to field: " << field << std::endl; )
@@ -264,7 +291,12 @@
 			if (memberIter && *memberIter) {
 				std::list<InitAlternative> ret = memberIter->first();
+				PRINT( std::cerr << "sub: " << sub << std::endl; )
 				for ( InitAlternative & alt : ret ) {
 					PRINT( std::cerr << "iterating and adding designators" << std::endl; )
 					alt.designation->get_designators().push_front( new VariableExpr( safe_dynamic_cast< ObjectDecl * >( *curMember ) ) );
+					// need to substitute for generic types, so that casts are to concrete types
+					PRINT( std::cerr << "  type is: " << alt.type; )
+					sub.apply( alt.type ); // also apply to designation??
+					PRINT( std::cerr << " ==> " << alt.type << std::endl; )
 				}
 				return ret;
@@ -276,5 +308,5 @@
 			if ( ! designators.empty() ) {
 				if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( designators.front() ) ) {
-					for ( curMember = decl->get_members().begin(); curMember != decl->get_members().end(); ++curMember ) {
+					for ( curMember = members.begin(); curMember != members.end(); ++curMember ) {
 						if ( *curMember == varExpr->get_var() ) {
 							designators.pop_front();
@@ -282,12 +314,12 @@
 							memberIter = createMemberIterator( varExpr->get_result() );
 							curType = varExpr->get_result();
-							atbegin = curMember == decl->get_members().begin() && designators.empty(); // xxx - is this right??
+							atbegin = curMember == members.begin() && designators.empty(); // xxx - is this the right condition for atbegin??
 							memberIter->setPosition( designators );
 							return;
 						} // if
 					} // for
-					assertf( false, "could not find member in %s: %s", kind, toString( varExpr ).c_str() );
+					assertf( false, "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
 				} else {
-					assertf( false, "bad designator given to %s: %s", kind, toString( designators.front() ).c_str() );
+					assertf( false, "bad designator given to %s: %s", kind.c_str(), toString( designators.front() ).c_str() );
 				} // if
 			} // if
@@ -336,5 +368,5 @@
 
 		virtual void print( std::ostream & out, Indenter indent ) const {
-			out << kind << "(" << decl->get_name() << ")";
+			out << kind << "(" << name << ")";
 			if ( memberIter ) {
 				Indenter childIndent = indent+1;
@@ -347,5 +379,5 @@
 	class UnionIterator : public AggregateIterator {
 	public:
-		UnionIterator( UnionInstType * inst ) : AggregateIterator( "UnionIterator", inst, inst->get_baseUnion() ) {}
+		UnionIterator( UnionInstType * inst ) : AggregateIterator( "UnionIterator", inst->get_name(), inst, inst->get_baseUnion()->get_members() ) {}
 
 		virtual operator bool() const { return (memberIter && *memberIter); }
@@ -357,5 +389,5 @@
 			memberIter = nullptr;
 			curType = nullptr;
-			curMember = decl->get_members().end();
+			curMember = members.end();
 			return *this;
 		}
@@ -365,7 +397,7 @@
 	class StructIterator : public AggregateIterator {
 	public:
-		StructIterator( StructInstType * inst ) : AggregateIterator( "StructIterator", inst, inst->get_baseStruct() ) {}
-
-		virtual operator bool() const { return curMember != decl->get_members().end() || (memberIter && *memberIter); }
+		StructIterator( StructInstType * inst ) : AggregateIterator( "StructIterator", inst->get_name(), inst, inst->get_baseStruct()->get_members() ) {}
+
+		virtual operator bool() const { return curMember != members.end() || (memberIter && *memberIter); }
 
 		virtual MemberIterator & bigStep() {
@@ -375,5 +407,27 @@
 			memberIter = nullptr;
 			curType = nullptr;
-			for ( ; curMember != decl->get_members().end(); ) {
+			for ( ; curMember != members.end(); ) {
+				++curMember;
+				if ( init() ) {
+					return *this;
+				}
+			}
+			return *this;
+		}
+	};
+
+	class TupleIterator : public AggregateIterator {
+	public:
+		TupleIterator( TupleType * inst ) : AggregateIterator( "TupleIterator", toString("Tuple", inst->size()), inst, inst->get_members() ) {}
+
+		virtual operator bool() const { return curMember != members.end() || (memberIter && *memberIter); }
+
+		virtual MemberIterator & bigStep() {
+			PRINT( std::cerr << "bigStep in " << kind << std::endl; )
+			atbegin = false;
+			delete memberIter;
+			memberIter = nullptr;
+			curType = nullptr;
+			for ( ; curMember != members.end(); ) {
 				++curMember;
 				if ( init() ) {
@@ -392,8 +446,11 @@
 				return new UnionIterator( uit );
 			} else {
-				assertf( false, "some other reftotype" );
+				assertf( dynamic_cast< TypeInstType * >( type ), "some other reftotype" );
+				return new SimpleIterator( type );
 			}
 		} else if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
 			return new ArrayIterator( at );
+		} else if ( TupleType * tt = dynamic_cast< TupleType * >( type ) ) {
+			return new TupleIterator( tt );
 		} else {
 			return new SimpleIterator( type );
@@ -494,5 +551,4 @@
 		Type * type = objStack.top()->getNext();
 		if ( type ) {
-			// xxx - record types.front()?
 			objStack.push( createMemberIterator( type ) );
 		} else {
@@ -517,4 +573,10 @@
 		return **objStack.top();
 	}
+
+	Type * CurrentObject::getCurrentType() {
+		PRINT( std::cerr << "____getting current type" << std::endl; )
+		assertf( ! objStack.empty(), "objstack empty in getCurrentType" );
+		return objStack.top()->getNext();
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/CurrentObject.h
===================================================================
--- src/ResolvExpr/CurrentObject.h	(revision 579263a52ab065d42a5208e15e3d707dd0d03798)
+++ src/ResolvExpr/CurrentObject.h	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
@@ -42,4 +42,6 @@
 		/// produces a list of alternatives (Type *, Designation *) for the current sub-object's initializer
 		std::list< InitAlternative > getOptions();
+		/// produces the type of the current object but no subobjects
+		Type * getCurrentType();
 
 	private:
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 579263a52ab065d42a5208e15e3d707dd0d03798)
+++ src/ResolvExpr/Resolver.cc	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
@@ -375,103 +375,54 @@
 	}
 
-	template< typename Aggr >
-	void lookupDesignation( Aggr * aggr, const std::list< Expression > & designators ) {
-
-	}
-
 	void Resolver::visit( SingleInit *singleInit ) {
+		// resolve initialization using the possibilities as determined by the currentObject cursor
 		UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
 		Expression * newExpr = findSingleExpression( untyped, *this );
 		InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
-		singleInit->set_value( new CastExpr( initExpr->get_expr()->clone(), initExpr->get_result()->clone() ) );
+
+		// move cursor to the object that is actually initialized
 		currentObject.setNext( initExpr->get_designation() );
+
+		// discard InitExpr wrapper and retain relevant pieces
+		newExpr = initExpr->get_expr();
+		singleInit->get_value()->set_env( initExpr->get_env() );
+		initExpr->set_expr( nullptr );
+		initExpr->set_env( nullptr );
+		delete initExpr;
+
+		// get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
+		Type * initContext = currentObject.getCurrentType();
+
+		// check if actual object's type is char[]
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
+			if ( isCharType( at->get_base() ) ) {
+				// check if the resolved type is char *
+				if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
+					if ( isCharType( pt->get_base() ) ) {
+						// strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
+						CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr );
+						newExpr = ce->get_arg();
+						ce->set_arg( nullptr );
+						delete ce;
+					}
+				}
+			}
+		}
+
+		// set initializer expr to resolved express
+		singleInit->set_value( newExpr );
+
+		// move cursor to next object in preparation for next initializer
 		currentObject.increment();
-		delete initExpr;
-
-		// // check if initializing type is char[]
-		// if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
-		// 	if ( isCharType( at->get_base() ) ) {
-		// 		// check if the resolved type is char *
-		// 		if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
-		// 			if ( isCharType( pt->get_base() ) ) {
-		// 				// strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
-		// 				CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
-		// 				singleInit->set_value( ce->get_arg() );
-		// 				ce->set_arg( NULL );
-		// 				delete ce;
-		// 			}
-		// 		}
-		// 	}
-		// }
-	}
-
-	// template< typename AggrInst >
-	// TypeSubstitution makeGenericSubstitution( AggrInst * inst ) {
-	// 	assert( inst );
-	// 	assert( inst->get_baseParameters() );
-	// 	std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
-	// 	std::list< Expression * > typeSubs = inst->get_parameters();
-	// 	TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
-	// 	return subs;
-	// }
-
-	// ReferenceToType * isStructOrUnion( Type * type ) {
-	// 	if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
-	// 		return sit;
-	// 	} else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
-	// 		return uit;
-	// 	}
-	// 	return nullptr;
-	// }
-
-	// void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
-	// 	ObjectDecl * obj = dynamic_cast< ObjectDecl * >( dcl );
-	// 	assert( obj );
-	// 	// need to substitute for generic types, so that casts are to concrete types
-	// 	currentObject = obj->clone();  // xxx - delete this
-	// 	sub.apply( currentObject );
-
-	// 	try {
-	// 		if ( init == initEnd ) return; // stop when there are no more initializers
-	// 		(*init)->accept( *this );
-	// 		++init; // made it past an initializer
-	// 	} catch( SemanticError & ) {
-	// 		// need to delve deeper, if you can
-	// 		if ( ReferenceToType * type = isStructOrUnion( currentObject->get_type() ) ) {
-	// 			resolveAggrInit( type, init, initEnd );
-	// 		} else {
-	// 			// member is not an aggregate type, so can't go any deeper
-
-	// 			// might need to rethink what is being thrown
-	// 			throw;
-	// 		} // if
-	// 	}
-	// }
-
-	// void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
-	// 	if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
-	// 		TypeSubstitution sub = makeGenericSubstitution( sit );
-	// 		StructDecl * st = sit->get_baseStruct();
-	// 		if(st->get_members().empty()) return;
-	// 		// want to resolve each initializer to the members of the struct,
-	// 		// but if there are more initializers than members we should stop
-	// 		list< Declaration * >::iterator it = st->get_members().begin();
-	// 		for ( ; it != st->get_members().end(); ++it) {
-	// 			resolveSingleAggrInit( *it, init, initEnd, sub );
-	// 		}
-	// 	} else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
-	// 		TypeSubstitution sub = makeGenericSubstitution( uit );
-	// 		UnionDecl * un = uit->get_baseUnion();
-	// 		if(un->get_members().empty()) return;
-	// 		// only resolve to the first member of a union
-	// 		resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
-	// 	} // if
-	// }
+	}
 
 	void Resolver::visit( ListInit * listInit ) {
+		// move cursor into brace-enclosed initializer-list
 		currentObject.enterListInit();
 		// xxx - fix this so that the list isn't copied, iterator should be used to change current element
 		std::list<Designation *> newDesignations;
 		for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
+			// iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving
+			// the initializer against that object.
 			Designation * des = std::get<0>(p);
 			Initializer * init = std::get<1>(p);
@@ -479,7 +430,9 @@
 			init->accept( *this );
 		}
+		// set the set of 'resolved' designations and leave the brace-enclosed initializer-list
 		listInit->get_designations() = newDesignations; // xxx - memory management
 		currentObject.exitListInit();
 
+		// xxx - this part has not be folded into CurrentObject yet
 		// } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
 		// 	Type * base = tt->get_baseType()->get_base();
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 579263a52ab065d42a5208e15e3d707dd0d03798)
+++ src/ResolvExpr/Unify.cc	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
@@ -606,8 +606,8 @@
 			} else if ( tupleParam ) {
 				// bundle other parameters into tuple to match
-				TupleType* binder = new TupleType{ paramTy->get_qualifiers() };
+				std::list< Type * > binderTypes;
 
 				do {
-					binder->get_types().push_back( otherParam->get_type()->clone() );
+					binderTypes.push_back( otherParam->get_type()->clone() );
 					++jt;
 
@@ -618,12 +618,12 @@
 				} while (true);
 
-				otherParamTy = binder;
+				otherParamTy = new TupleType{ paramTy->get_qualifiers(), binderTypes };
 				++it;  // skip ttype parameter for break
 			} else if ( otherTupleParam ) {
 				// bundle parameters into tuple to match other
-				TupleType* binder = new TupleType{ otherParamTy->get_qualifiers() };
+				std::list< Type * > binderTypes;
 
 				do {
-					binder->get_types().push_back( param->get_type()->clone() );
+					binderTypes.push_back( param->get_type()->clone() );
 					++it;
 
@@ -634,5 +634,5 @@
 				} while (true);
 
-				paramTy = binder;
+				paramTy = new TupleType{ otherParamTy->get_qualifiers(), binderTypes };
 				++jt;  // skip ttype parameter for break
 			}
@@ -756,9 +756,9 @@
 			return function->get_returnVals().front()->get_type()->clone();
 		} else {
-			TupleType * tupleType = new TupleType( Type::Qualifiers() );
+			std::list< Type * > types;
 			for ( DeclarationWithType * decl : function->get_returnVals() ) {
-				tupleType->get_types().push_back( decl->get_type()->clone() );
+				types.push_back( decl->get_type()->clone() );
 			} // for
-			return tupleType;
+			return new TupleType( Type::Qualifiers(), types );
 		}
 	}
