Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 5eb3f65e95375f1be49b0bbe3338a9b4b1d26c67)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -698,8 +698,4 @@
 		void postvisit( const ast::CountExpr * countExpr );
 
-		const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src, 
-			const ast::EnumInstType * dst
-			, const ast::Expr * expr, Cost minCost );
-
 		void postvisit( const ast::InitExpr * ) {
 			assertf( false, "CandidateFinder should never see a resolved InitExpr." );
@@ -1213,47 +1209,4 @@
 	}
 
-	// src is a subset of dst
-	const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src, 
-		const ast::EnumInstType * dst,
-		const ast::Expr * expr,
-		Cost minCost ) {
-		
-		auto srcDecl = src->base;
-		auto dstDecl = dst->base;
-
-		if (srcDecl->name == dstDecl->name) return expr;
-
-		for (auto& dstChild: dstDecl->inlinedDecl) {
-			Cost c = castCost(src, dstChild, false, symtab, tenv);
-			ast::CastExpr * castToDst;
-			if (c<minCost) {
-				unsigned offset = dstDecl->calChildOffset(dstChild.get());
-				if (offset > 0) {
-					auto untyped = ast::UntypedExpr::createCall(
-						expr->location, 
-						"?+?", 
-						{ new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
-						ast::ConstantExpr::from_int(expr->location, offset)});
-					CandidateFinder finder(context, tenv);
-					finder.find( untyped );
-					CandidateList winners = findMinCost( finder.candidates );
-					CandidateRef & choice = winners.front();
-					// choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
-					choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);
-					// castToDst = new ast::CastExpr(choice->expr, dstChild);
-					castToDst = new ast::CastExpr( 
-						makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),
-					 dst);
-
-				} else {
-					castToDst = new ast::CastExpr( expr, dst );
-				}
-				return castToDst;
-			}
-		}
-		SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);
-		return nullptr;
-	}
-
 	void Finder::postvisit( const ast::CastExpr * castExpr ) {
 		ast::ptr< ast::Type > toType = castExpr->result;
@@ -1309,6 +1262,7 @@
 			auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
 			auto toAsEnum = toType.as<ast::EnumInstType>();
-			if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {	
-				ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
+			if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
+				CandidateFinder subFinder(context, tenv);
+				ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
 				cand->expr = offsetExpr;
 			}
@@ -2193,6 +2147,9 @@
 					expr->location, 
 					"?+?", 
-					{ new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
-					ast::ConstantExpr::from_int(expr->location, offset)});
+					{ new ast::CastExpr( expr->location,
+						expr,
+						new ast::BasicType(ast::BasicKind::SignedInt),
+						ast::GeneratedFlag::ExplicitCast ),
+						ast::ConstantExpr::from_int(expr->location, offset)} );
 				CandidateFinder finder(context, env);
 				finder.find( untyped );
Index: src/ResolvExpr/CastCost.cpp
===================================================================
--- src/ResolvExpr/CastCost.cpp	(revision 5eb3f65e95375f1be49b0bbe3338a9b4b1d26c67)
+++ src/ResolvExpr/CastCost.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -53,4 +53,15 @@
 		void postvisit( const ast::EnumInstType * enumInst ) {
 			cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
+
+			if (Cost::unsafe < cost) {
+				static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
+				Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
+				cost = intCost < cost? intCost: cost;
+			}
+			if ( enumInst->base->isTyped && enumInst->base->base ) {
+				auto baseConversionCost = 
+					castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
+				cost = baseConversionCost < cost? baseConversionCost: cost;
+			}
 		}
 
Index: src/ResolvExpr/ConversionCost.cpp
===================================================================
--- src/ResolvExpr/ConversionCost.cpp	(revision 5eb3f65e95375f1be49b0bbe3338a9b4b1d26c67)
+++ src/ResolvExpr/ConversionCost.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -162,5 +162,5 @@
 Cost conversionCost(
 	const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
-	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
+const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
 ) {
 	if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
@@ -284,5 +284,5 @@
 	if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
-	}	else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
+	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
 			cost = Cost::unsafe;
@@ -368,7 +368,8 @@
 		return;
 	}
-	static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
-	cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
+
 	if ( !inst->base->isTyped ) {
+		static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
+		cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
 		if ( cost < Cost::unsafe ) {
 			cost.incSafe();
@@ -376,5 +377,5 @@
 		return;
 	}
-	cost.incUnsafe();
+	// cost.incUnsafe();
 }
 
Index: src/ResolvExpr/Unify.cpp
===================================================================
--- src/ResolvExpr/Unify.cpp	(revision 5eb3f65e95375f1be49b0bbe3338a9b4b1d26c67)
+++ src/ResolvExpr/Unify.cpp	(revision d3aa55e994d9978b6eeed324d12124cd1e92a452)
@@ -276,6 +276,4 @@
 	void postvisit( const ast::VoidType * ) {
 		result = dynamic_cast< const ast::VoidType * >( type2 );
-			// || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
-		;
 	}
 
@@ -284,5 +282,4 @@
 			result = basic->kind == basic2->kind;
 		}
-		// result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -293,5 +290,4 @@
 				noWiden());
 		}
-		// result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -312,5 +308,4 @@
 		result = unifyExact(
 			array->base, array2->base, tenv, need, have, open, noWiden());
-			// || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -607,20 +602,16 @@
 
 		result = unifyList( types, types2, tenv, need, have, open );
-			// || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::VarArgsType * ) {
 		result = dynamic_cast< const ast::VarArgsType * >( type2 );
-			// || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::ZeroType * ) {
 		result = dynamic_cast< const ast::ZeroType * >( type2 );
-			// || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::OneType * ) {
 		result = dynamic_cast< const ast::OneType * >( type2 );
-			// || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
 	}
 };
