Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision dccc09135f13ac15d667c7d54961cc5a51b99367)
+++ src/AST/Expr.hpp	(revision 17a0228a259e28502dd8d4b446e1158357310c60)
@@ -503,5 +503,5 @@
 };
 
-/// The application of a function to a set of parameters, along with a set of copy constructor 
+/// The application of a function to a set of parameters, along with a set of copy constructor
 /// calls, one for each argument
 class ImplicitCopyCtorExpr final : public Expr {
@@ -603,6 +603,6 @@
 };
 
-/// A multiple- or mass-assignment operation, or a tuple ctor/dtor expression. 
-/// multiple-assignment: both sides of the assignment have tuple type, 
+/// A multiple- or mass-assignment operation, or a tuple ctor/dtor expression.
+/// multiple-assignment: both sides of the assignment have tuple type,
 ///     e.g. `[a, b, c] = [d, e, f];`
 /// mass-assignment: left-hand side has tuple type and right-hand side does not:
@@ -612,8 +612,8 @@
 	ptr<StmtExpr> stmtExpr;
 
-	TupleAssignExpr( 
-		const CodeLocation & loc, std::vector<ptr<Expr>> && assigns, 
+	TupleAssignExpr(
+		const CodeLocation & loc, std::vector<ptr<Expr>> && assigns,
 		std::vector<ptr<ObjectDecl>> && tempDecls );
-	
+
 	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
 private:
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision dccc09135f13ac15d667c7d54961cc5a51b99367)
+++ src/AST/Fwd.hpp	(revision 17a0228a259e28502dd8d4b446e1158357310c60)
@@ -15,4 +15,6 @@
 
 #pragma once
+
+#include <string>
 
 #include "AST/Node.hpp"
@@ -134,5 +136,8 @@
 
 template < typename ... Params >
-std::string toString( const Params & ... params );
+std::string toString( const Params & ... params ) {
+	#warning not implemented
+	return "";
+}
 
 typedef unsigned int UniqueId;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision dccc09135f13ac15d667c7d54961cc5a51b99367)
+++ src/AST/Pass.impl.hpp	(revision 17a0228a259e28502dd8d4b446e1158357310c60)
@@ -571,5 +571,5 @@
 	__pass::indexer::addType( pass, 0, node );
 
-	maybe_accept( node, &TypedefDecl::assertions );
+	VISIT( maybe_accept( node, &TypedefDecl::assertions ); )
 
 	VISIT_END( Decl, node );
@@ -626,5 +626,5 @@
 // ExprStmt
 template< typename pass_t >
