Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 5ea7a228345060e0d7b908238c08f7fee6c70c71)
+++ src/Common/PassVisitor.impl.h	(revision 7821d6c9e338cc77be5204c2797a086bedb79410)
@@ -2,39 +2,39 @@
 // IWYU pragma: private, include "PassVisitor.h"
 
-#define VISIT_START( node )                     \
-	__attribute__((unused))                   \
+#define VISIT_START( node )                                     \
+	__attribute__((unused))                                   \
+	ChildrenGuard children_guard( get_visit_children_ptr() ); \
+	__attribute__((unused))                                   \
 	guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
-	bool visit_children = true;               \
-	set_visit_children( visit_children );	\
-	call_previsit( node );                    \
-	if( visit_children ) {                    \
+	call_previsit( node );                                    \
 
 #define VISIT_END( node )                       \
-	}                                         \
 	call_postvisit( node );                   \
 
-#define MUTATE_START( node )                    \
-	__attribute__((unused))                   \
+#define MUTATE_START( node )                                    \
+	__attribute__((unused))                                   \
+	ChildrenGuard children_guard( get_visit_children_ptr() ); \
+	__attribute__((unused))                                   \
 	guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
-	bool visit_children = true;               \
-	set_visit_children( visit_children );	\
-	call_premutate( node );                   \
-	if( visit_children ) {                    \
+	call_premutate( node );                                   \
 
 #define MUTATE_END( type, node )                \
-	}                                         \
 	return call_postmutate< type * >( node ); \
 
 
