Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/AST/Pass.impl.hpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -20,4 +20,5 @@
 #include <unordered_map>
 
+#include "AST/Copy.hpp"
 #include "AST/TranslationUnit.hpp"
 #include "AST/TypeSubstitution.hpp"
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/AST/Print.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -16,12 +16,13 @@
 #include "Print.hpp"
 
+#include "Attribute.hpp"
 #include "Decl.hpp"
 #include "Expr.hpp"
+#include "Init.hpp"
 #include "Stmt.hpp"
 #include "Type.hpp"
 #include "TypeSubstitution.hpp"
 #include "CompilationState.h"
-
-#include "Common/utility.h" // for group_iterate
+#include "Common/Iterate.hpp"
 
 using namespace std;
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/AST/SymbolTable.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -18,4 +18,5 @@
 #include <cassert>
 
+#include "Copy.hpp"
 #include "Decl.hpp"
 #include "Expr.hpp"
Index: src/AST/TypeSubstitution.cpp
===================================================================
--- src/AST/TypeSubstitution.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/AST/TypeSubstitution.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -10,15 +10,14 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Jun  3 13:26:00 2017
-// Update Count     : 5
-//
+// Last Modified On : Thr May 25 11:24:00 2023
+// Update Count     : 6
+//
+
+#include "TypeSubstitution.hpp"
 
 #include "Type.hpp"   // for TypeInstType, Type, StructInstType, UnionInstType
-#include "TypeSubstitution.hpp"
+#include "Pass.hpp"   // for Pass, PureVisitor, WithGuards, WithVisitorRef
 
 namespace ast {
-
-
-// size_t TypeSubstitution::Substituter::traceId = Stats::Heap::new_stacktrace_id("TypeSubstitution");
 
 TypeSubstitution::TypeSubstitution() {
@@ -119,4 +118,29 @@
 }
 
+// definitition must happen after PassVisitor is included so that WithGuards can be used
+struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter>, public PureVisitor {
+	//static size_t traceId;
+
+	Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
+
+	const Type * postvisit( const TypeInstType * aggregateUseType );
+
+	/// Records type variable bindings from forall-statements
+	void previsit( const FunctionType * type );
+	/// Records type variable bindings from forall-statements and instantiations of generic types
+	// void handleAggregateType( const BaseInstType * type );
+
+	// void previsit( const StructInstType * aggregateUseType );
+	// void previsit( const UnionInstType * aggregateUseType );
+
+	const TypeSubstitution & sub;
+	int subCount = 0;
+	bool freeOnly;
+	typedef std::unordered_set< TypeEnvKey > BoundVarsType;
+	BoundVarsType boundVars;
+};
+
+// size_t TypeSubstitution::Substituter::traceId = Stats::Heap::new_stacktrace_id("TypeSubstitution");
+
 void TypeSubstitution::normalize() {
 	Pass<Substituter> sub( *this, true );
@@ -128,4 +152,12 @@
 		}
 	} while ( sub.core.subCount );
+}
+
+TypeSubstitution::ApplyResult<Node> TypeSubstitution::applyBase(
+		const Node * input, bool isFree ) const {
+	assert( input );
+	Pass<Substituter> sub( *this, isFree );
+	const Node * output = input->accept( sub );
+	return { output, sub.core.subCount };
 }
 
Index: src/AST/TypeSubstitution.hpp
===================================================================
--- src/AST/TypeSubstitution.hpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/AST/TypeSubstitution.hpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Apr 30 22:52:47 2019
-// Update Count     : 9
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr May 25 12:31:00 2023
+// Update Count     : 10
 //
 
@@ -46,26 +46,33 @@
 	TypeSubstitution &operator=( const TypeSubstitution &other );
 
-	template< typename SynTreeClass >
+	template< typename node_t >
 	struct ApplyResult {
-		ast::ptr<SynTreeClass> node;
+		ast::ptr<node_t> node;
 		int count;
 	};
 
