Index: src/AST/TypeEnvironment.hpp
===================================================================
--- src/AST/TypeEnvironment.hpp	(revision 9d5089e3f418f8ae4795697294bf00b26fc226a7)
+++ src/AST/TypeEnvironment.hpp	(revision 2890212a2b66d8b4d2e668cc354f6205f1c666bd)
@@ -38,20 +38,20 @@
 /// Adding this comparison operator significantly improves assertion satisfaction run time for
 /// some cases. The current satisfaction algorithm's speed partially depends on the order of
-/// assertions. Assertions which have fewer possible matches should appear before assertions 
-/// which have more possible matches. This seems to imply that this could be further improved 
-/// by providing an indexer as an additional argument and ordering based on the number of 
+/// assertions. Assertions which have fewer possible matches should appear before assertions
+/// which have more possible matches. This seems to imply that this could be further improved
+/// by providing an indexer as an additional argument and ordering based on the number of
 /// matches of the same kind (object, function) for the names of the declarations.
 ///
-/// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this 
+/// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this
 /// comparator.
 ///
-/// Note: since this compares pointers for position, minor changes in the source file that 
-/// affect memory layout can alter compilation time in unpredictable ways. For example, the 
-/// placement of a line directive can reorder type pointers with respect to each other so that 
-/// assertions are seen in different orders, causing a potentially different number of 
-/// unification calls when resolving assertions. I've seen a TU go from 36 seconds to 27 
-/// seconds by reordering line directives alone, so it would be nice to fix this comparison so 
-/// that assertions compare more consistently. I've tried to modify this to compare on mangle 
-/// name instead of type as the second comparator, but this causes some assertions to never be 
+/// Note: since this compares pointers for position, minor changes in the source file that
+/// affect memory layout can alter compilation time in unpredictable ways. For example, the
+/// placement of a line directive can reorder type pointers with respect to each other so that
+/// assertions are seen in different orders, causing a potentially different number of
+/// unification calls when resolving assertions. I've seen a TU go from 36 seconds to 27
+/// seconds by reordering line directives alone, so it would be nice to fix this comparison so
+/// that assertions compare more consistently. I've tried to modify this to compare on mangle
+/// name instead of type as the second comparator, but this causes some assertions to never be
 /// recorded. More investigation is needed.
 struct AssertCompare {
@@ -87,5 +87,5 @@
 void print( std::ostream &, const OpenVarSet &, Indenter indent = {} );
 
-/// Represents an equivalence class of bound type variables, optionally with the concrete type 
+/// Represents an equivalence class of bound type variables, optionally with the concrete type
 /// they bind to.
 struct EqvClass {
@@ -96,7 +96,7 @@
 
 	EqvClass() : vars(), bound(), allowWidening( true ), data() {}
-	
+
 	/// Copy-with-bound constructor
-	EqvClass( const EqvClass & o, const Type * b ) 
+	EqvClass( const EqvClass & o, const Type * b )
 	: vars( o.vars ), bound( b ), allowWidening( o.allowWidening ), data( o.data ) {}
 
@@ -143,16 +143,16 @@
 	void writeToSubstitution( TypeSubstitution & sub ) const;
 
-	template< typename node_t, enum Node::ref_type ref_t >
-	int apply( ptr_base< node_t, ref_t > & type ) const {
+	template< typename node_t >
+	auto apply( node_t && type ) const {
 		TypeSubstitution sub;
 		writeToSubstitution( sub );
-		return sub.apply( type );
-	}
-
-	template< typename node_t, enum Node::ref_type ref_t >
-	int applyFree( ptr_base< node_t, ref_t > & type ) const {
+		return sub.apply( std::forward<node_t>(type) );
+	}
+
+	template< typename node_t >
+	auto applyFree( node_t && type ) const {
 		TypeSubstitution sub;
 		writeToSubstitution( sub );
-		return sub.applyFree( type );
+		return sub.applyFree( std::forward<node_t>(type) );
 	}
 
@@ -173,16 +173,16 @@
 	void addActual( const TypeEnvironment & actualEnv, OpenVarSet & openVars );
 
-	/// Binds the type class represented by `typeInst` to the type `bindTo`; will add the class if 
+	/// Binds the type class represented by `typeInst` to the type `bindTo`; will add the class if
 	/// needed. Returns false on failure.
-	bool bindVar( 
-		const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data, 
-		AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 
+	bool bindVar(
+		const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data,
+		AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars,
 		ResolvExpr::WidenMode widen, const SymbolTable & symtab );
-	
-	/// Binds the type classes represented by `var1` and `var2` together; will add one or both 
+
+	/// Binds the type classes represented by `var1` and `var2` together; will add one or both
 	/// classes if needed. Returns false on failure.
-	bool bindVarToVar( 
-		const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, 
-		AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 
+	bool bindVarToVar(
+		const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data,
+		AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars,
 		ResolvExpr::WidenMode widen, const SymbolTable & symtab );
 
@@ -199,10 +199,10 @@
 
 	/// Unifies the type bound of `to` with the type bound of `from`, returning false if fails
-	bool mergeBound( 
+	bool mergeBound(
 		EqvClass & to, const EqvClass & from, OpenVarSet & openVars, const SymbolTable & symtab );
 
 	/// Merges two type classes from local environment, returning false if fails
-	bool mergeClasses( 
-		ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars, 
+	bool mergeClasses(
+		ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars,
 		const SymbolTable & symtab );
 
