Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision ecd4923b6c6691baf4df6c29ef6d99081a28b0d1)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 1449d83d58f534d045be59bb9bcd5ecab96c5519)
@@ -14,4 +14,5 @@
 //
 
+#include "Common/PassVisitor.h"
 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
 #include "SynTree/Type.h"                // for TypeInstType, Type, BasicType
@@ -20,24 +21,25 @@
 
 namespace ResolvExpr {
-	class PtrsAssignable : public Visitor {
-	  public:
+	struct PtrsAssignable : public WithShortCircuiting {
 		PtrsAssignable( Type *dest, const TypeEnvironment &env );
 
 		int get_result() const { return result; }
 
-		virtual void visit( VoidType *voidType );
-		virtual void visit( BasicType *basicType );
-		virtual void visit( PointerType *pointerType );
-		virtual void visit( ArrayType *arrayType );
-		virtual void visit( FunctionType *functionType );
-		virtual void visit( StructInstType *inst );
-		virtual void visit( UnionInstType *inst );
-		virtual void visit( EnumInstType *inst );
-		virtual void visit( TraitInstType *inst );
-		virtual void visit( TypeInstType *inst );
-		virtual void visit( TupleType *tupleType );
-		virtual void visit( VarArgsType *varArgsType );
-		virtual void visit( ZeroType *zeroType );
-		virtual void visit( OneType *oneType );
+		void previsit( Type * ) { visit_children = false; }
+
+		void postvisit( VoidType * voidType );
+		void postvisit( BasicType * basicType );
+		void postvisit( PointerType * pointerType );
+		void postvisit( ArrayType * arrayType );
+		void postvisit( FunctionType * functionType );
+		void postvisit( StructInstType * inst );
+		void postvisit( UnionInstType * inst );
+		void postvisit( EnumInstType * inst );
+		void postvisit( TraitInstType * inst );
+		void postvisit( TypeInstType * inst );
+		void postvisit( TupleType * tupleType );
+		void postvisit( VarArgsType * varArgsType );
+		void postvisit( ZeroType * zeroType );
+		void postvisit( OneType * oneType );
 	  private:
 		Type *dest;
@@ -59,7 +61,7 @@
 			return -1;
 		} else {
-			PtrsAssignable ptrs( dest, env );
+			PassVisitor<PtrsAssignable> ptrs( dest, env );
 			src->accept( ptrs );
-			return ptrs.get_result();
+			return ptrs.pass.get_result();
 		} // if
 	}
@@ -67,18 +69,18 @@
 	PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
 
-	void PtrsAssignable::visit( VoidType * ) {
+	void PtrsAssignable::postvisit( VoidType * ) {
 		// T * = void * is disallowed - this is a change from C, where any
 		// void * can be assigned or passed to a non-void pointer without a cast.
 	}
 
-	void PtrsAssignable::visit( __attribute__((unused)) BasicType *basicType ) {}
-	void PtrsAssignable::visit( __attribute__((unused)) PointerType *pointerType ) {}
-	void PtrsAssignable::visit( __attribute__((unused)) ArrayType *arrayType ) {}
-	void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {}
+	void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
+	void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
+	void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
+	void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
 
-	void PtrsAssignable::visit(  __attribute__((unused)) StructInstType *inst ) {}
-	void PtrsAssignable::visit(  __attribute__((unused)) UnionInstType *inst ) {}
+	void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
+	void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
 
-	void PtrsAssignable::visit( EnumInstType * ) {
+	void PtrsAssignable::postvisit( EnumInstType * ) {
 		if ( dynamic_cast< BasicType* >( dest ) ) {
 			// int * = E *, etc. is safe. This isn't technically correct, as each
@@ -91,6 +93,6 @@
 	}
 
-	void PtrsAssignable::visit(  __attribute__((unused)) TraitInstType *inst ) {}
-	void PtrsAssignable::visit( TypeInstType *inst ) {
+	void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
+	void PtrsAssignable::postvisit( TypeInstType *inst ) {
 		EqvClass eqvClass;
 		if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
@@ -100,8 +102,8 @@
 	}
 
-	void PtrsAssignable::visit(  __attribute__((unused)) TupleType *tupleType ) {}
-	void PtrsAssignable::visit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
-	void PtrsAssignable::visit(  __attribute__((unused)) ZeroType *zeroType ) {}
-	void PtrsAssignable::visit(  __attribute__((unused)) OneType *oneType ) {}
+	void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
+	void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
+	void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
+	void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
 
 } // namespace ResolvExpr
