Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/Convert.cpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -2343,5 +2343,6 @@
 				old->location,
 				GET_ACCEPT_1(arg, Expr),
-				old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
+				old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast,
+				(ast::CastExpr::CastKind) old->kind
 			)
 		);
Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/Expr.cpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -186,6 +186,6 @@
 // --- CastExpr
 
-CastExpr::CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g )
-: Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ) {}
+CastExpr::CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g, CastKind kind )
+: Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ), kind( kind ) {}
 
 bool CastExpr::get_lvalue() const {
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/Expr.hpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -55,4 +55,6 @@
 		const Expr * e )
 	: decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {}
+
+	operator bool() {return declptr;}
 };
 
@@ -335,8 +337,16 @@
 	GeneratedFlag isGenerated;
 
+	enum CastKind {
+		Default, // C
+		Coerce, // reinterpret cast
+		Return  // overload selection
+	};
+
+	CastKind kind = Default;
+
 	CastExpr( const CodeLocation & loc, const Expr * a, const Type * to,
-		GeneratedFlag g = GeneratedCast ) : Expr( loc, to ), arg( a ), isGenerated( g ) {}
+		GeneratedFlag g = GeneratedCast, CastKind kind = Default ) : Expr( loc, to ), arg( a ), isGenerated( g ), kind( kind ) {}
 	/// Cast-to-void
-	CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast );
+	CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast, CastKind kind = Default );
 
 	/// Wrap a cast expression around an existing expression (always generated)
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/SymbolTable.cpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -19,4 +19,7 @@
 
 #include "Copy.hpp"
+#include <iostream>
+#include <algorithm>
+
 #include "Decl.hpp"
 #include "Expr.hpp"
@@ -203,4 +206,6 @@
 			out.push_back(decl.second);
 		}
+
+		// std::cerr << otypeKey << ' ' << out.size() << std::endl;
 	}
 
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/Type.hpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -451,5 +451,7 @@
 	bool operator==(const TypeEnvKey & other) const;
 	bool operator<(const TypeEnvKey & other) const;
-};
+	operator bool() {return base;}
+};
+
 
 /// tuple type e.g. `[int, char]`
Index: src/AST/TypeEnvironment.cpp
===================================================================
--- src/AST/TypeEnvironment.cpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/TypeEnvironment.cpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -135,5 +135,5 @@
 		}
 	}
-	sub.normalize();
+	// sub.normalize();
 }
 
Index: src/AST/TypeEnvironment.hpp
===================================================================
--- src/AST/TypeEnvironment.hpp	(revision 8f5571611e55362b66ba5af61560f8d5d9ea50cb)
+++ src/AST/TypeEnvironment.hpp	(revision e172f4282bdde75d2719d7f3a0220b5fc643bd00)
@@ -63,5 +63,5 @@
 
 		int cmp = d1->var->name.compare( d2->var->name );
-		return cmp < 0 || ( cmp == 0 && d1->result < d2->result );
+		return cmp > 0 || ( cmp == 0 && d1->result < d2->result );
 	}
 };