-const ast::Stmt * ast::Pass< pass_t >::visit( const ExprStmt * node ) {
+const ast::Stmt * ast::Pass< pass_t >::visit( const ast::ExprStmt * node ) {
 	VISIT_START( node );
 
@@ -666,4 +666,5 @@
 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::IfStmt * node ) {
 	VISIT_START( node );
+
 	VISIT({
 		// if statements introduce a level of scope (for the initialization)
@@ -674,4 +675,5 @@
 		maybe_accept( node, &IfStmt::elsePart );
 	})
+
 	VISIT_END( Stmt, node );
 }
@@ -680,5 +682,5 @@
 // WhileStmt
 template< typename pass_t >
-const ast::Stmt * ast::Pass< pass_t >::visit( const WhileStmt * node ) {
+const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WhileStmt * node ) {
 	VISIT_START( node );
 
@@ -910,5 +912,649 @@
 }
 
-
+//--------------------------------------------------------------------------
+// ApplicationExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::ApplicationExpr * node ) {
+	VISIT_START( node );
+
+	VISIT(
+		{
+			guard_indexer guard { *this };
+			maybe_accept( node, &ApplicationExpr::result );
+		}
+		maybe_accept( node, &ApplicationExpr::func );
+		maybe_accept( node, &ApplicationExpr::args );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// UntypedExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedExpr * node ) {
+	VISIT_START( node );
+
+	VISIT(
+		{
+			guard_indexer guard { *this };
+			maybe_accept( node, &UntypedExpr::result );
+		}
+
+		maybe_accept( node, &UntypedExpr::args );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// NameExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::NameExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+		guard_indexer guard { *this };
+		maybe_accept( node, &NameExpr::result );
+	})
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// CastExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::CastExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &CastExpr::result );
+		}
+		maybe_accept( node, &CastExpr::arg );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// KeywordCastExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::KeywordCastExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &KeywordCastExpr::result );
+		}
+		maybe_accept( node, &KeywordCastExpr::arg );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// VirtualCastExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::VirtualCastExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &VirtualCastExpr::result );
+		}
+		maybe_accept( node, &VirtualCastExpr::arg );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// AddressExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::AddressExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &AddressExpr::result );
+		}
+		maybe_accept( node, &AddressExpr::arg );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// LabelAddressExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::LabelAddressExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+		guard_indexer guard { *this };
+		maybe_accept( node, &LabelAddressExpr::result );
+	})
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// UntypedMemberExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedMemberExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &UntypedMemberExpr::result );
+		}
+		maybe_accept( node, &UntypedMemberExpr::aggregate );
+		maybe_accept( node, &UntypedMemberExpr::member    );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// MemberExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::MemberExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &MemberExpr::result );
+		}
+		maybe_accept( node, &MemberExpr::aggregate );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// VariableExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::VariableExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+		guard_indexer guard { *this };
+		maybe_accept( node, &VariableExpr::result );
+	})
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// ConstantExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::ConstantExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+		guard_indexer guard { *this };
+		maybe_accept( node, &ConstantExpr::result );
+	})
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// SizeofExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::SizeofExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &SizeofExpr::result );
+		}
+		if ( node->type ) {
+			maybe_accept( node, &SizeofExpr::type );
+		} else {
+			maybe_accept( node, &SizeofExpr::expr );
+		}
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// AlignofExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::AlignofExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &AlignofExpr::result );
+		}
+		if ( node->type ) {
+			maybe_accept( node, &AlignofExpr::type );
+		} else {
+			maybe_accept( node, &AlignofExpr::expr );
+		}
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// UntypedOffsetofExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedOffsetofExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &UntypedOffsetofExpr::result );
+		}
+		maybe_accept( node, &UntypedOffsetofExpr::type   );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// OffsetofExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::OffsetofExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &OffsetofExpr::result );
+		}
+		maybe_accept( node, &OffsetofExpr::type   );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// OffsetPackExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::OffsetPackExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &OffsetPackExpr::result );
+		}
+		maybe_accept( node, &OffsetPackExpr::type   );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// LogicalExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::LogicalExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &LogicalExpr::result );
+		}
+		maybe_accept( node, &LogicalExpr::arg1 );
+		maybe_accept( node, &LogicalExpr::arg2 );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// ConditionalExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::ConditionalExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &ConditionalExpr::result );
+		}
+		maybe_accept( node, &ConditionalExpr::arg1 );
+		maybe_accept( node, &ConditionalExpr::arg2 );
+		maybe_accept( node, &ConditionalExpr::arg3 );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// CommaExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::CommaExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &CommaExpr::result );
+		}
+		maybe_accept( node, &CommaExpr::arg1 );
+		maybe_accept( node, &CommaExpr::arg2 );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// TypeExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::TypeExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &TypeExpr::result );
+		}
+		maybe_accept( node, &TypeExpr::type );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// AsmExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::AsmExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &AsmExpr::result );
+		}
+		maybe_accept( node, &AsmExpr::inout      );
+		maybe_accept( node, &AsmExpr::constraint );
+		maybe_accept( node, &AsmExpr::operand    );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// ImplicitCopyCtorExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::ImplicitCopyCtorExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &ImplicitCopyCtorExpr::result );
+		}
+		maybe_accept( node, &ImplicitCopyCtorExpr::callExpr    );
+		maybe_accept( node, &ImplicitCopyCtorExpr::tempDecls   );
+		maybe_accept( node, &ImplicitCopyCtorExpr::returnDecls );
+		maybe_accept( node, &ImplicitCopyCtorExpr::dtors       );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// ConstructorExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::ConstructorExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &ConstructorExpr::result );
+		}
+		maybe_accept( node, &ConstructorExpr::callExpr );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// CompoundLiteralExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::CompoundLiteralExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &CompoundLiteralExpr::result );
+		}
+		maybe_accept( node, &CompoundLiteralExpr::init );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// RangeExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::RangeExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &RangeExpr::result );
+		}
+		maybe_accept( node, &RangeExpr::low    );
+		maybe_accept( node, &RangeExpr::high   );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// UntypedTupleExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedTupleExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &UntypedTupleExpr::result );
+		}
+		maybe_accept( node, &UntypedTupleExpr::exprs  );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// TupleExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::TupleExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &TupleExpr::result );
+		}
+		maybe_accept( node, &TupleExpr::exprs  );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// TupleIndexExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::TupleIndexExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &TupleIndexExpr::result );
+		}
+		maybe_accept( node, &TupleIndexExpr::tuple  );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// TupleAssignExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::TupleAssignExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &TupleAssignExpr::result );
+		}
+		maybe_accept( node, &TupleAssignExpr::stmtExpr );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// StmtExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::StmtExpr * node ) {
+	VISIT_START( node );
+
+	VISIT(// don't want statements from outer CompoundStmts to be added to this StmtExpr
+		// get the stmts that will need to be spliced in
+		auto stmts_before = __pass::stmtsToAddBefore( pass, 0);
+		auto stmts_after  = __pass::stmtsToAddAfter ( pass, 0);
+
+		// These may be modified by subnode but most be restored once we exit this statemnet.
+		ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::env( pass, 0) );
+		ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
+		ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
+
+		{
+			guard_indexer guard { *this };
+			maybe_accept( node, &StmtExpr::result );
+		}
+		maybe_accept( node, &StmtExpr::stmts       );
+		maybe_accept( node, &StmtExpr::returnDecls );
+		maybe_accept( node, &StmtExpr::dtors       );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// UniqueExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::UniqueExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &UniqueExpr::result );
+		}
+		maybe_accept( node, &UniqueExpr::expr   );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// UntypedInitExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::UntypedInitExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &UntypedInitExpr::result );
+		}
+		maybe_accept( node, &UntypedInitExpr::expr   );
+		// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// InitExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::InitExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &InitExpr::result );
+		}
+		maybe_accept( node, &InitExpr::expr   );
+		maybe_accept( node, &InitExpr::designation );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// DeletedExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::DeletedExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &DeletedExpr::result );
+		}
+		maybe_accept( node, &DeletedExpr::expr );
+		// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// DefaultArgExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::DefaultArgExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &DefaultArgExpr::result );
+		}
+		maybe_accept( node, &DefaultArgExpr::expr );
+	)
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// GenericExpr
+template< typename pass_t >
+const ast::Expr * ast::Pass< pass_t >::visit( const ast::GenericExpr * node ) {
+	VISIT_START( node );
+
+	VISIT({
+			guard_indexer guard { *this };
+			maybe_accept( node, &GenericExpr::result );
+		}
+		maybe_accept( node, &GenericExpr::control );
+
+		std::vector<GenericExpr::Association> new_kids;
+		new_kids.reserve(node->associations.size());
+		bool mutated = false;
+		for( const auto & assoc : node->associations ) {
+			Type * type = nullptr;
+			if( assoc.type ) {
+				guard_indexer guard { *this };
+				type = assoc.type->accept( *this );
+				if( type != assoc.type ) mutated = true;
+			}
+			Expr * expr = nullptr;
+			if( assoc.expr ) {
+				expr = assoc.expr->accept( *this );
+				if( expr != assoc.expr ) mutated = true;
+			}
+			new_kids.emplace_back( type, expr );
+		}
+
+		if(mutated) {
+			auto n = mutate(node);
+			n->associations = std::move( new_kids );
+			node = n;
+		}
+	)
+
+	VISIT_END( Expr, node );
+}
 
 
@@ -970,46 +1616,46 @@
 }
 
