Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/AST/Decl.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -203,4 +203,7 @@
 }
 
+bool EnumDecl::isTyped() const { return base;}
+
+bool EnumDecl::isOpague() const { return isCfa && !isTyped(); } 
 }
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/AST/Decl.hpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -308,17 +308,17 @@
 class EnumDecl final : public AggregateDecl {
 public:
-	// isTyped indicated if the enum has a declaration like:
+	// isCfa indicated if the enum has a declaration like:
 	// enum (type_optional) Name {...}
-	bool isTyped;
-	// if isTyped == true && base.get() == nullptr, it is a "void" type enum
+	bool isCfa;
+	// if isCfa == true && base.get() == nullptr, it is a "opague" enum
 	ptr<Type> base;
 	enum class EnumHiding { Visible, Hide } hide;
 	std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
 
-	EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
+	EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false,
 		std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
 		Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
 		std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
-	: AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {}
+	: AggregateDecl( loc, name, std::move(attrs), linkage ), isCfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}
 
 	/// gets the integer value for this enumerator, returning true iff value found
@@ -336,4 +336,6 @@
 
 	bool isSubTypeOf(const ast::EnumDecl *) const;
+	bool isTyped() const;
+	bool isOpague() const;
 private:
 	EnumDecl * clone() const override { return new EnumDecl{ *this }; }
Index: src/ControlStruct/TranslateEnumRange.cpp
===================================================================
--- src/ControlStruct/TranslateEnumRange.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/ControlStruct/TranslateEnumRange.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -91,11 +91,14 @@
     ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
         "?<=?",
-        { 
-            ast::UntypedExpr::createCall(location, "posn", { new ast::NameExpr( location, indexName ) } ),
-            ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 )
-        });
+        {new ast::CastExpr(location,
+            new ast::NameExpr( location, indexName ),
+            new ast::BasicType( ast::BasicKind::UnsignedInt ),
+            ast::GeneratedFlag::ExplicitCast),
+        ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 ) });
+
     auto increment = ast::UntypedExpr::createCall( location, 
-        stmt->is_inc? "succ": "pred",
+        stmt->is_inc? "?++": "?--",
         { new ast::NameExpr( location, indexName ) });
+    
     auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
     auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
Index: src/Parser/TypeData.cpp
===================================================================
--- src/Parser/TypeData.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/Parser/TypeData.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -1469,6 +1469,6 @@
 		ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
 		object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
-		if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
-			SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
+		if ( ret->isOpague() && cur->has_enumeratorValue() ) {
+			SemanticError( td->location, "Opague cannot have an explicit initializer value." );
 		} else if ( cur->has_enumeratorValue() ) {
 			object->init = new ast::SingleInit(
Index: src/ResolvExpr/CastCost.cpp
===================================================================
--- src/ResolvExpr/CastCost.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/ResolvExpr/CastCost.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -54,10 +54,9 @@
 			cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
 
-			if (Cost::unsafe < cost) {
+			if ( !enumInst->base->isCfa ) {
 				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 ) {
+			} else if ( enumInst->base->isTyped() ) {
 				auto baseConversionCost = 
 					castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
@@ -74,7 +73,6 @@
 				cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
 				if ( Cost::unsafe < cost ) {
-					if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
-						// Always explict cast only for typed enum
-						if (enumInst->base->isTyped) cost = Cost::unsafe;
+					if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
+						cost = Cost::unsafe;
 					}
 				}
@@ -85,6 +83,6 @@
 			cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
 			if ( Cost::unsafe < cost ) {
-				if (auto enumInst =  dynamic_cast<const ast::EnumInstType *>(dst)) {
-					if (enumInst->base->isTyped) cost = Cost::unsafe;
+				if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
+					cost = Cost::unsafe;
 				}
 			}
@@ -94,6 +92,6 @@
 			cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
 			if ( Cost::unsafe < cost ) {
-				if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
-					if (enumInst->base->isTyped) cost = Cost::unsafe;
+				if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
+					cost = Cost::unsafe;
 				}
 			}
Index: src/ResolvExpr/CommonType.cpp
===================================================================
--- src/ResolvExpr/CommonType.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/ResolvExpr/CommonType.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -386,5 +386,5 @@
 		} else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
 			const ast::EnumDecl* enumDecl = enumInst->base;
-			if ( !enumDecl->base ) {
+			if ( !enumDecl->isCfa  ) {
 				ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
 				if (
@@ -642,5 +642,5 @@
 			const ast::EnumDecl* argDecl = argAsEnumInst->base;
 			if (argDecl->isSubTypeOf(paramDecl)) result = param;
-		} else if ( param->base && !param->base->isTyped ) {
+		} else if ( param->base && !param->base->isCfa ) {
 			auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
 			result = commonType( basicType, type2, tenv, need, have, open, widen);
Index: src/ResolvExpr/ConversionCost.cpp
===================================================================
--- src/ResolvExpr/ConversionCost.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/ResolvExpr/ConversionCost.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -235,9 +235,20 @@
 			return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
 		}
+		if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
+			if (srcAsInst->base && !srcAsInst->base->isCfa) {
+				static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
+				return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
+			}
+		}
 	} else {
 		assert( -1 == diff );
 		const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
 		assert( dstAsRef );
-		if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
+		auto dstBaseType = dstAsRef->base;
+		const ast::Type * newSrc = src;
+		if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
+			newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
+		}
+		if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
 			if ( srcIsLvalue ) {
 				if ( src->qualifiers == dstAsRef->base->qualifiers ) {
@@ -285,6 +296,6 @@
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
-			cost = Cost::unsafe;
+		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+			cost = Cost::safe;
 		}
 	}
@@ -366,14 +377,7 @@
 	if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
 		cost = enumCastCost(inst, dstInst, symtab, env);
-		return;
-	}
-
-	if ( !inst->base->isTyped ) {
+	} else if ( !inst->base->isCfa ) {
 		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();
-		}
-		return;
 	}
 	// cost.incUnsafe();
@@ -455,6 +459,6 @@
 		// assuming 0p is supposed to be used for pointers?
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
-			cost = Cost::unsafe;
+		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+			cost = Cost::safe;
 		}
 	}
@@ -476,6 +480,6 @@
 		}
 	} else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
-		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
-			cost = Cost::unsafe;
+		if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
+			cost = Cost::safe;
 		}
 	}
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision 7552fdeef475fdf78568b8832b5d1ae15b0f249a)
+++ src/Validate/ImplementEnumFunc.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
@@ -476,5 +476,5 @@
 
 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) {
-	if (!enumDecl->body || !enumDecl->isTyped) return;
+	if (!enumDecl->body || !enumDecl->isCfa) return;
 	ast::EnumInstType enumInst(enumDecl->name);
 	enumInst.base = enumDecl;
