1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-15 23:04:09 +02:00

Fixed const expr preference in method selection

This commit is contained in:
Brian Fiete 2020-08-01 12:16:17 -07:00
parent fb960747ec
commit 91dea6cd3b
2 changed files with 69 additions and 13 deletions

View file

@ -678,6 +678,9 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
bool betterByGenericParam = false;
bool worseByGenericParam = false;
bool betterByConstExprParam = false;
bool worseByConstExprParam = false;
for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++)
{
BfTypedValue arg;
@ -708,12 +711,20 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
BfType* origParamType = paramType;
BfType* origPrevParamType = prevParamType;
bool paramWasConstExpr = false;
bool prevParamWasConstExpr = false;
bool paramWasUnspecialized = paramType->IsUnspecializedType();
if ((genericArgumentsSubstitute != NULL) && (paramWasUnspecialized))
{
paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, allowSpecializeFail);
paramType = mModule->FixIntUnknown(paramType);
}
if (paramType->IsConstExprValue())
{
prevParamWasConstExpr = true;
paramType = ((BfConstExprValueType*)paramType)->mType;
}
bool prevParamWasUnspecialized = prevParamType->IsUnspecializedType();
if ((prevGenericArgumentsSubstitute != NULL) && (prevParamWasUnspecialized))
@ -721,6 +732,11 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, allowSpecializeFail);
prevParamType = mModule->FixIntUnknown(prevParamType);
}
if (prevParamType->IsConstExprValue())
{
prevParamWasConstExpr = true;
prevParamType = ((BfConstExprValueType*)prevParamType)->mType;
}
bool paramsEquivalent = paramType == prevParamType;
@ -735,9 +751,6 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
(!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
if ((!isBetter) && (!isWorse))
SET_BETTER_OR_WORSE(paramType->IsConstExprValue(), prevParamType->IsConstExprValue());
if ((!isBetter) && (!isWorse) && (!isUnspecializedParam) && (!isPrevUnspecializedParam))
{
SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
@ -785,8 +798,13 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
}
}
if (((!isBetter) && (!isWorse)) && (paramsEquivalent) &&
((paramWasUnspecialized) || (prevParamWasUnspecialized)))
if ((!isBetter) & (!isWorse) && (paramsEquivalent))
{
if ((origParamType != origPrevParamType) && (paramWasConstExpr) && (!prevParamWasConstExpr))
betterByConstExprParam = true;
else if ((origParamType != origPrevParamType) && (!paramWasConstExpr) && (prevParamWasConstExpr))
worseByConstExprParam = true;
else if (((paramWasUnspecialized) || (prevParamWasUnspecialized)))
{
int origTypeMoreSpecific = GetMostSpecificType(origParamType, origPrevParamType);
if (origTypeMoreSpecific == 0)
@ -794,6 +812,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
else if (origTypeMoreSpecific == 1)
worseByGenericParam = true;
}
}
if ((newArgIdx >= 0) && (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params))
usedExtendedForm = true;
@ -815,6 +834,17 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
}
}
if ((!isBetter) && (!isWorse))
{
// Don't allow ambiguity
if ((betterByConstExprParam && !worseByConstExprParam) ||
(!betterByConstExprParam && worseByConstExprParam))
{
isBetter = betterByConstExprParam;
isWorse = worseByConstExprParam;
}
}
if ((isBetter) || (isWorse))
{
RETURN_RESULTS;

View file

@ -81,6 +81,26 @@ namespace Tests
return 2;
}
public static int MethodE<T>(T val, int val2)
{
return 1;
}
public static int MethodE<T, TVal>(T val, TVal val2) where TVal : const int
{
return 2;
}
public static int MethodE<T>(List<T> val, int val2)
{
return 3;
}
public static int MethodE<T, TVal>(List<T> val, TVal val2) where TVal : const int
{
return 4;
}
[Test]
public static void TestBasics()
{
@ -115,8 +135,14 @@ namespace Tests
Test.Assert(MethodB(("A", "B")) == 3);
Test.Assert(MethodC(("A", "B")) == 3);
int[][] arrArr = new int[1][];
int[][] arrArr = scope int[1][];
Test.Assert(MethodD(ref arrArr) == 2);
int a = 100;
Test.Assert(MethodE(sa, a) == 1);
Test.Assert(MethodE(sa, 100) == 2);
Test.Assert(MethodE(sal, a) == 3);
Test.Assert(MethodE(sal, 200) == 4);
}
}
}