Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/AST/Fwd.hpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -133,5 +133,4 @@
 class OneType;
 class GlobalScopeType;
-class EnumAttrType;
 
 class Designation;
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/AST/Pass.hpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -207,5 +207,4 @@
 	const ast::Type *             visit( const ast::UnionInstType        * ) override final;
 	const ast::Type *             visit( const ast::EnumInstType         * ) override final;
-	const ast::Type *             visit( const ast::EnumAttrType         * ) override final;
 	const ast::Type *             visit( const ast::TraitInstType        * ) override final;
 	const ast::Type *             visit( const ast::TypeInstType         * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/AST/Pass.impl.hpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -1940,12 +1940,4 @@
 
 //--------------------------------------------------------------------------
-// EnumAttrType
-template< typename core_t >
-const ast::Type * ast::Pass< core_t >::visit( const ast::EnumAttrType * node ) {
-	VISIT_START( node );
-	VISIT_END( Type, node );
-}
-
-//--------------------------------------------------------------------------
 // TraitInstType
 template< typename core_t >
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/AST/Print.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -1576,18 +1576,4 @@
 	}
 
-	virtual const ast::Type * visit( const ast::EnumAttrType * node ) override final {
-		preprint( node );
-		os << "enum attr ";
-		if ( node->attr == ast::EnumAttribute::Label ) {
-			os << "Label ";
-		} else if ( node->attr == ast::EnumAttribute::Value ) {
-			os << "Value ";
-		} else {
-			os << "Posn ";
-		}
-		(*(node->instance)).accept( *this );
-		return node;
-	}
-
 	virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
 		preprint( node );
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/AST/Type.hpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -319,20 +319,4 @@
 using EnumInstType = SueInstType<EnumDecl>;
 
-class EnumAttrType final : public Type {
-public:
-	readonly<EnumInstType> instance;
-	EnumAttribute attr;
-	const Type * accept( Visitor & v ) const override { return v.visit( this ); }
-	EnumAttrType( const EnumInstType * instance, EnumAttribute attr = EnumAttribute::Posn )
-		: instance(instance), attr(attr) {}
-
-	bool match( const ast::EnumAttrType * other) const {
-		return instance->base->name == other->instance->base->name && attr == other->attr;
-	}
-private:
-	EnumAttrType * clone() const override { return new EnumAttrType{ *this }; }
-	MUTATE_FRIEND
-};
-
 /// An instance of a trait type.
 class TraitInstType final : public BaseInstType {
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/AST/Visitor.hpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -119,5 +119,4 @@
     virtual const ast::Type *             visit( const ast::OneType              * ) = 0;
     virtual const ast::Type *             visit( const ast::GlobalScopeType      * ) = 0;
-    virtual const ast::Type *             visit( const ast::EnumAttrType         * ) = 0;
     virtual const ast::Designation *      visit( const ast::Designation          * ) = 0;
     virtual const ast::Init *             visit( const ast::SingleInit           * ) = 0;
Index: src/CodeGen/GenType.cpp
===================================================================
--- src/CodeGen/GenType.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/CodeGen/GenType.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -47,5 +47,4 @@
 	void postvisit( ast::UnionInstType const * type );
 	void postvisit( ast::EnumInstType const * type );
-	void postvisit( ast::EnumAttrType const * type );
 	void postvisit( ast::TypeInstType const * type );
 	void postvisit( ast::TupleType const * type );
@@ -241,8 +240,4 @@
 }
 
-void GenType::postvisit( ast::EnumAttrType const * type ) {
-	postvisit( type->instance );
-}
-
 void GenType::postvisit( ast::TypeInstType const * type ) {
 	assertf( !options.genC, "TypeInstType should not reach code generation." );
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/Common/CodeLocationTools.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -188,5 +188,4 @@
     macro(UnionInstType, Type) \
     macro(EnumInstType, Type) \
-    macro(EnumAttrType, Type) \
     macro(TraitInstType, Type) \
     macro(TypeInstType, Type) \
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -906,5 +906,5 @@
 				}
 				CandidateRef & choice = winners.front();
-				choice->cost.incSafe();
+				choice->cost = Cost::unsafe;
 				candidates.emplace_back( std::move(choice) );
 			}
