Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision f6aa89cedbf067f470de7318a0b73c33e7624bb7)
+++ src/GenPoly/Box.cc	(revision 7ed7b4a80c819b4f40dcf617aefc52c4682f81bc)
@@ -99,13 +99,26 @@
 			void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
 			/// wraps a function application with a new temporary for the out-parameter return value
-			Expression *addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg );
+			Expression *addRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *retType );
 			/// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
-			Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg );
-			Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
-			void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
-			void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
-			void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
+			Expression *addDynRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *polyType );
+			/// Converts a function call into a call of the adapter with the
+			/// original function as the first argument (all other arguments
+			/// are pushed back). May adjust return value.
+			Expression *applyAdapter( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars );
+			/// Modifies the `arg`, replacing it with a boxed expression
+			/// that matches `formal` under the current TyVarMap.
+			void boxParam( Expression *&arg, Type *formal, const TyVarMap &exprTyVars );
+			/// Box an argument of `appExpr` for each parameter in `function`
+			/// starting at `arg`.
+			/// `exprTyVars` is the function's type variables.
+			void boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars );
+			/// Boxes each assertion and inserts them into `appExpr` at
+			/// `arg`. `exprTyVars` is the function's type variables.
+			void addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars );
 			/// Stores assignment operators from assertion list in local map of assignment operations
 			void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
+			/// Creates an adapter definition from `adaptee` to `realType`, using
+			/// `mangleName` as the base name for the adapter. `tyVars` is the map of
+			/// type variables for the function type of the adapted expression.
 			FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
 			/// Replaces intrinsic operator functions with their arithmetic desugaring
@@ -590,5 +603,5 @@
 		}
 
-		Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg ) {
+		Expression *Pass1::addRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *retType ) {
 			// Create temporary to hold return value of polymorphic function and produce that temporary as a result
 			// using a comma expression.
@@ -630,4 +643,5 @@
 		// See forward definition.
 		Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone ) {
+			assert( env );
 			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
 				Type *concrete = env->lookup( typeInst->get_name() );
@@ -652,16 +666,15 @@
 		}
 
-		Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) {
-			assert( env );
+		Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *dynType ) {
 			Type *concrete = replaceWithConcrete( dynType, env );
 			// add out-parameter for return value
-			return addRetParam( appExpr, concrete, arg );
-		}
-
-		Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
+			return addRetParam( appExpr, arg, concrete );
+		}
+
+		Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &tyVars ) {
 			Expression *ret = appExpr;
 //			if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
 			if ( isDynRet( function, tyVars ) ) {
-				ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg );
+				ret = addRetParam( appExpr, arg, function->returnVals.front()->get_type() );
 			} // if
 			std::string mangleName = mangleAdapterName( function, tyVars );
@@ -709,5 +722,5 @@
 		}
 
-		void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
+		void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) {
 			assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
 			addCast( arg, param, exprTyVars );
@@ -722,5 +735,5 @@
 				// 	}
 				// }
-				arg =  generalizedLvalue( new AddressExpr( arg ) );
+				arg = generalizedLvalue( new AddressExpr( arg ) );
 				if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
 					// silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
@@ -731,8 +744,10 @@
 				Type * newType = param->clone();
 				if ( env ) env->apply( newType );
-				ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );
-				newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
-				stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
-				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
+				ObjectDecl *newObj = makeTemporary( newType );
+				// TODO: is this right??? (Why wouldn't it be?)
+				newObj->get_type()->get_qualifiers() = Type::Qualifiers();
+				// TODO: why doesn't this just use initialization syntax?
+				// (Possibly to ensure code is run at the right time.)
+				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
 				assign->get_args().push_back( new VariableExpr( newObj ) );
 				assign->get_args().push_back( arg );
@@ -742,13 +757,13 @@
 		}
 
-		void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
+		void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) {
 			for ( DeclarationWithType * param : function->parameters ) {
 				assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
-				boxParam( param->get_type(), *arg, exprTyVars );
+				boxParam( *arg, param->get_type(), exprTyVars );
 				++arg;
 			} // for
 		}
 
-		void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
+		void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {
 			std::list< Expression *>::iterator cur = arg;
 			for ( TypeDecl * const tyVar : functionType->forall ) {
@@ -757,5 +772,5 @@
 					assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() );
 					Expression *newExpr = inferParam->second.expr->clone();
-					boxParam( assert->get_type(), newExpr, tyVars );
+					boxParam( newExpr, assert->get_type(), tyVars );
 					appExpr->get_args().insert( cur, newExpr );
 				} // for
@@ -1104,5 +1119,5 @@
 				// std::cerr << "dynRetType: " << dynRetType << std::endl;
 				Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
-				ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
+				ret = addDynRetParam( appExpr, arg, concRetType ); // xxx - used to use dynRetType instead of concRetType
 			} else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...?
 				// xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed.
@@ -1112,5 +1127,5 @@
 				// std::cerr << *env << std::endl;
 				// change the application so it calls the adapter rather than the passed function
-				ret = applyAdapter( appExpr, function, arg, scopeTyVars );
+				ret = applyAdapter( appExpr, arg, function, scopeTyVars );
 			} // if
 			arg = appExpr->get_args().begin();
@@ -1118,9 +1133,9 @@
 			Type *concRetType = replaceWithConcrete( dynRetType, env );
 			passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)
-			addInferredParams( appExpr, function, arg, exprTyVars );
+			addInferredParams( appExpr, arg, function, exprTyVars );
 
 			arg = paramBegin;
 
-			boxParams( appExpr, function, arg, exprTyVars );
+			boxParams( appExpr, arg, function, exprTyVars );
 			passAdapters( appExpr, function, exprTyVars );
 