-//--------------------------------------------------------------------------
-// TypeSubstitution
-template< typename pass_t >
-const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) {
-	VISIT_START( node );
-
-	VISIT(
-		{
-			bool mutated = false;
-			std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
-			for ( const auto & p : node->typeEnv ) {
-				guard_indexer guard { *this };
-				auto new_node = p.second->accept( *this );
-				if (new_node != p.second) mutated = false;
-				new_map.insert({ p.first, new_node });
-			}
-			if (mutated) {
-				auto new_node = mutate( node );
-				new_node->typeEnv.swap( new_map );
-				node = new_node;
-			}
-		}
-
-		{
-			bool mutated = false;
-			std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
-			for ( const auto & p : node->varEnv ) {
-				guard_indexer guard { *this };
-				auto new_node = p.second->accept( *this );
-				if (new_node != p.second) mutated = false;
-				new_map.insert({ p.first, new_node });
-			}
-			if (mutated) {
-				auto new_node = mutate( node );
-				new_node->varEnv.swap( new_map );
-				node = new_node;
-			}
-		}
-	)
-
-	VISIT_END( TypeSubstitution, node );
-}
+// //--------------------------------------------------------------------------
+// // TypeSubstitution
+// template< typename pass_t >
+// const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) {
+// 	VISIT_START( node );
+
+// 	VISIT(
+// 		{
+// 			bool mutated = false;
+// 			std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
+// 			for ( const auto & p : node->typeEnv ) {
+// 				guard_indexer guard { *this };
+// 				auto new_node = p.second->accept( *this );
+// 				if (new_node != p.second) mutated = false;
+// 				new_map.insert({ p.first, new_node });
+// 			}
+// 			if (mutated) {
+// 				auto new_node = mutate( node );
+// 				new_node->typeEnv.swap( new_map );
+// 				node = new_node;
+// 			}
+// 		}
+
+// 		{
+// 			bool mutated = false;
+// 			std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
+// 			for ( const auto & p : node->varEnv ) {
+// 				guard_indexer guard { *this };
+// 				auto new_node = p.second->accept( *this );
+// 				if (new_node != p.second) mutated = false;
+// 				new_map.insert({ p.first, new_node });
+// 			}
+// 			if (mutated) {
+// 				auto new_node = mutate( node );
+// 				new_node->varEnv.swap( new_map );
+// 				node = new_node;
+// 			}
+// 		}
+// 	)
+
+// 	VISIT_END( TypeSubstitution, node );
+// }
 
 #undef VISIT_START
Index: src/main.cc
===================================================================
--- src/main.cc	(revision dccc09135f13ac15d667c7d54961cc5a51b99367)
+++ src/main.cc	(revision 17a0228a259e28502dd8d4b446e1158357310c60)
@@ -40,5 +40,4 @@
 #include "Common/Stats.h"
 #include "Common/PassVisitor.h"
-// #include "AST/Pass.hpp"
 #include "Common/SemanticError.h"           // for SemanticError
 #include "Common/UnimplementedError.h"      // for UnimplementedError