-#define VISIT_BODY( node )        \
-	VISIT_START( node );        \
-	Visitor::visit( node );     \
-	VISIT_END( node );          \
-
-
-#define MUTATE_BODY( type, node ) \
-	MUTATE_START( node );       \
-	Mutator::mutate( node );    \
-	MUTATE_END( type, node );   \
+#define VISIT_BODY( node )          \
+	VISIT_START( node );          \
+	if( children_guard ) {        \
+		Visitor::visit( node ); \
+	}                             \
+	VISIT_END( node );            \
+
+
+#define MUTATE_BODY( type, node )    \
+	MUTATE_START( node );          \
+	if( children_guard ) {         \
+		Mutator::mutate( node ); \
+	}                              \
+	MUTATE_END( type, node );      \
 
 
@@ -63,5 +63,4 @@
 template< typename pass_type >
 static inline void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& visitor ) {
-
 	DeclList_t* beforeDecls = visitor.get_beforeDecls();
 	DeclList_t* afterDecls  = visitor.get_afterDecls();
@@ -76,5 +75,5 @@
 		try {
 			// run visitor on declaration
-			maybeAccept( *i, visitor );
+			maybeAccept_impl( *i, visitor );
 		} catch( SemanticError &e ) {
 			e.set_location( (*i)->location );
@@ -92,5 +91,4 @@
 template< typename pass_type >
 static inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) {
-
 	DeclList_t* beforeDecls = mutator.get_beforeDecls();
 	DeclList_t* afterDecls  = mutator.get_afterDecls();
@@ -104,5 +102,5 @@
 		try {
 			// run mutator on declaration
-			*i = maybeMutate( *i, mutator );
+			maybeMutate_impl( *i, mutator );
 		} catch( SemanticError &e ) {
 			e.set_location( (*i)->location );
@@ -118,6 +116,15 @@
 }
 
-template< typename Container, typename VisitorType >
-inline void maybeAccept( Container &container, VisitorType &visitor ) {
+template< typename TreeType, typename pass_type >
+inline void maybeAccept_impl( TreeType * tree, PassVisitor< pass_type > & visitor ) {
+	if ( ! visitor.get_visit_children() ) return;
+	if ( tree ) {
+		tree->accept( visitor );
+	}
+}
+
+template< typename Container, typename pass_type >
+inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
+	if ( ! visitor.get_visit_children() ) return;
 	SemanticError errors;
 	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
@@ -136,11 +143,20 @@
 }
 
-template< typename Container, typename MutatorType >
-inline void maybeMutateRef( Container &container, MutatorType &mutator ) {
+template< typename TreeType, typename pass_type >
+inline void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_type > & mutator ) {
+	if ( ! mutator.get_visit_children() ) return;
+
+	if ( tree ) {
+		tree = strict_dynamic_cast< TreeType * >( tree->acceptMutator( mutator ) );
+	}
+}
+
+template< typename Container, typename pass_type >
+inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
+	if ( ! mutator.get_visit_children() ) return;
 	SemanticError errors;
 	for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
 		try {
 			if ( *i ) {
-///		    *i = (*i)->acceptMutator( mutator );
 				*i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
 				assert( *i );
@@ -159,4 +175,5 @@
 template< typename func_t >
 void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
+	if ( ! get_visit_children() ) return;
 	SemanticError errors;
 
@@ -199,5 +216,5 @@
 void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
 	handleStatementList( statements, [this]( Statement * stmt) {
-		stmt->accept( *this );
+		maybeAccept_impl( stmt, *this );
 	});
 }
@@ -206,5 +223,5 @@
 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
 	handleStatementList( statements, [this]( Statement *& stmt) {
-		stmt = stmt->acceptMutator( *this );
+		maybeMutate_impl( stmt, *this );
 	});
 }
@@ -214,4 +231,6 @@
 template< typename func_t >
 Statement * PassVisitor< pass_type >::handleStatement( Statement * stmt, func_t func ) {
+	if ( ! get_visit_children() ) return stmt;
+
 	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
 	ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
@@ -244,5 +263,5 @@
 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
 	return handleStatement( stmt, [this]( Statement * stmt ) {
-		maybeAccept( stmt, *this );
+		maybeAccept_impl( stmt, *this );
 		return stmt;
 	});
@@ -252,5 +271,6 @@
 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
 	return handleStatement( stmt, [this]( Statement * stmt ) {
-	 	return maybeMutate( stmt, *this );
+		maybeMutate_impl( stmt, *this );
+		return stmt;
 	});
 }
@@ -259,4 +279,5 @@
 template< typename func_t >
 Expression * PassVisitor< pass_type >::handleExpression( Expression * expr, func_t func ) {
+	if ( ! get_visit_children() ) return expr;
 	if( !expr ) return nullptr;
 
@@ -266,5 +287,5 @@
 	}
 
-	// should env be cloned (or moved) onto the result of the mutate?
+	// should env be moved onto the result of the mutate?
 	return func( expr );
 }
@@ -273,5 +294,5 @@
 Expression * PassVisitor< pass_type >::visitExpression( Expression * expr ) {
 	return handleExpression(expr, [this]( Expression * expr ) {
-		expr->accept( *this );
+		maybeAccept_impl( expr, *this );
 		return expr;
 	});
@@ -281,6 +302,27 @@
 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
 	return handleExpression(expr, [this]( Expression * expr ) {
-		return expr->acceptMutator( *this );
+		maybeMutate_impl( expr, *this );
+		return expr;
 	});
+}
+
+template< typename TreeType, typename VisitorType >
+inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
+	if ( ! visitor.get_visit_children() ) return;
+	auto guard = makeFuncGuard(
+		[&visitor]() { visitor.indexerScopeEnter(); },
+		[&visitor]() { visitor.indexerScopeLeave(); }
+	);
+	maybeAccept_impl( tree, visitor );
+}
+
+template< typename TreeType, typename MutatorType >
+inline void indexerScopedMutate( TreeType *& tree, MutatorType & mutator ) {
+	if ( ! mutator.get_visit_children() ) return;
+	auto guard = makeFuncGuard(
+		[&mutator]() { mutator.indexerScopeEnter(); },
+		[&mutator]() { mutator.indexerScopeLeave(); }
+	);
+	maybeMutate_impl( tree, mutator );
 }
 
@@ -319,7 +361,7 @@
 
 	indexerScopedAccept( node->type         , *this );
