Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision a55ebcca1b712f00e2fd94a9d348511dd62c8f8a)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 0522ebe7b3ae7204a1d2c50a1bc7273bfa36762a)
@@ -893,17 +893,60 @@
 		} 
 		else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
-			// The Attribute Arrays are not yet generated, need to proxy them
-			// as attribute function call
-			const CodeLocation & location = cand->expr->location;
-			if ( enumInst->base && enumInst->base->base ) {
-				auto valueName = new ast::NameExpr(location, "valueE");
-				auto untypedValueCall = new ast::UntypedExpr( 
-					location, valueName, { aggrExpr } );
-				auto result = ResolvExpr::findVoidExpression( untypedValueCall, context );
-				assert( result.get() );
-				CandidateRef newCand = std::make_shared<Candidate>(
-					*cand, result, Cost::safe );
-				candidates.emplace_back( std::move( newCand ) );
-			}
+			if (enumInst->base && enumInst->base->base) {
+            const CodeLocation &location = cand->expr->location;
+
+            CandidateFinder funcFinder(context, tenv);
+            auto nameExpr = new ast::NameExpr(location, "valueE");
+            ResolveMode mode = {true, false, selfFinder.candidates.empty()};
+            funcFinder.find( nameExpr, mode );
+
+            // make variableExpr itself the candidate for the value Call
+            ExplodedArgs argExpansions;
+            argExpansions.emplace_back();
+            auto &argE = argExpansions.back();
+
+            argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value
+
+            CandidateList found;
+            SemanticErrorException errors;
+
+            for (CandidateRef &func : funcFinder) {
+                try {
+                    const ast::Type *funcResult =
+                        func->expr->result->stripReferences();
+                    if (auto pointer = dynamic_cast<const ast::PointerType *>(
+                            funcResult)) {
+                        if (auto function =
+                                pointer->base.as<ast::FunctionType>()) {
+                            CandidateRef newFunc{new Candidate{*func}};
+                            newFunc->expr = referenceToRvalueConversion(
+                                newFunc->expr, newFunc->cost);
+                            makeFunctionCandidates( location,
+                                                   newFunc, function,
+                                                   argExpansions, found );
+                        }
+                    }
+                } catch (SemanticErrorException &e) {
+                    std::cerr
+                        << "Resolving value function should cause an error"
+                        << std::endl;
+                    errors.append(e);
+                }
+            }
+
+            if (found.empty()) {
+                std::cerr << "Resolve value function should always success"
+                          << std::endl;
+            }
+
+            for (CandidateRef &withFunc : found) {
+                withFunc->cost.incSafe();
+                Cost cvtCost =
+                    computeApplicationConversionCost(withFunc, symtab);
+                assert(cvtCost != Cost::infinity);
+
+                candidates.emplace_back(std::move(withFunc));
+            }
+        }
 		}
 	}
@@ -1401,8 +1444,70 @@
 	}
 