-	template< typename SynTreeClass > ApplyResult<SynTreeClass> apply( const SynTreeClass * input ) const;
-	template< typename SynTreeClass > ApplyResult<SynTreeClass> applyFree( const SynTreeClass * input ) const;
+	template< typename node_t >
+	ApplyResult<node_t> apply( const node_t * input ) const {
+		ApplyResult<Node> ret = applyBase( input, false );
+		return { ret.node.strict_as<node_t>(), ret.count };
+	}
 
 	template< typename node_t, enum Node::ref_type ref_t >
 	int apply( ptr_base< node_t, ref_t > & input ) const {
-		const node_t * p = input.get();
-		auto ret = apply(p);
-		input = ret.node;
+		ApplyResult<Node> ret = applyBase( input.get(), false );
+		input = ret.node.strict_as<node_t>();
 		return ret.count;
+	}
+
+	template< typename node_t >
+	ApplyResult<node_t> applyFree( const node_t * input ) const {
+		ApplyResult<Node> ret = applyBase( input, true );
+		return { ret.node.strict_as<node_t>(), ret.count };
 	}
 
 	template< typename node_t, enum Node::ref_type ref_t >
 	int applyFree( ptr_base< node_t, ref_t > & input ) const {
-		const node_t * p = input.get();
-		auto ret = applyFree(p);
-		input = ret.node;
+		ApplyResult<Node> ret = applyBase( input.get(), true );
+		input = ret.node.strict_as<node_t>();
 		return ret.count;
 	}
@@ -97,4 +104,5 @@
 	// Mutator that performs the substitution
 	struct Substituter;
+	ApplyResult<Node> applyBase( const Node * input, bool isFree ) const;
 
 	// TODO: worry about traversing into a forall-qualified function type or type decl with assertions
@@ -158,53 +166,4 @@
 } // namespace ast
 
-// include needs to happen after TypeSubstitution is defined so that both TypeSubstitution and
-// PassVisitor are defined before PassVisitor implementation accesses TypeSubstitution internals.
-#include "Pass.hpp"
-#include "Copy.hpp"
-
-namespace ast {
-
-// definitition must happen after PassVisitor is included so that WithGuards can be used
-struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter>, public PureVisitor {
-		static size_t traceId;
-
-		Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
-
-		const Type * postvisit( const TypeInstType * aggregateUseType );
-
-		/// Records type variable bindings from forall-statements
-		void previsit( const FunctionType * type );
-		/// Records type variable bindings from forall-statements and instantiations of generic types
-		// void handleAggregateType( const BaseInstType * type );
-
-		// void previsit( const StructInstType * aggregateUseType );
-		// void previsit( const UnionInstType * aggregateUseType );
-
-		const TypeSubstitution & sub;
-		int subCount = 0;
-		bool freeOnly;
-		typedef std::unordered_set< TypeEnvKey > BoundVarsType;
-		BoundVarsType boundVars;
-
-};
-
-template< typename SynTreeClass >
-TypeSubstitution::ApplyResult<SynTreeClass> TypeSubstitution::apply( const SynTreeClass * input ) const {
-	assert( input );
-	Pass<Substituter> sub( *this, false );
-	input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) );
-	return { input, sub.core.subCount };
-}
-
-template< typename SynTreeClass >
-TypeSubstitution::ApplyResult<SynTreeClass> TypeSubstitution::applyFree( const SynTreeClass * input ) const {
-	assert( input );
-	Pass<Substituter> sub( *this, true );
-	input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) );
-	return { input, sub.core.subCount };
-}
-
-} // namespace ast
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/Concurrency/Waituntil.cpp
===================================================================
--- src/Concurrency/Waituntil.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Concurrency/Waituntil.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -14,7 +14,9 @@
 //
 
+#include "Waituntil.hpp"
+
 #include <string>
 
-#include "Waituntil.hpp"
+#include "AST/Copy.hpp"
 #include "AST/Expr.hpp"
 #include "AST/Pass.hpp"