-	maybeAccept        ( node->init         , *this );
-	maybeAccept        ( node->bitfieldWidth, *this );
-	maybeAccept        ( node->attributes   , *this );
+	maybeAccept_impl   ( node->init         , *this );
+	maybeAccept_impl   ( node->bitfieldWidth, *this );
+	maybeAccept_impl   ( node->attributes   , *this );
 
 	if ( node->name != "" ) {
@@ -335,7 +377,7 @@
 
 	indexerScopedMutate( node->type         , *this );
-	maybeMutateRef     ( node->init         , *this );
-	maybeMutateRef     ( node->bitfieldWidth, *this );
-	maybeMutateRef     ( node->attributes   , *this );
+	maybeMutate_impl   ( node->init         , *this );
+	maybeMutate_impl   ( node->bitfieldWidth, *this );
+	maybeMutate_impl   ( node->attributes   , *this );
 
 	if ( node->name != "" ) {
@@ -358,7 +400,7 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->type, *this );
-		maybeAccept( node->statements, *this );
-		maybeAccept( node->attributes, *this );
+		maybeAccept_impl( node->type, *this );
+		maybeAccept_impl( node->statements, *this );
+		maybeAccept_impl( node->attributes, *this );
 	}
 
@@ -376,7 +418,7 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->type, *this );
-		maybeMutateRef( node->statements, *this );
-		maybeMutateRef( node->attributes, *this );
+		maybeMutate_impl( node->type, *this );
+		maybeMutate_impl( node->statements, *this );
+		maybeMutate_impl( node->attributes, *this );
 	}
 
@@ -396,6 +438,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->parameters, *this );
-		maybeAccept( node->members   , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
 	}
 
@@ -416,6 +458,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->parameters, *this );
-		maybeMutateRef( node->members   , *this );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->members   , *this );
 	}
 
@@ -437,6 +479,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->parameters, *this );
-		maybeAccept( node->members   , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
 	}
 
@@ -455,6 +497,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->parameters, *this );
-		maybeMutateRef( node->members   , *this );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->members   , *this );
 	}
 
@@ -473,6 +515,6 @@
 
 	// unlike structs, traits, and unions, enums inject their members into the global scope
-	maybeAccept( node->parameters, *this );
-	maybeAccept( node->members   , *this );
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
 
 	VISIT_END( node );
@@ -486,6 +528,6 @@
 
 	// unlike structs, traits, and unions, enums inject their members into the global scope
-	maybeMutateRef( node->parameters, *this );
-	maybeMutateRef( node->members   , *this );
+	maybeMutate_impl( node->parameters, *this );
+	maybeMutate_impl( node->members   , *this );
 
 	MUTATE_END( Declaration, node );
@@ -500,6 +542,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->parameters, *this );
-		maybeAccept( node->members   , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
 	}
 
@@ -515,6 +557,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->parameters, *this );
-		maybeMutateRef( node->members   , *this );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->members   , *this );
 	}
 
@@ -532,6 +574,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->parameters, *this );
-		maybeAccept( node->base      , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->base      , *this );
 	}
 
@@ -541,5 +583,5 @@
 	indexerAddType( node );
 
-	maybeAccept( node->assertions, *this );
+	maybeAccept_impl( node->assertions, *this );
 
 	indexerScopedAccept( node->init, *this );
@@ -554,6 +596,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->parameters, *this );
-		maybeMutateRef( node->base      , *this );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->base      , *this );
 	}
 
@@ -563,5 +605,5 @@
 	indexerAddType( node );
 
-	maybeMutateRef( node->assertions, *this );
+	maybeMutate_impl( node->assertions, *this );
 
 	indexerScopedMutate( node->init, *this );
@@ -578,11 +620,11 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->parameters, *this );
-		maybeAccept( node->base      , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->base      , *this );
 	}
 
 	indexerAddType( node );
 
-	maybeAccept( node->assertions, *this );
+	maybeAccept_impl( node->assertions, *this );
 
 	VISIT_END( node );
@@ -595,11 +637,11 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef     ( node->parameters, *this );
-		maybeMutateRef( node->base      , *this );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->base      , *this );
 	}
 
 	indexerAddType( node );
 
-	maybeMutateRef( node->assertions, *this );
+	maybeMutate_impl( node->assertions, *this );
 
 	MUTATE_END( Declaration, node );
@@ -612,5 +654,5 @@
 	VISIT_START( node );
 