@@ -955,5 +955,7 @@
 
 		CandidateFinder funcFinder( context, tenv );
+		std::string funcName;
 		if (auto nameExpr = untypedExpr->func.as<ast::NameExpr>()) {
+			funcName = nameExpr->name;
 			auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
 			if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) {
@@ -1019,4 +1021,5 @@
 		CandidateList found;
 		SemanticErrorException errors;
+		
 		for ( CandidateRef & func : funcFinder ) {
 			try {
@@ -1093,4 +1096,5 @@
 			Cost cvtCost = computeApplicationConversionCost( withFunc, symtab );
 
+			if (funcName == "?|?") {
 			PRINT(
 				auto appExpr = withFunc->expr.strict_as< ast::ApplicationExpr >();
@@ -1108,5 +1112,5 @@
 				std::cerr << "cost of conversion is:" << cvtCost << std::endl;
 			)
-
+			}
 			if ( cvtCost != Cost::infinity ) {
 				withFunc->cvtCost = cvtCost;
@@ -1774,39 +1778,14 @@
 						matches.clear();
 					}
-					// ambiguous case, still output candidates to print in error message
-					if ( cand->cost == minExprCost && thisCost == minCastCost ) {
-						auto commonAsEnumAttr = common.as<ast::EnumAttrType>();
-						if ( commonAsEnumAttr && commonAsEnumAttr->attr == ast::EnumAttribute::Value ) {
-							auto callExpr = new ast::UntypedExpr(
-								cand->expr->location, new ast::NameExpr( cand->expr->location, "valueE"), {cand->expr} );
-							CandidateFinder finder( context, env );
-							finder.find( callExpr );
-							CandidateList winners = findMinCost( finder.candidates );
-							if (winners.size() != 1) {
-								SemanticError( callExpr, "Ambiguous expression in valueE..." );
-							}
-							CandidateRef & choice = winners.front();
-							// assert( valueCall->result );
-							CandidateRef newCand = std::make_shared<Candidate>(
-								new ast::InitExpr{
-									initExpr->location,
-									// restructureCast( cand->expr, toType ),
-									choice->expr,
-									initAlt.designation },
-								std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
-								inferParameters( newCand, matches );
-						} else {
-							CandidateRef newCand = std::make_shared<Candidate>(
-								new ast::InitExpr{
-									initExpr->location,
-									restructureCast( cand->expr, toType ),
-									initAlt.designation },
-								std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
-							// currently assertions are always resolved immediately so this should have no effect.
-							// if this somehow changes in the future (e.g. delayed by indeterminate return type)
-							// we may need to revisit the logic.
-							inferParameters( newCand, matches );
-						}
-					}
+					CandidateRef newCand = std::make_shared<Candidate>(
+						new ast::InitExpr{
+							initExpr->location,
+							restructureCast( cand->expr, toType ),
+							initAlt.designation },
+						std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
+					// currently assertions are always resolved immediately so this should have no effect.
+					// if this somehow changes in the future (e.g. delayed by indeterminate return type)
+					// we may need to revisit the logic.
+					inferParameters( newCand, matches );
 				}
 			}
Index: src/ResolvExpr/CommonType.cpp
===================================================================
--- src/ResolvExpr/CommonType.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/ResolvExpr/CommonType.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -388,16 +388,4 @@
 			const ast::EnumDecl* enumDecl = enumInst->base;
 			if ( !enumDecl->base ) {
-				ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
-				if (
-					( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
-						|| widen.first )
-					&& ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
-						|| widen.second )
-				) {
-					result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
-				}
-			}
-		} else if ( auto type2AsAttr = dynamic_cast< const ast::EnumAttrType * >( type2 ) ) {
-			if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) {
 				ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
 				if (
@@ -656,6 +644,4 @@
 	}
 
-	void postvisit( const ast::EnumAttrType * ) {}
-
 	void postvisit( const ast::TraitInstType * ) {}
 
Index: src/ResolvExpr/ConversionCost.cpp
===================================================================
--- src/ResolvExpr/ConversionCost.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/ResolvExpr/ConversionCost.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -279,8 +279,5 @@
 	if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
-	} else if ( dynamic_cast< const ast::EnumAttrType *>(dst) ) {
-		static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
-		cost = costCalc( basicType, integer, srcIsLvalue, symtab, env );
-	} 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;
@@ -373,34 +370,11 @@
 	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();
-	}
-}
-
-void ConversionCost::postvisit( const ast::EnumAttrType * src ) {
-	auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst);
-	assert( src->attr != ast::EnumAttribute::Label );
-	if ( src->attr == ast::EnumAttribute::Value ) {
-		if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) {
-			cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env );
-		} else {
-			auto baseType = src->instance->base->base;
-			cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
-			if ( cost < Cost::infinity ) {
-				cost.incUnsafe();
-			}
-		}
-	} else { // ast::EnumAttribute::Posn
-		if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
-			cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
-			if ( cost < Cost::unsafe ) cost.incSafe();
-		} else {
-			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();
-			}
-		}
-	}
+	if ( !inst->base->isTyped ) {
+		if ( cost < Cost::unsafe ) {
+			cost.incSafe();
+		}
+		return;
+	}
+	cost.incUnsafe();
 }
 