Index: src/ControlStruct/ExceptDeclNew.cpp
===================================================================
--- src/ControlStruct/ExceptDeclNew.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/ControlStruct/ExceptDeclNew.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -18,4 +18,5 @@
 #include <sstream>
 
+#include "AST/Copy.hpp"
 #include "AST/Decl.hpp"
 #include "AST/Pass.hpp"
Index: src/GenPoly/SpecializeNew.cpp
===================================================================
--- src/GenPoly/SpecializeNew.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/GenPoly/SpecializeNew.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -16,4 +16,5 @@
 #include "Specialize.h"
 
+#include "AST/Copy.hpp"                  // for deepCopy
 #include "AST/Inspect.hpp"               // for isIntrinsicCallExpr
 #include "AST/Pass.hpp"                  // for Pass
Index: src/MakeLibCfaNew.cpp
===================================================================
--- src/MakeLibCfaNew.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/MakeLibCfaNew.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -16,4 +16,5 @@
 #include "MakeLibCfa.h"
 
+#include "AST/Copy.hpp"
 #include "AST/Fwd.hpp"
 #include "AST/Pass.hpp"
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/ResolvExpr/CommonType.cc	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -21,4 +21,5 @@
 
 #include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
 #include "AST/Type.hpp"
 #include "Common/PassVisitor.h"
Index: src/ResolvExpr/PolyCost.cc
===================================================================
--- src/ResolvExpr/PolyCost.cc	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/ResolvExpr/PolyCost.cc	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -15,4 +15,5 @@
 
 #include "AST/SymbolTable.hpp"
+#include "AST/Pass.hpp"
 #include "AST/Type.hpp"
 #include "AST/TypeEnvironment.hpp"
Index: src/Tuples/Explode.cc
===================================================================
--- src/Tuples/Explode.cc	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Tuples/Explode.cc	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -17,4 +17,5 @@
 #include <list>                  // for list
 
+#include "AST/Pass.hpp"          // for Pass
 #include "SynTree/Mutator.h"     // for Mutator
 #include "Common/PassVisitor.h"  // for PassVisitor
Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Validate/Autogen.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -25,4 +25,5 @@
 
 #include "AST/Attribute.hpp"
+#include "AST/Copy.hpp"
 #include "AST/Create.hpp"
 #include "AST/Decl.hpp"
Index: src/Validate/FixQualifiedTypes.cpp
===================================================================
--- src/Validate/FixQualifiedTypes.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Validate/FixQualifiedTypes.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -16,4 +16,5 @@
 #include "Validate/FixQualifiedTypes.hpp"
 
+#include "AST/Copy.hpp"
 #include "AST/LinkageSpec.hpp"             // for Linkage
 #include "AST/Pass.hpp"
Index: src/Validate/GenericParameter.cpp
===================================================================
--- src/Validate/GenericParameter.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Validate/GenericParameter.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -16,4 +16,5 @@
 #include "GenericParameter.hpp"
 
+#include "AST/Copy.hpp"
 #include "AST/Decl.hpp"
 #include "AST/Expr.hpp"
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Validate/ReplaceTypedef.cpp	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -16,4 +16,5 @@
 #include "ReplaceTypedef.hpp"
 
+#include "AST/Copy.hpp"
 #include "AST/Pass.hpp"
 #include "Common/ScopedMap.h"
Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/Virtual/ExpandCasts.cc	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -20,4 +20,5 @@
 #include <string>                  // for string, allocator, operator==, ope...
 
+#include "AST/Copy.hpp"
 #include "AST/Decl.hpp"
 #include "AST/Expr.hpp"
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 2d0f918fccda13d7214a5f8726ab517b71632108)
+++ src/main.cc	(revision 124400b89554d49da6f0c09302230624a4618bd6)
@@ -32,4 +32,6 @@
 
 #include "AST/Convert.hpp"
+#include "AST/Pass.hpp"                     // for pass_visitor_stats
+#include "AST/TranslationUnit.hpp"          // for TranslationUnit
 #include "AST/Util.hpp"                     // for checkInvariants
 #include "CompilationState.h"