-	maybeAccept( node->stmt, *this );
+	maybeAccept_impl( node->stmt, *this );
 
 	VISIT_END( node );
@@ -621,5 +663,5 @@
 	MUTATE_START( node );
 
-	maybeMutateRef( node->stmt, *this );
+	maybeMutate_impl( node->stmt, *this );
 
 	MUTATE_END( AsmDecl, node );
@@ -690,6 +732,6 @@
 		// if statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		acceptAll( node->get_initialization(), *this );
-		visitExpression( node->condition );
+		maybeAccept_impl( node->get_initialization(), *this );
+		visitExpression ( node->condition );
 		node->thenPart = visitStatement( node->thenPart );
 		node->elsePart = visitStatement( node->elsePart );
@@ -704,5 +746,5 @@
 		// if statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->get_initialization(), *this );
+		maybeMutate_impl( node->get_initialization(), *this );
 		node->condition = mutateExpression( node->condition );
 		node->thenPart  = mutateStatement ( node->thenPart  );
@@ -742,5 +784,5 @@
 		// for statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->initialization, *this );
+		maybeAccept_impl( node->initialization, *this );
 		visitExpression( node->condition );
 		visitExpression( node->increment );
@@ -756,5 +798,5 @@
 		// for statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->initialization, *this );
+		maybeMutate_impl( node->initialization, *this );
 		node->condition = mutateExpression( node->condition );
 		node->increment = mutateExpression( node->increment );
@@ -859,7 +901,7 @@
 	VISIT_START( node );
 
-	maybeAccept( node->block       , *this );
-	maybeAccept( node->handlers    , *this );
-	maybeAccept( node->finallyBlock, *this );
+	maybeAccept_impl( node->block       , *this );
+	maybeAccept_impl( node->handlers    , *this );
+	maybeAccept_impl( node->finallyBlock, *this );
 
 	VISIT_END( node );
@@ -870,7 +912,7 @@
 	MUTATE_START( node );
 
-	maybeMutateRef( node->block       , *this );
-	maybeMutateRef( node->handlers    , *this );
-	maybeMutateRef( node->finallyBlock, *this );
+	maybeMutate_impl( node->block       , *this );
+	maybeMutate_impl( node->handlers    , *this );
+	maybeMutate_impl( node->finallyBlock, *this );
 
 	MUTATE_END( Statement, node );
@@ -885,5 +927,5 @@
 		// catch statements introduce a level of scope (for the caught exception)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->decl, *this );
+		maybeAccept_impl( node->decl, *this );
 		node->cond = visitExpression( node->cond );
 		node->body = visitStatement ( node->body );
@@ -898,5 +940,5 @@
 		// catch statements introduce a level of scope (for the caught exception)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->decl, *this );
+		maybeMutate_impl( node->decl, *this );
 		node->cond = mutateExpression( node->cond );
 		node->body = mutateStatement ( node->body );
@@ -972,6 +1014,6 @@
 
 	indexerScopedAccept( node->result  , *this );
-	maybeAccept        ( node->function, *this );
-	maybeAccept        ( node->args    , *this );
+	maybeAccept_impl        ( node->function, *this );
+	maybeAccept_impl        ( node->args    , *this );
 
 	VISIT_END( node );
@@ -984,6 +1026,6 @@
 	indexerScopedMutate( node->env     , *this );
 	indexerScopedMutate( node->result  , *this );
-	maybeMutateRef     ( node->function, *this );
-	maybeMutateRef     ( node->args    , *this );
+	maybeMutate_impl   ( node->function, *this );
+	maybeMutate_impl   ( node->args    , *this );
 
 	MUTATE_END( Expression, node );
@@ -996,5 +1038,5 @@
 	VISIT_START( node );
 
-	// maybeAccept( node->get_env(), *this );
+	// maybeAccept_impl( node->get_env(), *this );
 	indexerScopedAccept( node->result, *this );
 
@@ -1048,5 +1090,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->arg   , *this );
+	maybeAccept_impl        ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1059,5 +1101,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->arg   , *this );
+	maybeMutate_impl   ( node->arg   , *this );
 
 	MUTATE_END( Expression, node );