Index: src/ResolvExpr/ConversionCost.hpp
===================================================================
--- src/ResolvExpr/ConversionCost.hpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/ResolvExpr/ConversionCost.hpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -72,5 +72,4 @@
 	void postvisit( const ast::ZeroType * zeroType );
 	void postvisit( const ast::OneType * oneType );
-	void postvisit( const ast::EnumAttrType * posType );
 private:
 	// refactor for code resue
Index: src/ResolvExpr/Unify.cpp
===================================================================
--- src/ResolvExpr/Unify.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/ResolvExpr/Unify.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -275,6 +275,6 @@
 
 	void postvisit( const ast::VoidType * vt) {
-		result = dynamic_cast< const ast::VoidType * >( type2 )
-			|| tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
+		result = dynamic_cast< const ast::VoidType * >( type2 ); 
+			// || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
 		;
 	}
@@ -284,5 +284,5 @@
 			result = basic->kind == basic2->kind;
 		}
-		result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
+		// result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -293,5 +293,5 @@
 				noWiden());
 		}
-		result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
+		// result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -311,6 +311,6 @@
 
 		result = unifyExact(
-			array->base, array2->base, tenv, need, have, open, noWiden())
-			|| tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
+			array->base, array2->base, tenv, need, have, open, noWiden());
+			// || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -404,18 +404,4 @@
 	}
 
-	bool tryToUnifyWithEnumValue( const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
-		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
-		WidenMode widen) {
-		if ( auto attrType2 = dynamic_cast<const ast::EnumAttrType *>(type2)) {
-			if (attrType2->attr == ast::EnumAttribute::Value) {
-				return unifyExact( type1, attrType2->instance->base->base, env, need, have, open,
-					widen);
-			} else if (attrType2->attr == ast::EnumAttribute::Posn) {
-				return unifyExact( type1, attrType2->instance, env, need, have, open, widen );
-			}
-		}
-		return false;
-	}
-
 public:
 	void postvisit( const ast::FunctionType * func ) {
@@ -527,29 +513,16 @@
 	void postvisit( const ast::StructInstType * aggrType ) {
 		handleGenericRefType( aggrType, type2 );
-		result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::UnionInstType * aggrType ) {
 		handleGenericRefType( aggrType, type2 );
-		result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::EnumInstType * aggrType ) {
 		handleRefType( aggrType, type2 );
-		result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
-	}
-
-	void postvisit( const ast::EnumAttrType * enumAttr ) {
-		// Lazy approach for now
-		if ( auto otherPos = dynamic_cast< const ast::EnumAttrType *>( type2 ) ) {
-			if ( enumAttr->match(otherPos) ) {
-				result = otherPos;
-			}
-		}
 	}
 
 	void postvisit( const ast::TraitInstType * aggrType ) {
 		handleRefType( aggrType, type2 );
-		result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -560,5 +533,4 @@
 			this->result = otherInst;
 		}
-		result = result || tryToUnifyWithEnumValue(typeInst, type2, tenv, need, have, open, noWiden());
 	}
 
@@ -634,21 +606,21 @@
 		auto types2 = flatten( flat2 );
 
