Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/AST/Node.hpp	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -32,4 +32,7 @@
 		}
 
+		template<typename node_t>
+		friend auto mutate(const node_t * node);
+
 	private:
 		size_t strong_ref = 0;
@@ -37,5 +40,40 @@
 	};
 
-	template< typename node_t, enum  Node::ref_type ref_t>
+	// Mutate a node, non-member function to avoid static type
+	// problems and be able to use auto return
+	template<typename node_t>
+	auto mutate(const node_t * node) {
+		assertf(
+			node->strong_count >= 1,
+			"Error: attempting to mutate a node that appears to have been linked"
+		);
+		if (node->strong_count == 1) {
+			return const_cast<node_t *>(node);
+		}
+
+		assertf(
+			node->weak_count == 0,
+			"Error: mutating node with weak references to it will invalided some references"
+		);
+		return node->clone();
+	}
+
+	// All accept routines should look as follows :
+	// virtual void accept( Visitor &v ) override {
+	// 	return v.visit(this);
+	// }
+	// Using the following wrapper to handle the node type
+	template< typename node_t >
+	auto visit_this( visitor & v, node_t * node ) {
+		ptr<node_t> p;
+		p.node = node;
+		auto r = v.visit(p);
+		p.node = nullptr;
+		return r;
+	}
+
+	// Base class for the smart pointer types
+	// should never really be used.
+	template< typename node_t, enum Node::ref_type ref_t>
 	class ptr_base {
 	public:
@@ -87,70 +125,7 @@
 
 	template< typename node_t >
-	class ptr : public ptr_base< node_t, Node::ref_type::strong > {
-	public:
-		typedef ptr_base< node_t, Node::ref_type::strong > base_t;
-
-		ptr() = default;
-		ptr( node_t node ) : base_t( node ) {}
-		~ptr() = default;
-
-		template< enum  Node::ref_type ref_t >
-		ptr( const ptr_base<node_t, ref_t> & o ) : base_t(o) {}
-
-		template< enum  Node::ref_type ref_t >
-		ptr( ptr_base<node_t, ref_t> && o ) : base_t( std::move(o) ) {}
-
-		template< enum  Node::ref_type o_ref_t >
-		ptr & operator=( const ptr_base<node_t, o_ref_t> & o ) {
-			base_t::operator=(o);
-			return *this;
-		}
-
-		template< enum  Node::ref_type o_ref_t >
-		ptr & operator=( ptr_base<node_t, o_ref_t> && o ) {
-			base_t::operator=(std::move(o));
-			return *this;
-		}
-
-		node_t * mutate() {
-			using base_t::node;
-			assert(node->strong_count);
-			if (node->strong_count == 1) {
-				return node;
-			}
-
-			assertf(node->weak_count == 0, "Error: mutating node with weak references to it will invalided some references");
-			auto n = new node_t(*node);
-			assign(n);
-			return node;
-		}
-	};
+	using ptr = ptr_base< node_t, Node::ref_type::strong >;
 
 	template< typename node_t >
-	class readonly : public ptr_base< node_t, Node::ref_type::weak > {
-	public:
-		typedef ptr_base< node_t, Node::ref_type::strong > base_t;
-
-		readonly() = default;
-		readonly( node_t node ) : base_t( node ) {}
-		~readonly() = default;
-
-		template< enum  Node::ref_type ref_t >
-		readonly( const ptr_base<node_t, ref_t> & o ) : base_t(o) {}
-
-		template< enum  Node::ref_type ref_t >
-		readonly( ptr_base<node_t, ref_t> && o ) : base_t( std::move(o) ) {}
-
-		template< enum  Node::ref_type o_ref_t >
-		readonly & operator=( const ptr_base<node_t, o_ref_t> & o ) {
-			base_t::operator=(o);
-			return *this;
-		}
-
-		template< enum  Node::ref_type o_ref_t >
-		readonly & operator=( ptr_base<node_t, o_ref_t> && o ) {
-			base_t::operator=(std::move(o));
-			return *this;
-		}
-	};
+	using readonly = ptr_base< node_t, Node::ref_type::weak >;
 }
Index: src/Common/Assert.cc
===================================================================
--- src/Common/Assert.cc	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/Common/Assert.cc	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -39,4 +39,14 @@
 }
 
+void abort(const char *fmt, ...	) noexcept __attribute__((noreturn, format(printf, 1, 2)));
+void abort(const char *fmt, ...	) noexcept {
+	va_list args;
+	va_start( args, fmt );
+	vfprintf( stderr, fmt, args );
+	va_end( args );
+	fprintf( stderr, "\n" );
+	abort();
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/Common/PassVisitor.impl.h	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -20,5 +20,7 @@
 
 #define MUTATE_END( type, node )                \
-	return call_postmutate< type * >( node ); \
+	auto __return = call_postmutate< type * >( node ); \
+	assert( __return ); \
+	return __return;
 
 
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/Common/PassVisitor.proto.h	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -174,4 +174,6 @@
 FIELD_PTR( PassVisitor<pass_type> * const, visitor )
 
+#undef FIELD_PTR
+
 //---------------------------------------------------------
 // Indexer
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -617,8 +617,7 @@
 				return create_terminate_rethrow( throwStmt );
 			} else {
-				assertf(false, "Invalid throw in %s at %i\n",
+				abort("Invalid throw in %s at %i\n",
 					throwStmt->location.filename.c_str(),
 					throwStmt->location.first_line);
-				return nullptr;
 			}
 		} else {
@@ -628,8 +627,7 @@
 				return create_resume_rethrow( throwStmt );
 			} else {
-				assertf(false, "Invalid throwResume in %s at %i\n",
+				abort("Invalid throwResume in %s at %i\n",
 					throwStmt->location.filename.c_str(),
 					throwStmt->location.first_line);
-				return nullptr;
 			}
 		}
Index: src/include/cassert
===================================================================
--- src/include/cassert	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/include/cassert	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -45,4 +45,5 @@
 }
 
+extern void abort(const char *fmt, ...	) noexcept __attribute__((noreturn, format(printf, 1, 2)));
 // Local Variables: //
 // tab-width: 4 //
Index: src/main.cc
===================================================================
--- src/main.cc	(revision b1d3ee1e84145955b10068d160898445cc59b4a6)
+++ src/main.cc	(revision 6a625dec0f64e84a53f9f54b9e3e180ce6265463)
@@ -40,4 +40,5 @@
 #include "Common/Stats.h"
 #include "Common/PassVisitor.h"
+// #include "AST/Pass.hpp"
 #include "Common/SemanticError.h"           // for SemanticError
 #include "Common/UnimplementedError.h"      // for UnimplementedError