@@ -1071,5 +1113,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept( node->arg, *this );
+	maybeAccept_impl( node->arg, *this );
 
 	VISIT_END( node );
@@ -1082,5 +1124,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->arg   , *this );
+	maybeMutate_impl   ( node->arg   , *this );
 
 	MUTATE_END( Expression, node );
@@ -1094,5 +1136,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->arg   , *this );
+	maybeAccept_impl   ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1105,5 +1147,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->arg   , *this );
+	maybeMutate_impl   ( node->arg   , *this );
 
 	MUTATE_END( Expression, node );
@@ -1138,6 +1180,6 @@
 
 	indexerScopedAccept( node->result   , *this );
-	maybeAccept        ( node->aggregate, *this );
-	maybeAccept        ( node->member   , *this );
+	maybeAccept_impl   ( node->aggregate, *this );
+	maybeAccept_impl   ( node->member   , *this );
 
 	VISIT_END( node );
@@ -1150,6 +1192,6 @@
 	indexerScopedMutate( node->env      , *this );
 	indexerScopedMutate( node->result   , *this );
-	maybeMutateRef     ( node->aggregate, *this );
-	maybeMutateRef     ( node->member   , *this );
+	maybeMutate_impl   ( node->aggregate, *this );
+	maybeMutate_impl   ( node->member   , *this );
 
 	MUTATE_END( Expression, node );
@@ -1163,5 +1205,5 @@
 
 	indexerScopedAccept( node->result   , *this );
-	maybeAccept        ( node->aggregate, *this );
+	maybeAccept_impl   ( node->aggregate, *this );
 
 	VISIT_END( node );
@@ -1174,5 +1216,5 @@
 	indexerScopedMutate( node->env      , *this );
 	indexerScopedMutate( node->result   , *this );
-	maybeMutateRef     ( node->aggregate, *this );
+	maybeMutate_impl   ( node->aggregate, *this );
 
 	MUTATE_END( Expression, node );
@@ -1207,5 +1249,5 @@
 
 	indexerScopedAccept( node->result   , *this );
-	maybeAccept        ( &node->constant, *this );
+	maybeAccept_impl   ( &node->constant, *this );
 
 	VISIT_END( node );
@@ -1218,5 +1260,7 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	node->constant = *maybeMutate( &node->constant, *this );
+	Constant * ptr = &node->constant;
+	maybeMutate_impl( ptr, *this );
+	node->constant = *ptr;
 
 	MUTATE_END( Expression, node );
@@ -1231,7 +1275,7 @@
 	indexerScopedAccept( node->result, *this );
 	if ( node->get_isType() ) {
-		maybeAccept( node->type, *this );
+		maybeAccept_impl( node->type, *this );
 	} else {
-		maybeAccept( node->expr, *this );
+		maybeAccept_impl( node->expr, *this );
 	}
 
@@ -1246,7 +1290,7 @@
 	indexerScopedMutate( node->result, *this );
 	if ( node->get_isType() ) {
-		maybeMutateRef( node->type, *this );
+		maybeMutate_impl( node->type, *this );
 	} else {
-		maybeMutateRef( node->expr, *this );
+		maybeMutate_impl( node->expr, *this );
 	}
 
@@ -1262,7 +1306,7 @@
 	indexerScopedAccept( node->result, *this );
 	if ( node->get_isType() ) {
-		maybeAccept( node->type, *this );
+		maybeAccept_impl( node->type, *this );
 	} else {
-		maybeAccept( node->expr, *this );
+		maybeAccept_impl( node->expr, *this );
 	}
 
@@ -1277,7 +1321,7 @@
 	indexerScopedMutate( node->result, *this );
 	if ( node->get_isType() ) {
-		maybeMutateRef( node->type, *this );
+		maybeMutate_impl( node->type, *this );
 	} else {
-		maybeMutateRef( node->expr, *this );
+		maybeMutate_impl( node->expr, *this );
 	}
 
@@ -1292,5 +1336,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->type  , *this );
+	maybeAccept_impl   ( node->type  , *this );
 
 	VISIT_END( node );