-		result = unifyList( types, types2, tenv, need, have, open )
-			|| tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
+		result = unifyList( types, types2, tenv, need, have, open );
+			// || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::VarArgsType * vat) {
-		result = dynamic_cast< const ast::VarArgsType * >( type2 )
-			|| tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
+		result = dynamic_cast< const ast::VarArgsType * >( type2 );
+			// || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::ZeroType * zt) {
-		result = dynamic_cast< const ast::ZeroType * >( type2 )
-			|| tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
+		result = dynamic_cast< const ast::ZeroType * >( type2 );
+			// || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
 	}
 
 	void postvisit( const ast::OneType * ot) {
-		result = dynamic_cast< const ast::OneType * >( type2 )
-			|| tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
+		result = dynamic_cast< const ast::OneType * >( type2 );
+			// || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
 	}
 };
Index: src/SymTab/Mangler.cpp
===================================================================
--- src/SymTab/Mangler.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/SymTab/Mangler.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -58,5 +58,4 @@
 	void postvisit( const ast::OneType * oneType );
 	void postvisit( const ast::QualifiedType * qualType );
-	void postvisit( const ast::EnumAttrType * posType );
 
 	/// The result is the current constructed mangled name.
@@ -278,22 +277,4 @@
 	assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
 	mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
-}
-
-void Mangler::postvisit( const ast::EnumAttrType * enumAttr ) {
-	postvisit( enumAttr->instance );
-	// mangleName += "_pos";
-	switch ( enumAttr->attr )
-	{
-		case ast::EnumAttribute::Label:
-			mangleName += "_label_";
-			break;
-		case ast::EnumAttribute::Posn:
-			mangleName += "_posn_";
-			break;
-		case ast::EnumAttribute::Value:
-			mangleName += "_value_";
-			break;
-	}
-
 }
 
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision 2c8946b85385514ba04b2c0df6e5c5bb5f4781df)
+++ src/Validate/ImplementEnumFunc.cpp	(revision 4fc7388ea88eb10cdb80bc09e77bf2758b6beb01)
@@ -72,16 +72,4 @@
 		ast::DeclWithType* decl = declPtr.get_and_mutate();
 		decl->attributes.push_back(new ast::Attribute("unused"));
-	}
-
-	ast::ObjectDecl* dstParam() const {
-		return new ast::ObjectDecl(getLocation(), "_dst",
-		                           new ast::ReferenceType(new ast::EnumAttrType(
-		                               ast::deepCopy(instType))));
-	}
-
-	ast::ObjectDecl* srcParam() const {
-		return new ast::ObjectDecl(
-			getLocation(), "_src",
-			new ast::EnumAttrType(ast::deepCopy(instType)));
 	}
 
@@ -329,8 +317,4 @@
 }
 
-inline ast::EnumAttrType * getPosnType( const ast::EnumDecl * decl ) {
-	return new ast::EnumAttrType(new ast::EnumInstType(decl), ast::EnumAttribute::Posn);
-}
-
 ast::ObjectDecl* EnumAttrFuncGenerator::genAttrArrayProto(
 	const ast::EnumAttribute attr, const CodeLocation& location,
@@ -360,6 +344,7 @@
 			func->location,
 			new ast::VariableExpr( func->location, func->params.front() ),
-			new ast::EnumAttrType( new ast::EnumInstType(decl),
-				ast::EnumAttribute::Posn))});
+			new ast::BasicType( ast::BasicKind::UnsignedInt ),
+			ast::GeneratedFlag::ExplicitCast
+		)});
 	func->stmts = new ast::CompoundStmt(
 		func->location, {new ast::ReturnStmt(func->location, untyped)});
@@ -370,6 +355,6 @@
 		func->location,
 		new ast::VariableExpr(func->location, func->params.front()),
-		new ast::EnumAttrType(new ast::EnumInstType(decl),
-							  ast::EnumAttribute::Posn));
+		new ast::BasicType( ast::BasicKind::UnsignedInt ),
+			ast::GeneratedFlag::ExplicitCast);
 	func->stmts = new ast::CompoundStmt(
 		func->location, {new ast::ReturnStmt(func->location, castExpr)});
