Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision d8ba08645e3a1d872799a07b1bf581390d8798ce)
+++ src/GenPoly/Box.cc	(revision 540de412b77591cc4fdbb16932060ef6229a3f1d)
@@ -10,5 +10,5 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Apr 29 12:16:11 2016
+// Last Modified On : Mon May 02 14:49:01 2016
 // Update Count     : 295
 //
@@ -785,5 +785,5 @@
 					} else {
 						/// xxx - should this be an assertion?
-						throw SemanticError( "unbound type variable in application ", appExpr );
+						throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr );
 					} // if
 				} // if
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision d8ba08645e3a1d872799a07b1bf581390d8798ce)
+++ src/GenPoly/GenPoly.cc	(revision 540de412b77591cc4fdbb16932060ef6229a3f1d)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// GenPoly.cc -- 
+// GenPoly.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 15 16:11:18 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon May 02 14:53:33 2016
 // Update Count     : 13
 //
@@ -81,5 +81,5 @@
 		return 0;
 	}
-	
+
 	Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
@@ -112,5 +112,5 @@
 		return 0;
 	}
-	
+
 	Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
 		if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
@@ -146,5 +146,5 @@
 		return isPolyType( type, env );
 	}
-	
+
 	Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
 		int dummy;
@@ -192,4 +192,8 @@
 				if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
 				expr = *untypedExpr->begin_args();
+			} else if ( CommaExpr *commaExpr = dynamic_cast< CommaExpr* >( expr ) ) {
+				// copy constructors insert comma exprs, look at second argument which contains the variable
+				expr = commaExpr->get_arg2();
+				continue;
 			} else break;
 
@@ -209,5 +213,5 @@
 		}
 	}
-	
+
 	void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
 		for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
Index: src/GenPoly/PolyMutator.cc
===================================================================
--- src/GenPoly/PolyMutator.cc	(revision d8ba08645e3a1d872799a07b1bf581390d8798ce)
+++ src/GenPoly/PolyMutator.cc	(revision 540de412b77591cc4fdbb16932060ef6229a3f1d)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// PolyMutator.cc -- 
+// PolyMutator.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Aug 14 15:28:50 2015
+// Last Modified On : Mon May 02 14:50:58 2016
 // Update Count     : 11
 //
@@ -63,4 +63,5 @@
 				env = expr->get_env();
 			}
+			// xxx - should env be cloned (or moved) onto the result of the mutate?
 			return expr->acceptMutator( *this );
 		} else {
@@ -144,6 +145,6 @@
 		return untypedExpr;
 	}
- 
- 
+
+
 	Initializer *PolyMutator::mutate( SingleInit *singleInit ) {
 		singleInit->set_value( mutateExpression( singleInit->get_value() ) );
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision d8ba08645e3a1d872799a07b1bf581390d8798ce)
+++ src/InitTweak/FixInit.cc	(revision 540de412b77591cc4fdbb16932060ef6229a3f1d)
@@ -10,5 +10,5 @@
 // Created On       : Wed Jan 13 16:29:30 2016
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Apr 29 12:25:40 2016
+// Last Modified On : Mon May 02 14:57:45 2016
 // Update Count     : 30
 //
@@ -61,4 +61,6 @@
 		/// true if type does not need to be copy constructed to ensure correctness
 		bool skipCopyConstruct( Type * );
+	private:
+		TypeSubstitution * env;
 	};
 
@@ -151,13 +153,14 @@
 		// wrap each function call so that it is easy to identify nodes that have to be copy constructed
 		ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr );
-		// save a copy of the type substitution onto the new node so that it is easy to find.
+		// save the type substitution onto the new node so that it is easy to find.
+		// Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion.
 		// The substitution is needed to obtain the type of temporary variables so that copy constructor
 		// calls can be resolved. Normally this is what PolyMutator is for, but the pass that resolves
 		// copy constructor calls must be an Indexer. We could alternatively make a PolyIndexer which
-		// saves the environment, or compute the types of temporaries here, but it's more simpler to
+		// saves the environment, or compute the types of temporaries here, but it's much simpler to
 		// save the environment here, and more cohesive to compute temporary variables and resolve copy
 		// constructor calls together.
 		assert( env );
-		expr->set_env( env->clone() );
+		expr->set_env( env );
 		return expr;
 	}
@@ -178,4 +181,7 @@
 		PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
 		ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
+		if ( resolved->get_env() ) {
+			env->add( *resolved->get_env() );
+		}
 
 		assert( resolved );
@@ -190,4 +196,5 @@
 		PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
 		Visitor::visit( impCpCtorExpr );
+		env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer...
 
 		ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
@@ -246,5 +253,4 @@
 		PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
 
-		// assert( impCpCtorExpr->get_callExpr()->get_env() );
 		impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) );
 		assert( impCpCtorExpr );
@@ -278,4 +284,5 @@
 		returnDecls.clear();
 		impCpCtorExpr->set_callExpr( NULL );
+		impCpCtorExpr->set_env( NULL );
 		delete impCpCtorExpr;
 
@@ -311,4 +318,6 @@
 				retExpr = deref;
 			}
+			// xxx - might need to set env on retExpr...
+			// retExpr->set_env( env->clone() );
 			return retExpr;
 		} else {
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision d8ba08645e3a1d872799a07b1bf581390d8798ce)
+++ src/SynTree/TypeSubstitution.h	(revision 540de412b77591cc4fdbb16932060ef6229a3f1d)
@@ -10,5 +10,5 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Apr 29 13:50:09 2016
+// Last Modified On : Fri Apr 29 15:00:20 2016
 // Update Count     : 2
 //
@@ -48,4 +48,5 @@
 	void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
 
+	/// this function is unused...
 	template< typename TypeInstListIterator >
 	void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