@@ -1303,5 +1347,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->type  , *this );
+	maybeMutate_impl   ( node->type  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1315,6 +1359,6 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->type  , *this );
-	maybeAccept        ( node->member, *this );
+	maybeAccept_impl   ( node->type  , *this );
+	maybeAccept_impl   ( node->member, *this );
 
 	VISIT_END( node );
@@ -1327,6 +1371,6 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->type  , *this );
-	maybeMutateRef     ( node->member, *this );
+	maybeMutate_impl   ( node->type  , *this );
+	maybeMutate_impl   ( node->member, *this );
 
 	MUTATE_END( Expression, node );
@@ -1340,5 +1384,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->type  , *this );
+	maybeAccept_impl   ( node->type  , *this );
 
 	VISIT_END( node );
@@ -1351,5 +1395,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->type  , *this );
+	maybeMutate_impl   ( node->type  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1364,7 +1408,7 @@
 	indexerScopedAccept( node->result, *this );
 	if ( node->get_isType() ) {
-		maybeAccept( node->type, *this );
+		maybeAccept_impl( node->type, *this );
 	} else {
-		maybeAccept( node->expr, *this );
+		maybeAccept_impl( node->expr, *this );
 	}
 
@@ -1379,7 +1423,7 @@
 	indexerScopedMutate( node->result, *this );
 	if ( node->get_isType() ) {
-		maybeMutateRef( node->type, *this );
+		maybeMutate_impl( node->type, *this );
 	} else {
-		maybeMutateRef( node->expr, *this );
+		maybeMutate_impl( node->expr, *this );
 	}
 
@@ -1394,6 +1438,6 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->arg1  , *this );
-	maybeAccept        ( node->arg2  , *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
 
 	VISIT_END( node );
@@ -1406,6 +1450,6 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->arg1  , *this );
-	maybeMutateRef     ( node->arg2  , *this );
+	maybeMutate_impl   ( node->arg1  , *this );
+	maybeMutate_impl   ( node->arg2  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1419,7 +1463,7 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->arg1  , *this );
-	maybeAccept        ( node->arg2  , *this );
-	maybeAccept        ( node->arg3  , *this );
+	maybeAccept_impl        ( node->arg1  , *this );
+	maybeAccept_impl        ( node->arg2  , *this );
+	maybeAccept_impl        ( node->arg3  , *this );
 
 	VISIT_END( node );
@@ -1432,7 +1476,7 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->arg1  , *this );
-	maybeMutateRef     ( node->arg2  , *this );
-	maybeMutateRef     ( node->arg3  , *this );
+	maybeMutate_impl   ( node->arg1  , *this );
+	maybeMutate_impl   ( node->arg2  , *this );
+	maybeMutate_impl   ( node->arg3  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1446,6 +1490,6 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->arg1  , *this );
-	maybeAccept        ( node->arg2  , *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
 
 	VISIT_END( node );
@@ -1458,6 +1502,6 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->arg1  , *this );
-	maybeMutateRef     ( node->arg2  , *this );
+	maybeMutate_impl   ( node->arg1  , *this );
+	maybeMutate_impl   ( node->arg2  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1471,5 +1515,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->type, *this );
+	maybeAccept_impl   ( node->type, *this );
 
 	VISIT_END( node );
