Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision d7d9a605341969df23ea12387498dc6e6fea463c)
+++ src/ResolvExpr/Unify.cc	(revision 36a2367c488682e619007d98ff5bc30d567c9d5e)
@@ -44,26 +44,28 @@
 namespace ResolvExpr {
 
-	class Unify : public Visitor {
-	  public:
+	struct Unify : public WithShortCircuiting {
 		Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
 
 		bool get_result() const { return result; }
+
+		void previsit( BaseSyntaxNode * ) { visit_children = false; }
+
+		void postvisit( VoidType * voidType );
+		void postvisit( BasicType * basicType );
+		void postvisit( PointerType * pointerType );
+		void postvisit( ArrayType * arrayType );
+		void postvisit( ReferenceType * refType );
+		void postvisit( FunctionType * functionType );
+		void postvisit( StructInstType * aggregateUseType );
+		void postvisit( UnionInstType * aggregateUseType );
+		void postvisit( EnumInstType * aggregateUseType );
+		void postvisit( TraitInstType * aggregateUseType );
+		void postvisit( TypeInstType * aggregateUseType );
+		void postvisit( TupleType * tupleType );
+		void postvisit( VarArgsType * varArgsType );
+		void postvisit( ZeroType * zeroType );
+		void postvisit( OneType * oneType );
+
 	  private:
-		virtual void visit(VoidType *voidType);
-		virtual void visit(BasicType *basicType);
-		virtual void visit(PointerType *pointerType);
-		virtual void visit(ArrayType *arrayType);
-		virtual void visit(ReferenceType *refType);
-		virtual void visit(FunctionType *functionType);
-		virtual void visit(StructInstType *aggregateUseType);
-		virtual void visit(UnionInstType *aggregateUseType);
-		virtual void visit(EnumInstType *aggregateUseType);
-		virtual void visit(TraitInstType *aggregateUseType);
-		virtual void visit(TypeInstType *aggregateUseType);
-		virtual void visit(TupleType *tupleType);
-		virtual void visit(VarArgsType *varArgsType);
-		virtual void visit(ZeroType *zeroType);
-		virtual void visit(OneType *oneType);
-
 		template< typename RefType > void handleRefType( RefType *inst, Type *other );
 		template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
@@ -325,7 +327,7 @@
 			result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
 		} else {
-			Unify comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+			PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
 			type1->accept( comparator );
-			result = comparator.get_result();
+			result = comparator.pass.get_result();
 		} // if
 #ifdef DEBUG
@@ -404,9 +406,9 @@
 	}
 
-	void Unify::visit( __attribute__((unused)) VoidType *voidType) {
+	void Unify::postvisit( __attribute__((unused)) VoidType *voidType) {
 		result = dynamic_cast< VoidType* >( type2 );
 	}
 
-	void Unify::visit(BasicType *basicType) {
+	void Unify::postvisit(BasicType *basicType) {
 		if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
 			result = basicType->get_kind() == otherBasic->get_kind();
@@ -436,5 +438,5 @@
 	}
 
-	void Unify::visit(PointerType *pointerType) {
+	void Unify::postvisit(PointerType *pointerType) {
 		if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
 			result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
@@ -444,5 +446,5 @@
 	}
 
-	void Unify::visit(ReferenceType *refType) {
+	void Unify::postvisit(ReferenceType *refType) {
 		if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
 			result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
@@ -452,5 +454,5 @@
 	}
 
-	void Unify::visit(ArrayType *arrayType) {
+	void Unify::postvisit(ArrayType *arrayType) {
 		ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
 		// to unify, array types must both be VLA or both not VLA
@@ -567,5 +569,5 @@
 	}
 
-	void Unify::visit(FunctionType *functionType) {
+	void Unify::postvisit(FunctionType *functionType) {
 		FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
 		if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
@@ -669,21 +671,21 @@
 	}
 
-	void Unify::visit(StructInstType *structInst) {
+	void Unify::postvisit(StructInstType *structInst) {
 		handleGenericRefType( structInst, type2 );
 	}
 
-	void Unify::visit(UnionInstType *unionInst) {
+	void Unify::postvisit(UnionInstType *unionInst) {
 		handleGenericRefType( unionInst, type2 );
 	}
 
-	void Unify::visit(EnumInstType *enumInst) {
+	void Unify::postvisit(EnumInstType *enumInst) {
 		handleRefType( enumInst, type2 );
 	}
 
-	void Unify::visit(TraitInstType *contextInst) {
+	void Unify::postvisit(TraitInstType *contextInst) {
 		handleRefType( contextInst, type2 );
 	}
 
-	void Unify::visit(TypeInstType *typeInst) {
+	void Unify::postvisit(TypeInstType *typeInst) {
 		assert( openVars.find( typeInst->get_name() ) == openVars.end() );
 		TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 );
@@ -740,5 +742,5 @@
 	}
 
-	void Unify::visit(TupleType *tupleType) {
+	void Unify::postvisit(TupleType *tupleType) {
 		if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
 			std::unique_ptr<TupleType> flat1( tupleType->clone() );
@@ -757,13 +759,13 @@
 	}
 
-	void Unify::visit( __attribute__((unused)) VarArgsType *varArgsType ) {
+	void Unify::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {
 		result = dynamic_cast< VarArgsType* >( type2 );
 	}
 
-	void Unify::visit( __attribute__((unused)) ZeroType *zeroType ) {
+	void Unify::postvisit( __attribute__((unused)) ZeroType *zeroType ) {
 		result = dynamic_cast< ZeroType* >( type2 );
 	}
 
-	void Unify::visit( __attribute__((unused)) OneType *oneType ) {
+	void Unify::postvisit( __attribute__((unused)) OneType *oneType ) {
 		result = dynamic_cast< OneType* >( type2 );
 	}
