Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision be9aa0f1c85e356bf034f79d57aed3ad8de1a6c3)
+++ src/InitTweak/FixInit.cc	(revision b68382146bfc9aa68160d565370751e4f3074dd7)
@@ -197,5 +197,5 @@
 		};
 
-		struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer {
+		struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer, public WithVisitorRef<GenStructMemberCalls> {
 			/// generate default/copy ctor and dtor calls for user-defined struct ctor/dtors
 			/// for any member that is missing a corresponding ctor/dtor call.
@@ -203,9 +203,13 @@
 			static void generate( std::list< Declaration * > & translationUnit );
 
-			void previsit( FunctionDecl * funcDecl );
-			void postvisit( FunctionDecl * funcDecl );
-
-			void previsit( MemberExpr * memberExpr );
-			void previsit( ApplicationExpr * appExpr );
+			void premutate( FunctionDecl * funcDecl );
+			DeclarationWithType * postmutate( FunctionDecl * funcDecl );
+
+			void premutate( MemberExpr * memberExpr );
+			void premutate( ApplicationExpr * appExpr );
+
+			/// Note: this post mutate used to be in a separate visitor. If this pass breaks, one place to examine is whether it is
+			/// okay for this part of the recursion to occur alongside the rest.
+			Expression * postmutate( UntypedExpr * expr );
 
 			SemanticError errors;
@@ -220,19 +224,4 @@
 			bool isCtor = false; // true if current function is a constructor
 			StructDecl * structDecl = nullptr;
-		};
-
-		// very simple resolver-like mutator class - used to
-		// resolve UntypedExprs that are found within newly
-		// generated constructor/destructor calls
-		class MutatingResolver final : public Mutator {
-		  public:
-			MutatingResolver( SymTab::Indexer & indexer ) : indexer( indexer ) {}
-
-			using Mutator::mutate;
-			virtual DeclarationWithType* mutate( ObjectDecl *objectDecl ) override;
-			virtual Expression* mutate( UntypedExpr *untypedExpr ) override;
-
-		  private:
-			SymTab::Indexer & indexer;
 		};
 
@@ -315,5 +304,5 @@
 		void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) {
 			PassVisitor<GenStructMemberCalls> warner;
-			acceptAll( translationUnit, warner );
+			mutateAll( translationUnit, warner );
 		}
 
@@ -950,5 +939,5 @@
 		}
 
-		void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) {
+		void GenStructMemberCalls::premutate( FunctionDecl * funcDecl ) {
 			GuardValue( function );
 			GuardValue( unhandled );
@@ -984,5 +973,5 @@
 		}
 
-		void GenStructMemberCalls::postvisit( FunctionDecl * funcDecl ) {
+		DeclarationWithType * GenStructMemberCalls::postmutate( FunctionDecl * funcDecl ) {
 			// remove the unhandled objects from usedUninit, because a call is inserted
 			// to handle them - only objects that are later constructed are used uninitialized.
@@ -1038,7 +1027,6 @@
 						Statement * callStmt = stmt.front();
 
-						MutatingResolver resolver( indexer );
 						try {
-							callStmt->acceptMutator( resolver );
+							callStmt->acceptMutator( *visitor );
 							if ( isCtor ) {
 								function->get_statements()->push_front( callStmt );
@@ -1056,4 +1044,5 @@
 				throw errors;
 			}
+			return funcDecl;
 		}
 
@@ -1081,5 +1070,5 @@
 		}
 
-		void GenStructMemberCalls::previsit( ApplicationExpr * appExpr ) {
+		void GenStructMemberCalls::premutate( ApplicationExpr * appExpr ) {
 			if ( ! checkWarnings( function ) ) {
 				visit_children = false;
@@ -1106,5 +1095,5 @@
 		}
 
-		void GenStructMemberCalls::previsit( MemberExpr * memberExpr ) {
+		void GenStructMemberCalls::premutate( MemberExpr * memberExpr ) {
 			if ( ! checkWarnings( function ) || ! isCtor ) {
 				visit_children = false;
@@ -1134,13 +1123,5 @@
 		}
 
-		DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) {
-			// add object to the indexer assumes that there will be no name collisions
-			// in generated code. If this changes, add mutate methods for entities with
-			// scope and call {enter,leave}Scope explicitly.
-			indexer.addId( objectDecl );
-			return objectDecl;
-		}
-
-		Expression * MutatingResolver::mutate( UntypedExpr * untypedExpr ) {
+		Expression * GenStructMemberCalls::postmutate( UntypedExpr * untypedExpr ) {
 			Expression * newExpr = untypedExpr;
 			ResolvExpr::findVoidExpression( newExpr, indexer );
