Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 8c25760419860fd262fd45d0356675a44f69176b)
+++ src/AST/Pass.impl.hpp	(revision e3d4fd1b2ec7a7b883bb1d6504e81d04f98b5fcb)
@@ -22,5 +22,4 @@
 #include "AST/TranslationUnit.hpp"
 #include "AST/TypeSubstitution.hpp"
-#include "Common/Iterate.hpp"
 
 #define VISIT_START( node ) \
@@ -127,10 +126,4 @@
 	}
 
-	template< typename node_t >
-	template< typename object_t, typename super_t, typename field_t >
-	void __pass::result1< node_t >::apply( object_t * object, field_t super_t::* field ) {
-		object->*field = value;
-	}
-
 	template< typename core_t >
 	template< typename node_t >
@@ -234,54 +227,4 @@
 
 		return {true, compound};
-	}
-
-	template< template <class...> class container_t >
-	template< typename object_t, typename super_t, typename field_t >
-	void __pass::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
-		auto & container = object->*field;
-		__pedantic_pass_assert( container.size() <= values.size() );
-
-		auto cit = enumerate(container).begin();
-
-		container_t<ptr<Stmt>> nvals;
-		for (delta & d : values) {
-			if ( d.is_old ) {
-				__pedantic_pass_assert( cit.idx <= d.old_idx );
-				std::advance( cit, d.old_idx - cit.idx );
-				nvals.push_back( std::move( (*cit).val) );
-			} else {
-				nvals.push_back( std::move(d.new_val) );
-			}
-		}
-
-		container = std::move(nvals);
-	}
-
-	template< template <class...> class container_t >
-	template< template <class...> class incontainer_t >
-	void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Stmt>> * stmts ) {
-		if (!stmts || stmts->empty()) return;
-
-		std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ),
-			[](ast::ptr<ast::Stmt>& stmt) -> delta {
-				return delta( stmt.release(), -1, false );
-			});
-		stmts->clear();
-		differs = true;
-	}
-
-	template< template<class...> class container_t >
-	template< template<class...> class incontainer_t >
-	void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Decl>> * decls ) {
-		if (!decls || decls->empty()) return;
-
-		std::transform(decls->begin(), decls->end(), std::back_inserter( values ),
-			[](ast::ptr<ast::Decl>& decl) -> delta {
-				auto loc = decl->location;
-				auto stmt = new DeclStmt( loc, decl.release() );
-				return delta( stmt, -1, false );
-			});
-		decls->clear();
-		differs = true;
 	}
 
@@ -353,20 +296,4 @@
 
 		return new_kids;
-	}
-
-	template< template <class...> class container_t, typename node_t >
-	template< typename object_t, typename super_t, typename field_t >
-	void __pass::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
-		auto & container = object->*field;
-		__pedantic_pass_assert( container.size() == values.size() );
-
-		for(size_t i = 0; i < container.size(); i++) {
-			// Take all the elements that are different in 'values'
-			// and swap them into 'container'
-			if( values[i] != nullptr ) swap(container[i], values[i]);
-		}
-
-		// Now the original containers should still have the unchanged values
-		// but also contain the new values
 	}
 
@@ -2236,4 +2163,6 @@
 }
 
+#undef __pedantic_pass_assertf
+#undef __pedantic_pass_assert
 #undef VISIT_START
 #undef VISIT_END
Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision 8c25760419860fd262fd45d0356675a44f69176b)
+++ src/AST/Pass.proto.hpp	(revision e3d4fd1b2ec7a7b883bb1d6504e81d04f98b5fcb)
@@ -17,4 +17,5 @@
 // IWYU pragma: private, include "Pass.hpp"
 
+#include "Common/Iterate.hpp"
 #include "Common/Stats/Heap.h"
 namespace ast {
@@ -24,4 +25,12 @@
 	template<typename node_t> node_t * deepCopy( const node_t * );
 }
+
+#ifdef PEDANTIC_PASS_ASSERT
+#define __pedantic_pass_assert(...) assert (__VA_ARGS__)
+#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
+#else
+#define __pedantic_pass_assert(...)
+#define __pedantic_pass_assertf(...)
+#endif
 
 namespace ast::__pass {
@@ -130,5 +139,7 @@
 
 	template< typename object_t, typename super_t, typename field_t >
-	void apply( object_t *, field_t super_t::* field );
+	void apply( object_t * object, field_t super_t::* field ) {
+		object->*field = value;
+	}
 };
 
@@ -150,11 +161,48 @@
 
 	template< typename object_t, typename super_t, typename field_t >
-	void apply( object_t *, field_t super_t::* field );
+	void apply( object_t * object, field_t super_t::* field ) {
+		field_t & container = object->*field;
+		__pedantic_pass_assert( container.size() <= values.size() );
+
+		auto cit = enumerate(container).begin();
+
+		container_t<ptr<Stmt>> nvals;
+		for ( delta & d : values ) {
+			if ( d.is_old ) {
+				__pedantic_pass_assert( cit.idx <= d.old_idx );
+				std::advance( cit, d.old_idx - cit.idx );
+				nvals.push_back( std::move( (*cit).val ) );
+			} else {
+				nvals.push_back( std::move( d.new_val ) );
+			}
+		}
+
+		container = std::move(nvals);
+	}
 
 	template< template<class...> class incontainer_t >
-	void take_all( incontainer_t<ptr<Stmt>> * stmts );
+	void take_all( incontainer_t<ptr<Stmt>> * stmts ) {
+		if ( !stmts || stmts->empty() ) return;
+
+		std::transform( stmts->begin(), stmts->end(), std::back_inserter( values ),
+			[](ast::ptr<ast::Stmt>& stmt) -> delta {
+				return delta( stmt.release(), -1, false );
+			});
+		stmts->clear();
+		differs = true;
+	}
 
 	template< template<class...> class incontainer_t >
-	void take_all( incontainer_t<ptr<Decl>> * decls );
+	void take_all( incontainer_t<ptr<Decl>> * decls ) {
+		if ( !decls || decls->empty() ) return;
+
+		std::transform( decls->begin(), decls->end(), std::back_inserter( values ),
+			[](ast::ptr<ast::Decl>& decl) -> delta {
+				ast::Decl const * d = decl.release();
+				return delta( new DeclStmt( d->location, d ), -1, false );
+			});
+		decls->clear();
+		differs = true;
+	}
 };
 
@@ -166,5 +214,16 @@
 
 	template< typename object_t, typename super_t, typename field_t >
-	void apply( object_t *, field_t super_t::* field );
+	void apply( object_t * object, field_t super_t::* field ) {
+		field_t & container = object->*field;
+		__pedantic_pass_assert( container.size() == values.size() );
+
+		for ( size_t i = 0; i < container.size(); ++i ) {
+			// Take all the elements that are different in 'values'
+			// and swap them into 'container'
+			if ( values[i] != nullptr ) swap(container[i], values[i]);
+		}
+		// Now the original containers should still have the unchanged values
+		// but also contain the new values.
+	}
 };
 
@@ -517,2 +576,5 @@
 
 } // namespace ast::__pass
+
+#undef __pedantic_pass_assertf
+#undef __pedantic_pass_assert
