Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision 9b4f3290a76fc499cac978b84cc1ab000bd8d6d0)
+++ src/AST/Type.hpp	(revision 246c245850d55831cc2fd8e987ae1d76506c6fdd)
@@ -30,5 +30,5 @@
 
 // Must be included in *all* AST classes; should be #undef'd at the end of the file
-#define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);
+#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
 
 namespace ast {
@@ -37,5 +37,5 @@
 public:
 	CV::Qualifiers qualifiers;
-	
+
 	Type( CV::Qualifiers q = {} ) : qualifiers(q) {}
 
@@ -80,5 +80,5 @@
 public:
 	VoidType( CV::Qualifiers q = {} ) : Type( q ) {}
-	
+
 	unsigned size() const override { return 0; }
 	bool isVoid() const override { return true; }
@@ -171,5 +171,5 @@
 
 	PointerType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b), dimension() {}
-	PointerType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s, 
+	PointerType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
 		CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
 
@@ -193,5 +193,5 @@
 	DimensionFlag isStatic;
 
-	ArrayType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s, 
+	ArrayType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
 		CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
 
@@ -233,5 +233,5 @@
 	ptr<Type> child;
 
-	QualifiedType( const Type * p, const Type * c, CV::Qualifiers q = {} ) 
+	QualifiedType( const Type * p, const Type * c, CV::Qualifiers q = {} )
 	: Type(q), parent(p), child(c) {}
 
@@ -249,5 +249,5 @@
 	ForallList forall;
 
-	ParameterizedType( ForallList&& fs = {}, CV::Qualifiers q = {} ) 
+	ParameterizedType( ForallList&& fs = {}, CV::Qualifiers q = {} )
 	: Type(q), forall(std::move(fs)) {}
 	ParameterizedType( CV::Qualifiers q ) : Type(q), forall() {}
@@ -267,5 +267,5 @@
 	std::vector<ptr<DeclWithType>> params;
 
-	/// Does the function accept a variable number of arguments following the arguments specified 
+	/// Does the function accept a variable number of arguments following the arguments specified
 	/// in the parameters list.
 	/// This could be because of
@@ -296,5 +296,5 @@
 	bool hoistType = false;
 
-	ReferenceToType( const std::string& n, CV::Qualifiers q = {}, 
+	ReferenceToType( const std::string& n, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ParameterizedType(q), params(), attributes(std::move(as)), name(n) {}
@@ -319,10 +319,10 @@
 	readonly<StructDecl> base;
 
-	StructInstType( const std::string& n, CV::Qualifiers q = {}, 
+	StructInstType( const std::string& n, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
-	StructInstType( const StructDecl * b, CV::Qualifiers q = {}, 
+	StructInstType( const StructDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} );
-	
+
 	bool isComplete() const override;
 
@@ -342,10 +342,10 @@
 	readonly<UnionDecl> base;
 
-	UnionInstType( const std::string& n, CV::Qualifiers q = {}, 
+	UnionInstType( const std::string& n, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
-	UnionInstType( const UnionDecl * b, CV::Qualifiers q = {}, 
+	UnionInstType( const UnionDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} );
-	
+
 	bool isComplete() const override;
 
@@ -365,10 +365,10 @@
 	readonly<EnumDecl> base;
 
-	EnumInstType( const std::string& n, CV::Qualifiers q = {}, 
+	EnumInstType( const std::string& n, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
-	EnumInstType( const EnumDecl * b, CV::Qualifiers q = {}, 
+	EnumInstType( const EnumDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} );
-	
+
 	bool isComplete() const override;
 
@@ -388,10 +388,10 @@
 	readonly<TraitDecl> base;
 
-	TraitInstType( const std::string& n, CV::Qualifiers q = {}, 
+	TraitInstType( const std::string& n, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base() {}
-	TraitInstType( const TraitDecl * b, CV::Qualifiers q = {}, 
+	TraitInstType( const TraitDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} );
-	
+
 	// not meaningful for TraitInstType
 	bool isComplete() const override { assert(false); }
@@ -413,8 +413,8 @@
 	TypeVar::Kind kind;
 
-	TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {}, 
+	TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
-	TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {}, 
+	TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
 		std::vector<ptr<Attribute>> && as = {} )
 	: ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
@@ -448,9 +448,9 @@
 	iterator begin() const { return types.begin(); }
 	iterator end() const { return types.end(); }
-	
+
 	unsigned size() const override { return types.size(); }
 
 	const Type * getComponent( unsigned i ) override {
-		assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", 
+		assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d",
 			i, size() );
 		return *(begin()+i);
@@ -469,5 +469,5 @@
 	enum Kind { Typeof, Basetypeof } kind;
 
-	TypeofType( const Expr * e, Kind k = Typeof, CV::Qualifiers q = {} ) 
+	TypeofType( const Expr * e, Kind k = Typeof, CV::Qualifiers q = {} )
 	: Type(q), expr(e), kind(k) {}
 
@@ -482,5 +482,5 @@
 public:
 	VarArgsType( CV::Qualifiers q = {} ) : Type( q ) {}
-	
+
 	const Type * accept( Visitor & v ) const override { return v.visit( this ); }
 private:
@@ -493,5 +493,5 @@
 public:
 	ZeroType( CV::Qualifiers q = {} ) : Type( q ) {}
-	
+
 	const Type * accept( Visitor & v ) const override { return v.visit( this ); }
 private:
@@ -521,50 +521,4 @@
 	MUTATE_FRIEND
 };
-
-//=================================================================================================
-/// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency
-/// remove only if there is a better solution.
-/// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with
-/// forward declarations
-inline void increment( const class Type * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class Type * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class VoidType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class VoidType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class BasicType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class BasicType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class PointerType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class PointerType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class ArrayType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class ArrayType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class ReferenceType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class ReferenceType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class QualifiedType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class QualifiedType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class FunctionType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class FunctionType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class ReferenceToType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class ReferenceToType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class StructInstType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class StructInstType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class UnionInstType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class UnionInstType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class EnumInstType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class EnumInstType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class TraitInstType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class TraitInstType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class TypeInstType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class TypeInstType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class TupleType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class TupleType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class TypeofType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class TypeofType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class VarArgsType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class VarArgsType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class ZeroType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class ZeroType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class OneType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class OneType * node, Node::ref_type ref ) { node->decrement( ref ); }
-inline void increment( const class GlobalScopeType * node, Node::ref_type ref ) { node->increment( ref ); }
-inline void decrement( const class GlobalScopeType * node, Node::ref_type ref ) { node->decrement( ref ); }
 
 }
