1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-26 11:38:02 +02:00

Improvements to new conversion operator overload invoker

This commit is contained in:
Brian Fiete 2022-01-19 14:34:37 -05:00
parent 5267e18783
commit 7c6bdeffbe
4 changed files with 220 additions and 13 deletions

View file

@ -773,6 +773,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
anyIsExtension = true;
}
BfCastFlags implicitCastFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
int newMethodParamCount = newMethodInstance->GetParamCount();
int prevMethodParamCount = prevMethodInstance->GetParamCount();
@ -794,6 +796,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
bool someArgWasBetter = false;
bool someArgWasWorse = false;
for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++)
{
BfTypedValue arg;
@ -856,8 +859,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
{
prevParamWasConstExpr = true;
prevParamType = ((BfConstExprValueType*)prevParamType)->mType;
}
}
bool paramsEquivalent = paramType == prevParamType;
if ((prevParamType == NULL) || (paramType == NULL))
@ -871,6 +874,14 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
(!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
{
// Pick the one that can implicitly cast
SET_BETTER_OR_WORSE(
mModule->CanCast(arg, paramType, implicitCastFlags),
mModule->CanCast(arg, prevParamType, implicitCastFlags));
}
// Why did we have this !isUnspecializedParam check? We need the 'canCast' logic still
if ((!isBetter) && (!isWorse) /*&& (!isUnspecializedParam) && (!isPrevUnspecializedParam)*/)
{
@ -887,8 +898,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
isWorse = true;
else
{
bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(paramType), prevParamType);
bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevParamType), paramType);
bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(paramType), prevParamType, implicitCastFlags);
bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevParamType), paramType, implicitCastFlags);
if ((canCastFromCurToPrev) && (canCastFromPrevToCur))
paramsEquivalent = true;
@ -983,6 +994,37 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
RETURN_RESULTS;
}
}
// Choose by return type for conversion operators
if (((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) && (!isBetter) && (!isWorse))
{
auto returnType = newMethodInstance->mReturnType;
auto prevReturnType = prevMethodInstance->mReturnType;
if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
{
// Pick the one that can implicitly cast
SET_BETTER_OR_WORSE(
mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, implicitCastFlags),
mModule->CanCast(mModule->GetFakeTypedValue(prevReturnType), mCheckReturnType, implicitCastFlags));
}
if ((!isBetter) && (!isWorse))
{
bool canCastFromCurToPrev = mModule->CanCast(mModule->GetFakeTypedValue(returnType), prevReturnType, implicitCastFlags);
bool canCastFromPrevToCur = mModule->CanCast(mModule->GetFakeTypedValue(prevReturnType), returnType, implicitCastFlags);
if ((canCastFromCurToPrev) && (!canCastFromPrevToCur))
isWorse = true;
else if ((canCastFromPrevToCur) && (!canCastFromCurToPrev))
isBetter = true;
}
if ((isBetter) || (isWorse))
{
RETURN_RESULTS;
}
}
// Check for unused extended params as next param - that still counts as using extended form
usedExtendedForm = newMethodInstance->HasParamsArray();

View file

@ -12649,9 +12649,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
}
}
}
methodMatcher.FlushAmbiguityError();
if (methodMatcher.mBestMethodDef != NULL)
{
if (mayBeBox)
@ -12755,12 +12753,30 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
if (moduleMethodInstance.mMethodInstance != NULL)
{
auto returnType = moduleMethodInstance.mMethodInstance->mReturnType;
if (typedVal.mType->IsTypedPrimitive())
{
auto paramType = moduleMethodInstance.mMethodInstance->GetParamType(0);
BfCastFlags implicitCastFlags = (BfCastFlags)(castFlags & ~BfCastFlags_Explicit | BfCastFlags_NoConversionOperator);
// Check typedPrimitive->underlying cast
if ((explicitCast) && (typedVal.mType->IsTypedPrimitive()))
{
auto underlyingType = typedVal.mType->GetUnderlyingType();
if ((returnType != underlyingType) && (CanCast(GetFakeTypedValue(underlyingType), toType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))))
{
if ((CanCast(GetFakeTypedValue(underlyingType), returnType)) &&
float underlyingCanCast = CanCast(GetFakeTypedValue(underlyingType), toType, implicitCastFlags);
float returnCanCast = CanCast(GetFakeTypedValue(returnType), toType, implicitCastFlags);
if ((underlyingCanCast) &&
(!returnCanCast))
{
doCall = false;
}
else if ((returnCanCast) &&
(!underlyingCanCast))
{
doCall = true;
}
else if ((CanCast(GetFakeTypedValue(underlyingType), returnType, implicitCastFlags)) &&
(!CanCast(GetFakeTypedValue(returnType), underlyingType)))
{
doCall = true;
@ -12770,9 +12786,26 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
}
}
// Check underlying->typedPrimitive cast
if ((explicitCast) && (toType->IsTypedPrimitive()))
{
auto underlyingType = toType->GetUnderlyingType();
if ((paramType != underlyingType) && (CanCast(typedVal, underlyingType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))))
{
if ((CanCast(GetFakeTypedValue(underlyingType), paramType, implicitCastFlags)) &&
(!CanCast(GetFakeTypedValue(paramType), underlyingType, implicitCastFlags)))
{
doCall = true;
}
else
doCall = false;
}
}
if (doCall)
{
auto paramType = moduleMethodInstance.mMethodInstance->GetParamType(0);
methodMatcher.FlushAmbiguityError();
auto wantType = paramType;
if (wantType->IsRef())
wantType = wantType->GetUnderlyingType();

View file

@ -900,8 +900,8 @@ public:
{
if (mOperatorDeclaration->mExplicitToken != NULL)
return mOperatorDeclaration->mExplicitToken->mToken == BfToken_Explicit;
if (mOperatorDeclaration->mOperatorToken != NULL)
return mOperatorDeclaration->mOperatorToken->mToken == BfToken_Explicit;
if (mOperatorDeclaration->mOpTypeToken != NULL)
return mOperatorDeclaration->mOpTypeToken->mToken == BfToken_Explicit;
return false;
}
};