-	void Finder::postvisit( const ast::VariableExpr * variableExpr ) {
-		// not sufficient to just pass `variableExpr` here, type might have changed since
-		addCandidate( variableExpr, tenv );		
-	}
+    void Finder::postvisit(const ast::VariableExpr *variableExpr) {
+        // not sufficient to just pass `variableExpr` here, type might have changed
+
+        auto cand = new Candidate(variableExpr, tenv);
+        candidates.emplace_back(cand);
+
+        if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(
+                variableExpr->var->get_type())) {
+            if (enumInst->base && enumInst->base->base) {
+                const CodeLocation &location = cand->expr->location;
+
+                CandidateFinder funcFinder(context, tenv);
+                auto nameExpr = new ast::NameExpr(location, "valueE");
+                ResolveMode mode = {true, false, selfFinder.candidates.empty()};
+                funcFinder.find( nameExpr, mode );
+
+                // make variableExpr itself the candidate for the value Call
+                ExplodedArgs argExpansions;
+                argExpansions.emplace_back();
+                auto &argE = argExpansions.back();
+
+                argE.emplace_back(*cand, symtab);
+
+                CandidateList found;
+                SemanticErrorException errors;
+
+                for (CandidateRef &func : funcFinder) {
+                    try {
+                    const ast::Type *funcResult =
+                        func->expr->result->stripReferences();
+                    if (auto pointer = dynamic_cast<const ast::PointerType *>(
+                            funcResult)) {
+                        if (auto function =
+                                pointer->base.as<ast::FunctionType>()) {
+                            CandidateRef newFunc{new Candidate{*func}};
+                            newFunc->expr = referenceToRvalueConversion(
+                                newFunc->expr, newFunc->cost);
+                            makeFunctionCandidates(variableExpr->location,
+                                                   newFunc, function,
+                                                   argExpansions, found);
+                        }
+                    }
+                    } catch (SemanticErrorException &e) {
+                        std::cerr
+                            << "Resolving value function should cause an error"
+                            << std::endl;
+                        errors.append(e);
+                    }
+                }
+
+                if (found.empty()) {
+                    std::cerr << "Resolve value function should always success"
+                            << std::endl;
+                }
+
+                for (CandidateRef &withFunc : found) {
+                    withFunc->cost.incSafe();
+                    Cost cvtCost =
+                        computeApplicationConversionCost(withFunc, symtab);
+                    assert(cvtCost != Cost::infinity);
+
+                    candidates.emplace_back(std::move(withFunc));
+                }
+            }
+        }
+    }
 
 	void Finder::postvisit( const ast::ConstantExpr * constantExpr ) {
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision a55ebcca1b712f00e2fd94a9d348511dd62c8f8a)
+++ src/ResolvExpr/CommonType.cc	(revision 0522ebe7b3ae7204a1d2c50a1bc7273bfa36762a)
@@ -397,4 +397,14 @@
 					result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
 				}
+			}
+		} else if ( const ast::EnumPosType * pos = dynamic_cast< const ast::EnumPosType * >( type2 ) ) {
+			ast::BasicType::Kind kind = commonTypes[ basic->kind ][ ast::BasicType::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 };
 			}
 		}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision a55ebcca1b712f00e2fd94a9d348511dd62c8f8a)
+++ src/ResolvExpr/ConversionCost.cc	(revision 0522ebe7b3ae7204a1d2c50a1bc7273bfa36762a)
@@ -278,9 +278,11 @@
 	if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
 		conversionCostFromBasicToBasic( basicType, dstAsBasic );
-	} else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
+	} 
+	else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		auto enumDecl = enumInst->base;
-		if ( auto baseType = enumDecl->base.get() ) {
-			cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
-			cost.incUnsafe();
+		if ( enumDecl->base.get() ) {
+			// cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
+			// cost.incUnsafe();
+			cost = Cost::infinity;
 		} else {
             cost = Cost::unsafe;
@@ -365,4 +367,12 @@
 	cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
 	// }
+	if ( cost < Cost::unsafe ) {
+		cost.incSafe();
+	}
+}
+
+void ConversionCost::postvisit( const ast::EnumPosType * ) {
+	static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
+	cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
 	if ( cost < Cost::unsafe ) {
 		cost.incSafe();
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision a55ebcca1b712f00e2fd94a9d348511dd62c8f8a)
+++ src/ResolvExpr/ConversionCost.h	(revision 0522ebe7b3ae7204a1d2c50a1bc7273bfa36762a)
@@ -72,4 +72,5 @@
 	void postvisit( const ast::ZeroType * zeroType );
 	void postvisit( const ast::OneType * oneType );
+	void postvisit( const ast::EnumPosType * posType );
 private:
 	// refactor for code resue
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision a55ebcca1b712f00e2fd94a9d348511dd62c8f8a)
+++ src/ResolvExpr/Unify.cc	(revision 0522ebe7b3ae7204a1d2c50a1bc7273bfa36762a)
@@ -517,4 +517,9 @@
 		}
 
+		void postvisit( const ast::EnumPosType * posType ) {
+			// Does nothing for now. Handled in ReplacePseudoFunc
+			// Might move here in the future
+		}
+
 		void postvisit( const ast::TraitInstType * aggrType ) {
 			handleRefType( aggrType, type2 );
