Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 201182a7edebd0d3951b3d6a594f323c8b1a2900)
+++ src/GenPoly/Box.cc	(revision a31b384c2f1d792441e593f4312b46973c034c70)
@@ -38,5 +38,4 @@
 #include "Lvalue.h"                      // for generalizedLvalue
 #include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
-#include "PolyMutator.h"                 // for PolyMutator
 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
 #include "ResolvExpr/typeops.h"          // for typesCompatible
@@ -130,22 +129,14 @@
 		/// * Moves polymorphic returns in function types to pointer-type parameters
 		/// * adds type size and assertion parameters to parameter lists
-		class Pass2 final : public PolyMutator {
-		  public:
-			template< typename DeclClass >
-			DeclClass *handleDecl( DeclClass *decl );
-			template< typename AggDecl >
-			AggDecl * handleAggDecl( AggDecl * aggDecl );
-
-			typedef PolyMutator Parent;
-			using Parent::mutate;
-			virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
-			virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
-			virtual StructDecl *mutate( StructDecl *structDecl ) override;
-			virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
-			virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
-			virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
-			virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
-			virtual Type *mutate( PointerType *pointerType ) override;
-			virtual Type *mutate( FunctionType *funcType ) override;
+		struct Pass2 final : public BoxPass, public WithGuards {
+			void handleAggDecl();
+
+			DeclarationWithType * postmutate( FunctionDecl *functionDecl );
+			void premutate( StructDecl *structDecl );
+			void premutate( UnionDecl *unionDecl );
+			void premutate( TraitDecl *unionDecl );
+			void premutate( TypeDecl *typeDecl );
+			void premutate( PointerType *pointerType );
+			void premutate( FunctionType *funcType );
 
 		  private:
@@ -246,5 +237,5 @@
 		PassVisitor<LayoutFunctionBuilder> layoutBuilder;
 		PassVisitor<Pass1> pass1;
-		Pass2 pass2;
+		PassVisitor<Pass2> pass2;
 		PassVisitor<PolyGenericCalculator> polyCalculator;
 		PassVisitor<Pass3> pass3;
@@ -252,5 +243,5 @@
 		acceptAll( translationUnit, layoutBuilder );
 		mutateAll( translationUnit, pass1 );
-		mutateTranslationUnit/*All*/( translationUnit, pass2 );
+		mutateAll( translationUnit, pass2 );
 		mutateAll( translationUnit, polyCalculator );
 		mutateAll( translationUnit, pass3 );
@@ -1254,13 +1245,5 @@
 		}
 
-		template< typename DeclClass >
-		DeclClass * Pass2::handleDecl( DeclClass *decl ) {
-			DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) );
-
-			return ret;
-		}
-
-		DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
-			functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
+		DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
 			FunctionType * ftype = functionDecl->get_functionType();
 			if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
@@ -1286,55 +1269,30 @@
 		}
 
-		ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
-			return handleDecl( objectDecl );
-		}
-
-		template< typename AggDecl >
-		AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
+		void Pass2::premutate( StructDecl * ) {
 			// prevent tyVars from leaking into containing scope
-			scopeTyVars.beginScope();
-			Parent::mutate( aggDecl );
-			scopeTyVars.endScope();
-			return aggDecl;
-		}
-
-		StructDecl * Pass2::mutate( StructDecl *aggDecl ) {
-			return handleAggDecl( aggDecl );
-		}
-
-		UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) {
-			return handleAggDecl( aggDecl );
-		}
-
-		TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
-			return handleAggDecl( aggDecl );
-		}
-
-		TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
+			GuardScope( scopeTyVars );
+		}
+
+		void Pass2::premutate( UnionDecl * ) {
+			// prevent tyVars from leaking into containing scope
+			GuardScope( scopeTyVars );
+		}
+
+		void Pass2::premutate( TraitDecl * ) {
+			// prevent tyVars from leaking into containing scope
+			GuardScope( scopeTyVars );
+		}
+
+		void Pass2::premutate( TypeDecl *typeDecl ) {
 			addToTyVarMap( typeDecl, scopeTyVars );
-			if ( typeDecl->get_base() ) {
-				return handleDecl( typeDecl );
-			} else {
-				return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) );
-			}
-		}
-
-		TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) {
-			return handleDecl( typedefDecl );
-		}
-
-		Type * Pass2::mutate( PointerType *pointerType ) {
-			scopeTyVars.beginScope();
+		}
+
+		void Pass2::premutate( PointerType *pointerType ) {
+			GuardScope( scopeTyVars );
 			makeTyVarMap( pointerType, scopeTyVars );
-
-			Type *ret = Parent::mutate( pointerType );
-
-			scopeTyVars.endScope();
-			return ret;
-		}
-
-		Type *Pass2::mutate( FunctionType *funcType ) {
-			scopeTyVars.beginScope();
-
+		}
+
+		void Pass2::premutate( FunctionType *funcType ) {
+			GuardScope( scopeTyVars );
 			makeTyVarMap( funcType, scopeTyVars );
 
@@ -1375,5 +1333,4 @@
 				// move all assertions into parameter list
 				for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
-//      *assert = (*assert)->acceptMutator( *this );
 					// assertion parameters may not be used in body, pass along with unused attribute.
 					(*assert)->get_attributes().push_back( new Attribute( "unused" ) );
@@ -1411,5 +1368,4 @@
 						}
 					}
-
 					seenTypes.insert( typeName );
 				}
@@ -1419,9 +1375,4 @@
 			funcType->get_parameters().splice( last, inferredParams );
 			addAdapters( funcType );
-			mutateAll( funcType->get_returnVals(), *this );
-			mutateAll( funcType->get_parameters(), *this );
-
-			scopeTyVars.endScope();
-			return funcType;
 		}
 
