mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-16 07:14:09 +02:00
Fixed const expr preference in method selection
This commit is contained in:
parent
fb960747ec
commit
91dea6cd3b
2 changed files with 69 additions and 13 deletions
|
@ -678,6 +678,9 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
bool betterByGenericParam = false;
|
bool betterByGenericParam = false;
|
||||||
bool worseByGenericParam = false;
|
bool worseByGenericParam = false;
|
||||||
|
|
||||||
|
bool betterByConstExprParam = false;
|
||||||
|
bool worseByConstExprParam = false;
|
||||||
|
|
||||||
for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++)
|
for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++)
|
||||||
{
|
{
|
||||||
BfTypedValue arg;
|
BfTypedValue arg;
|
||||||
|
@ -708,12 +711,20 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
BfType* origParamType = paramType;
|
BfType* origParamType = paramType;
|
||||||
BfType* origPrevParamType = prevParamType;
|
BfType* origPrevParamType = prevParamType;
|
||||||
|
|
||||||
|
bool paramWasConstExpr = false;
|
||||||
|
bool prevParamWasConstExpr = false;
|
||||||
|
|
||||||
bool paramWasUnspecialized = paramType->IsUnspecializedType();
|
bool paramWasUnspecialized = paramType->IsUnspecializedType();
|
||||||
if ((genericArgumentsSubstitute != NULL) && (paramWasUnspecialized))
|
if ((genericArgumentsSubstitute != NULL) && (paramWasUnspecialized))
|
||||||
{
|
{
|
||||||
paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, allowSpecializeFail);
|
paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, allowSpecializeFail);
|
||||||
paramType = mModule->FixIntUnknown(paramType);
|
paramType = mModule->FixIntUnknown(paramType);
|
||||||
}
|
}
|
||||||
|
if (paramType->IsConstExprValue())
|
||||||
|
{
|
||||||
|
prevParamWasConstExpr = true;
|
||||||
|
paramType = ((BfConstExprValueType*)paramType)->mType;
|
||||||
|
}
|
||||||
|
|
||||||
bool prevParamWasUnspecialized = prevParamType->IsUnspecializedType();
|
bool prevParamWasUnspecialized = prevParamType->IsUnspecializedType();
|
||||||
if ((prevGenericArgumentsSubstitute != NULL) && (prevParamWasUnspecialized))
|
if ((prevGenericArgumentsSubstitute != NULL) && (prevParamWasUnspecialized))
|
||||||
|
@ -721,6 +732,11 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, allowSpecializeFail);
|
prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, allowSpecializeFail);
|
||||||
prevParamType = mModule->FixIntUnknown(prevParamType);
|
prevParamType = mModule->FixIntUnknown(prevParamType);
|
||||||
}
|
}
|
||||||
|
if (prevParamType->IsConstExprValue())
|
||||||
|
{
|
||||||
|
prevParamWasConstExpr = true;
|
||||||
|
prevParamType = ((BfConstExprValueType*)prevParamType)->mType;
|
||||||
|
}
|
||||||
|
|
||||||
bool paramsEquivalent = paramType == prevParamType;
|
bool paramsEquivalent = paramType == prevParamType;
|
||||||
|
|
||||||
|
@ -735,9 +751,6 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
|
SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()),
|
||||||
(!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
|
(!isPrevUnspecializedParam) && (!prevParamType->IsVar()));
|
||||||
|
|
||||||
if ((!isBetter) && (!isWorse))
|
|
||||||
SET_BETTER_OR_WORSE(paramType->IsConstExprValue(), prevParamType->IsConstExprValue());
|
|
||||||
|
|
||||||
if ((!isBetter) && (!isWorse) && (!isUnspecializedParam) && (!isPrevUnspecializedParam))
|
if ((!isBetter) && (!isWorse) && (!isUnspecializedParam) && (!isPrevUnspecializedParam))
|
||||||
{
|
{
|
||||||
SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
|
SET_BETTER_OR_WORSE((paramType != NULL) && (!paramType->IsUnspecializedType()),
|
||||||
|
@ -785,8 +798,13 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((!isBetter) && (!isWorse)) && (paramsEquivalent) &&
|
if ((!isBetter) & (!isWorse) && (paramsEquivalent))
|
||||||
((paramWasUnspecialized) || (prevParamWasUnspecialized)))
|
{
|
||||||
|
if ((origParamType != origPrevParamType) && (paramWasConstExpr) && (!prevParamWasConstExpr))
|
||||||
|
betterByConstExprParam = true;
|
||||||
|
else if ((origParamType != origPrevParamType) && (!paramWasConstExpr) && (prevParamWasConstExpr))
|
||||||
|
worseByConstExprParam = true;
|
||||||
|
else if (((paramWasUnspecialized) || (prevParamWasUnspecialized)))
|
||||||
{
|
{
|
||||||
int origTypeMoreSpecific = GetMostSpecificType(origParamType, origPrevParamType);
|
int origTypeMoreSpecific = GetMostSpecificType(origParamType, origPrevParamType);
|
||||||
if (origTypeMoreSpecific == 0)
|
if (origTypeMoreSpecific == 0)
|
||||||
|
@ -794,6 +812,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
else if (origTypeMoreSpecific == 1)
|
else if (origTypeMoreSpecific == 1)
|
||||||
worseByGenericParam = true;
|
worseByGenericParam = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((newArgIdx >= 0) && (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params))
|
if ((newArgIdx >= 0) && (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params))
|
||||||
usedExtendedForm = true;
|
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))
|
if ((isBetter) || (isWorse))
|
||||||
{
|
{
|
||||||
RETURN_RESULTS;
|
RETURN_RESULTS;
|
||||||
|
|
|
@ -81,6 +81,26 @@ namespace Tests
|
||||||
return 2;
|
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]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -115,8 +135,14 @@ namespace Tests
|
||||||
Test.Assert(MethodB(("A", "B")) == 3);
|
Test.Assert(MethodB(("A", "B")) == 3);
|
||||||
Test.Assert(MethodC(("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);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue