Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision cf90b882abe6cc2eb28dbf4b006d9d95c6fc37e1)
+++ src/GenPoly/Box.cc	(revision fc72845da193aa5bd08d9f818a08d4e83612b356)
@@ -61,4 +61,10 @@
 		FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
 
+		class BoxPass {
+		protected:
+			BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
+			TyVarMap scopeTyVars;
+		};
+
 		/// Adds layout-generation functions to polymorphic types
 		class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
@@ -197,19 +203,16 @@
 
 		/// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
-		class Pass3 final : public PolyMutator {
-		  public:
+		struct Pass3 final : public BoxPass, public WithGuards {
 			template< typename DeclClass >
-			DeclClass *handleDecl( DeclClass *decl, Type *type );
-
-			using PolyMutator::mutate;
-			virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
-			virtual Declaration *mutate( StructDecl *structDecl ) override;
-			virtual Declaration *mutate( UnionDecl *unionDecl ) override;
-			virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
-			virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
-			virtual TypeDecl *mutate( TypeDecl *objectDecl ) override;
-			virtual Type *mutate( PointerType *pointerType ) override;
-			virtual Type *mutate( FunctionType *funcType ) override;
-		  private:
+			void handleDecl( DeclClass * decl, Type * type );
+
+			void premutate( ObjectDecl * objectDecl );
+			void premutate( FunctionDecl * functionDecl );
+			void premutate( TypedefDecl * typedefDecl );
+			void premutate( StructDecl * structDecl );
+			void premutate( UnionDecl * unionDecl );
+			void premutate( TypeDecl * typeDecl );
+			void premutate( PointerType * pointerType );
+			void premutate( FunctionType * funcType );
 		};
 	} // anonymous namespace
@@ -247,5 +250,5 @@
 		Pass2 pass2;
 		PassVisitor<PolyGenericCalculator> polyCalculator;
-		Pass3 pass3;
+		PassVisitor<Pass3> pass3;
 
 		acceptAll( translationUnit, layoutBuilder );
@@ -253,5 +256,5 @@
 		mutateTranslationUnit/*All*/( translationUnit, pass2 );
 		mutateAll( translationUnit, polyCalculator );
-		mutateTranslationUnit/*All*/( translationUnit, pass3 );
+		mutateAll( translationUnit, pass3 );
 	}
 
@@ -1825,74 +1828,47 @@
 
 		template< typename DeclClass >
-		DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
-			scopeTyVars.beginScope();
+		void Pass3::handleDecl( DeclClass * decl, Type * type ) {
+			GuardScope( scopeTyVars );
 			makeTyVarMap( type, scopeTyVars );
-
-			DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
-			// ScrubTyVars::scrub( decl, scopeTyVars );
 			ScrubTyVars::scrubAll( decl );
-
-			scopeTyVars.endScope();
-			return ret;
-		}
-
-		ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) {
-			return handleDecl( objectDecl, objectDecl->get_type() );
-		}
-
-		DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) {
-			return handleDecl( functionDecl, functionDecl->get_functionType() );
-		}
-
-		TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) {
-			return handleDecl( typedefDecl, typedefDecl->get_base() );
+		}
+
+		void Pass3::premutate( ObjectDecl * objectDecl ) {
+			handleDecl( objectDecl, objectDecl->type );
+		}
+
+		void Pass3::premutate( FunctionDecl * functionDecl ) {
+			handleDecl( functionDecl, functionDecl->type );
+		}
+
+		void Pass3::premutate( TypedefDecl * typedefDecl ) {
+			handleDecl( typedefDecl, typedefDecl->base );
 		}
 
 		/// Strips the members from a generic aggregate
-		void stripGenericMembers(AggregateDecl* decl) {
-			if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
-		}
-
-		Declaration *Pass3::mutate( StructDecl *structDecl ) {
+		void stripGenericMembers(AggregateDecl * decl) {
+			if ( ! decl->parameters.empty() ) decl->members.clear();
+		}
+
+		void Pass3::premutate( StructDecl * structDecl ) {
 			stripGenericMembers( structDecl );
-			return structDecl;
-		}
-
-		Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
+		}
+
+		void Pass3::premutate( UnionDecl * unionDecl ) {
 			stripGenericMembers( unionDecl );
-			return unionDecl;
-		}
-
-		TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
-//   Initializer *init = 0;
-//   std::list< Expression *> designators;
-//   addToTyVarMap( typeDecl, scopeTyVars );
-//   if ( typeDecl->get_base() ) {
-//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
-//   }
-//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
-
+		}
+
+		void Pass3::premutate( TypeDecl * typeDecl ) {
 			addToTyVarMap( typeDecl, scopeTyVars );
-			return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
-		}
-
-		Type * Pass3::mutate( PointerType *pointerType ) {
-			scopeTyVars.beginScope();
+		}
+
+		void Pass3::premutate( PointerType * pointerType ) {
+			GuardScope( scopeTyVars );
 			makeTyVarMap( pointerType, scopeTyVars );
-
-			Type *ret = Mutator::mutate( pointerType );
-
-			scopeTyVars.endScope();
-			return ret;
-		}
-
-		Type * Pass3::mutate( FunctionType *functionType ) {
-			scopeTyVars.beginScope();
+		}
+
+		void Pass3::premutate( FunctionType * functionType ) {
+			GuardScope( scopeTyVars );
 			makeTyVarMap( functionType, scopeTyVars );
-
-			Type *ret = Mutator::mutate( functionType );
-
-			scopeTyVars.endScope();
-			return ret;
 		}
 	} // anonymous namespace
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision cf90b882abe6cc2eb28dbf4b006d9d95c6fc37e1)
+++ src/GenPoly/Specialize.cc	(revision fc72845da193aa5bd08d9f818a08d4e83612b356)
@@ -29,5 +29,4 @@
 #include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
 #include "Parser/LinkageSpec.h"          // for C
-#include "PolyMutator.h"                 // for PolyMutator
 #include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
 #include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision cf90b882abe6cc2eb28dbf4b006d9d95c6fc37e1)
+++ src/InitTweak/FixInit.cc	(revision fc72845da193aa5bd08d9f818a08d4e83612b356)
@@ -37,5 +37,4 @@
 #include "GenInit.h"                   // for genCtorDtor
 #include "GenPoly/GenPoly.h"           // for getFunctionType
-#include "GenPoly/PolyMutator.h"       // for PolyMutator
 #include "InitTweak.h"                 // for getFunctionName, getCallArg
 #include "Parser/LinkageSpec.h"        // for C, Spec, Cforall, isBuiltin
