Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision a4da45ee15c7b12fa95d6fa3d7ed164730c4d88e)
+++ src/AST/Pass.proto.hpp	(revision b78c54fee28c2555a5cdaed9b00ce8e8db3187e1)
@@ -226,50 +226,4 @@
 		// Now the original containers should still have the unchanged values
 		// but also contain the new values.
-	}
-};
-
-/// Used by previsit implementation
-/// We need to reassign the result to 'node', unless the function
-/// returns void, then we just leave 'node' unchanged
-template<bool is_void>
-struct __assign;
-
-template<>
-struct __assign<true> {
-	template<typename core_t, typename node_t>
-	static inline void result( core_t & core, const node_t * & node ) {
-		core.previsit( node );
-	}
-};
-
-template<>
-struct __assign<false> {
-	template<typename core_t, typename node_t>
-	static inline void result( core_t & core, const node_t * & node ) {
-		node = core.previsit( node );
-		assertf(node, "Previsit must not return NULL");
-	}
-};
-
-/// Used by postvisit implementation
-/// We need to return the result unless the function
-/// returns void, then we just return the original node
-template<bool is_void>
-struct __return;
-
-template<>
-struct __return<true> {
-	template<typename core_t, typename node_t>
-	static inline const node_t * result( core_t & core, const node_t * & node ) {
-		core.postvisit( node );
-		return node;
-	}
-};
-
-template<>
-struct __return<false> {
-	template<typename core_t, typename node_t>
-	static inline auto result( core_t & core, const node_t * & node ) {
-		return core.postvisit( node );
 	}
 };
@@ -297,9 +251,12 @@
 	);
 
-	__assign<
-		std::is_void<
-			decltype( core.previsit( node ) )
-		>::value
-	>::result( core, node );
+	// We need to reassign the result to 'node', unless the function
+	// returns void, then we just leave 'node' unchanged
+	if constexpr ( std::is_void_v<decltype( core.previsit( node ) )> ) {
+		core.previsit( node );
+	} else {
+		node = core.previsit( node );
+		assertf(node, "Previsit must not return NULL");
+	}
 }
 
@@ -312,9 +269,12 @@
 	decltype( core.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
 {
-	return __return<
-		std::is_void<
-			decltype( core.postvisit( node ) )
-		>::value
-	>::result( core, node );
+	// We need to return the result unless the function
+	// returns void, then we just return the original node
+	if constexpr ( std::is_void_v<decltype( core.postvisit( node ) )> ) {
+		core.postvisit( node );
+		return node;
+	} else {
+		return core.postvisit( node );
+	}
 }
 