@@ -1482,5 +1526,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->type  , *this );
+	maybeMutate_impl   ( node->type  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1494,7 +1538,7 @@
 
 	indexerScopedAccept( node->result    , *this );
-	maybeAccept        ( node->inout     , *this );
-	maybeAccept        ( node->constraint, *this );
-	maybeAccept        ( node->operand   , *this );
+	maybeAccept_impl   ( node->inout     , *this );
+	maybeAccept_impl   ( node->constraint, *this );
+	maybeAccept_impl   ( node->operand   , *this );
 
 	VISIT_END( node );
@@ -1507,7 +1551,7 @@
 	indexerScopedMutate( node->env       , *this );
 	indexerScopedMutate( node->result    , *this );
-	maybeMutateRef     ( node->inout     , *this );
-	maybeMutateRef     ( node->constraint, *this );
-	maybeMutateRef     ( node->operand   , *this );
+	maybeMutate_impl   ( node->inout     , *this );
+	maybeMutate_impl   ( node->constraint, *this );
+	maybeMutate_impl   ( node->operand   , *this );
 
 	MUTATE_END( Expression, node );
@@ -1521,8 +1565,8 @@
 
 	indexerScopedAccept( node->result     , *this );
-	maybeAccept        ( node->callExpr   , *this );
-	maybeAccept        ( node->tempDecls  , *this );
-	maybeAccept        ( node->returnDecls, *this );
-	maybeAccept        ( node->dtors      , *this );
+	maybeAccept_impl   ( node->callExpr   , *this );
+	maybeAccept_impl   ( node->tempDecls  , *this );
+	maybeAccept_impl   ( node->returnDecls, *this );
+	maybeAccept_impl   ( node->dtors      , *this );
 
 	VISIT_END( node );
@@ -1535,8 +1579,8 @@
 	indexerScopedMutate( node->env        , *this );
 	indexerScopedMutate( node->result     , *this );
-	maybeMutateRef     ( node->callExpr   , *this );
-	maybeMutateRef     ( node->tempDecls  , *this );
-	maybeMutateRef     ( node->returnDecls, *this );
-	maybeMutateRef     ( node->dtors      , *this );
+	maybeMutate_impl   ( node->callExpr   , *this );
+	maybeMutate_impl   ( node->tempDecls  , *this );
+	maybeMutate_impl   ( node->returnDecls, *this );
+	maybeMutate_impl   ( node->dtors      , *this );
 
 	MUTATE_END( Expression, node );
@@ -1550,5 +1594,5 @@
 
 	indexerScopedAccept( node->result  , *this );
-	maybeAccept        ( node->callExpr, *this );
+	maybeAccept_impl   ( node->callExpr, *this );
 
 	VISIT_END( node );
@@ -1561,5 +1605,5 @@
 	indexerScopedMutate( node->env     , *this );
 	indexerScopedMutate( node->result  , *this );
-	maybeMutateRef     ( node->callExpr, *this );
+	maybeMutate_impl   ( node->callExpr, *this );
 
 	MUTATE_END( Expression, node );
@@ -1573,5 +1617,5 @@
 
 	indexerScopedAccept( node->result     , *this );
-	maybeAccept        ( node->initializer, *this );
+	maybeAccept_impl   ( node->initializer, *this );
 
 	VISIT_END( node );
@@ -1584,5 +1628,5 @@
 	indexerScopedMutate( node->env        , *this );
 	indexerScopedMutate( node->result     , *this );
-	maybeMutateRef     ( node->initializer, *this );
+	maybeMutate_impl     ( node->initializer, *this );
 
 	MUTATE_END( Expression, node );
@@ -1596,6 +1640,6 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->low   , *this );
-	maybeAccept        ( node->high  , *this );
+	maybeAccept_impl   ( node->low   , *this );
+	maybeAccept_impl   ( node->high  , *this );
 
 	VISIT_END( node );
@@ -1608,6 +1652,6 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->low   , *this );
-	maybeMutateRef     ( node->high  , *this );
+	maybeMutate_impl   ( node->low   , *this );
+	maybeMutate_impl   ( node->high  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1621,5 +1665,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->exprs , *this );
+	maybeAccept_impl   ( node->exprs , *this );
 
 	VISIT_END( node );
@@ -1632,5 +1676,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->exprs , *this );
+	maybeMutate_impl   ( node->exprs , *this );
 
 	MUTATE_END( Expression, node );
@@ -1644,5 +1688,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept          ( node->exprs , *this );
+	maybeAccept_impl   ( node->exprs , *this );
 
 	VISIT_END( node );
@@ -1655,5 +1699,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->exprs , *this );
+	maybeMutate_impl   ( node->exprs , *this );
 
 	MUTATE_END( Expression, node );
@@ -1667,5 +1711,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->tuple , *this );
+	maybeAccept_impl   ( node->tuple , *this );
 
 	VISIT_END( node );
