Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 3aeaecd045fc36d8a618c00f85faaf42de32c104)
+++ src/InitTweak/FixInit.cc	(revision 696bf6e3935621cd7858ed21fbc4288c10b2dafb)
@@ -242,11 +242,9 @@
 		};
 
-		class FixCtorExprs final : public GenPoly::DeclMutator {
-		  public:
+		struct FixCtorExprs final : public WithDeclsToAdd, public WithIndexer {
 			/// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
 			static void fix( std::list< Declaration * > & translationUnit );
 
-			using GenPoly::DeclMutator::mutate;
-			virtual Expression * mutate( ConstructorExpr * ctorExpr ) override;
+			Expression * postmutate( ConstructorExpr * ctorExpr );
 		};
 	} // namespace
@@ -325,6 +323,6 @@
 
 		void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
-			FixCtorExprs fixer;
-			fixer.mutateDeclarationList( translationUnit );
+			PassVisitor<FixCtorExprs> fixer;
+			mutateAll( translationUnit, fixer );
 		}
 
@@ -1146,5 +1144,5 @@
 		}
 
-		Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
+		Expression * FixCtorExprs::postmutate( ConstructorExpr * ctorExpr ) {
 			static UniqueName tempNamer( "_tmp_ctor_expr" );
 			// xxx - is the size check necessary?
@@ -1153,5 +1151,5 @@
 			// xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
 			ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );
-			addDeclaration( tmp );
+			declsToAddBefore.push_back( tmp );
 
 			// xxx - this can be TupleAssignExpr now. Need to properly handle this case.
@@ -1162,26 +1160,14 @@
 			delete ctorExpr;
 
+			// build assignment and replace constructor's first argument with new temporary
 			Expression *& firstArg = callExpr->get_args().front();
-
-			// xxx - hack in 'fake' assignment operator until resolver can easily be called in this pass. Once the resolver can be used in PassVisitor, this hack goes away.
-
-			// generate the type of assignment operator using the type of tmp minus any reference types
-			Type * type = tmp->get_type()->stripReferences();
-			FunctionType * ftype = SymTab::genAssignType( type );
-
-			// generate fake assignment decl and call it using &tmp and &firstArg
-			// since tmp is guaranteed to be a reference and we want to assign pointers
-			FunctionDecl * assignDecl = new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Intrinsic, ftype, nullptr );
-			ApplicationExpr * assign = new ApplicationExpr( VariableExpr::functionPointer( assignDecl ) );
-			assign->get_args().push_back( new AddressExpr( new VariableExpr( tmp ) ) );
-			Expression * addrArg = new AddressExpr( firstArg );
-			// if firstArg has type T&&, then &firstArg has type T*&.
-			// Cast away the reference to a value type so that the argument
-			// matches the assignment's parameter types
-			if ( dynamic_cast<ReferenceType *>( addrArg->get_result() ) ) {
-				addrArg = new CastExpr( addrArg, addrArg->get_result()->stripReferences()->clone() );
-			}
-			assign->get_args().push_back( addrArg );
+			Expression * assign = new UntypedExpr( new NameExpr( "?=?" ), { new AddressExpr( new VariableExpr( tmp ) ), new AddressExpr( firstArg ) } );
 			firstArg = new VariableExpr( tmp );
+
+			// resolve assignment and dispose of new env
+			Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );
+			delete resolvedAssign->env;
+			resolvedAssign->env = nullptr;
+			delete assign;
 
 			// for constructor expr:
@@ -1192,5 +1178,5 @@
 			//   T & tmp;
 			//   &tmp = &x, ?{}(tmp), tmp
-			CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
+			CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
 			commaExpr->set_env( env );
 			return commaExpr;
