Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision c470ada0207d9011922938be7cbc87f706da5ed5)
+++ src/Tuples/TupleExpansion.cc	(revision 7f59bb345a8462c2117878ca56ebb1c782675845)
@@ -36,9 +36,7 @@
 namespace Tuples {
 	namespace {
-		struct MemberTupleExpander final : public Mutator {
-			typedef Mutator Parent;
-			using Parent::mutate;
-
-			virtual Expression * mutate( UntypedMemberExpr * memberExpr ) override;
+		struct MemberTupleExpander final : public WithShortCircuiting, public WithVisitorRef<MemberTupleExpander> {
+			void premutate( UntypedMemberExpr * ) { visit_children = false; }
+			Expression * postmutate( UntypedMemberExpr * memberExpr );
 		};
 
@@ -79,5 +77,5 @@
 
 	void expandMemberTuples( std::list< Declaration * > & translationUnit ) {
-		MemberTupleExpander expander;
+		PassVisitor<MemberTupleExpander> expander;
 		mutateAll( translationUnit, expander );
 	}
@@ -109,10 +107,10 @@
 				// construct a new UntypedMemberExpr with the correct structure , and recursively
 				// expand that member expression.
-				MemberTupleExpander expander;
-				UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() );
-				UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), inner );
+				PassVisitor<MemberTupleExpander> expander;
+				UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->aggregate, aggr->clone() );
+				UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member, inner );
 				inner->location = newMemberExpr->location = loc;
-				memberExpr->set_member(nullptr);
-				memberExpr->set_aggregate(nullptr);
+				memberExpr->member = nullptr;
+				memberExpr->aggregate = nullptr;
 				delete memberExpr;
 				return newMemberExpr->acceptMutator( expander );
@@ -126,12 +124,12 @@
 	}
 
-	Expression * MemberTupleExpander::mutate( UntypedMemberExpr * memberExpr ) {
-		if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->get_member() ) ) {
-			Expression * aggr = memberExpr->get_aggregate()->clone()->acceptMutator( *this );
+	Expression * MemberTupleExpander::postmutate( UntypedMemberExpr * memberExpr ) {
+		if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->member ) ) {
+			Expression * aggr = memberExpr->aggregate->clone()->acceptMutator( *visitor );
 			// aggregate expressions which might be impure must be wrapped in unique expressions
 			// xxx - if there's a member-tuple expression nested in the aggregate, this currently generates the wrong code if a UniqueExpr is not used, and it's purely an optimization to remove the UniqueExpr
 			// if ( Tuples::maybeImpureIgnoreUnique( memberExpr->get_aggregate() ) ) aggr = new UniqueExpr( aggr );
 			aggr = new UniqueExpr( aggr );
-			for ( Expression *& expr : tupleExpr->get_exprs() ) {
+			for ( Expression *& expr : tupleExpr->exprs ) {
 				expr = reconstructMemberExpr( expr, aggr, memberExpr->location );
 				expr->location = memberExpr->location;
@@ -143,5 +141,5 @@
 			// there may be a tuple expr buried in the aggregate
 			// xxx - this is a memory leak
-			UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) );
+			UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member->clone(), memberExpr->aggregate->acceptMutator( *visitor ) );
 			newMemberExpr->location = memberExpr->location;
 			return newMemberExpr;