@@ -1678,5 +1722,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->tuple , *this );
+	maybeMutate_impl   ( node->tuple , *this );
 
 	MUTATE_END( Expression, node );
@@ -1690,5 +1734,5 @@
 
 	indexerScopedAccept( node->result  , *this );
-	maybeAccept        ( node->stmtExpr, *this );
+	maybeAccept_impl   ( node->stmtExpr, *this );
 
 	VISIT_END( node );
@@ -1701,5 +1745,5 @@
 	indexerScopedMutate( node->env     , *this );
 	indexerScopedMutate( node->result  , *this );
-	maybeMutateRef     ( node->stmtExpr, *this );
+	maybeMutate_impl   ( node->stmtExpr, *this );
 
 	MUTATE_END( Expression, node );
@@ -1718,7 +1762,7 @@
 
 	indexerScopedAccept( node->result     , *this );
-	maybeAccept        ( node->statements , *this );
-	maybeAccept        ( node->returnDecls, *this );
-	maybeAccept        ( node->dtors      , *this );
+	maybeAccept_impl   ( node->statements , *this );
+	maybeAccept_impl   ( node->returnDecls, *this );
+	maybeAccept_impl   ( node->dtors      , *this );
 
 	VISIT_END( node );
@@ -1735,7 +1779,7 @@
 
 	indexerScopedMutate( node->result     , *this );
-	maybeMutateRef     ( node->statements , *this );
-	maybeMutateRef     ( node->returnDecls, *this );
-	maybeMutateRef     ( node->dtors      , *this );
+	maybeMutate_impl   ( node->statements , *this );
+	maybeMutate_impl   ( node->returnDecls, *this );
+	maybeMutate_impl   ( node->dtors      , *this );
 
 	MUTATE_END( Expression, node );
@@ -1749,5 +1793,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept        ( node->expr  , *this );
+	maybeAccept_impl   ( node->expr  , *this );
 
 	VISIT_END( node );
@@ -1760,5 +1804,5 @@
 	indexerScopedMutate( node->env   , *this );
 	indexerScopedMutate( node->result, *this );
-	maybeMutateRef     ( node->expr  , *this );
+	maybeMutate_impl   ( node->expr  , *this );
 
 	MUTATE_END( Expression, node );
@@ -1805,6 +1849,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->forall    , *this );
-		maybeAccept( node->parameters, *this );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
 	}
 
@@ -1820,6 +1864,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->forall    , *this );
-		maybeMutateRef( node->parameters, *this );
+		maybeMutate_impl( node->forall    , *this );
+		maybeMutate_impl( node->parameters, *this );
 	}
 
@@ -1837,6 +1881,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeAccept( node->forall    , *this );
-		maybeAccept( node->parameters, *this );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
 	}
 
@@ -1852,6 +1896,6 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutateRef( node->forall    , *this );
-		maybeMutateRef( node->parameters, *this );
+		maybeMutate_impl( node->forall    , *this );
+		maybeMutate_impl( node->parameters, *this );
 	}
 
@@ -1877,6 +1921,6 @@
 	VISIT_START( node );
 
-	maybeAccept( node->forall    , *this );
-	maybeAccept( node->parameters, *this );
+	maybeAccept_impl( node->forall    , *this );
+	maybeAccept_impl( node->parameters, *this );
 
 	VISIT_END( node );
@@ -1887,6 +1931,6 @@
 	MUTATE_START( node );
 
-	maybeMutateRef( node->forall    , *this );
-	maybeMutateRef( node->parameters, *this );
+	maybeMutate_impl( node->forall    , *this );
+	maybeMutate_impl( node->parameters, *this );
 
 	MUTATE_END( Type, node );
@@ -1934,5 +1978,5 @@
 	VISIT_START( node );
 
-	maybeAccept( node->get_designators(), *this );
+	maybeAccept_impl( node->get_designators(), *this );
 
 	VISIT_END( node );
@@ -1943,5 +1987,5 @@
 	MUTATE_START( node );
 
-	maybeMutateRef( node->get_designators(), *this );
+	maybeMutate_impl( node->get_designators(), *this );
 
 	MUTATE_END( Designation, node );
