mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 14:24:10 +02:00
Fixed method selection by extern constraint specificity
This commit is contained in:
parent
d0d89a552e
commit
56bcb6ecd1
2 changed files with 93 additions and 3 deletions
|
@ -1000,6 +1000,46 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
RETURN_RESULTS;
|
||||
}
|
||||
|
||||
if ((newMethodInstance->mMethodDef->mExternalConstraints.size() != 0) || (prevMethodInstance->mMethodDef->mExternalConstraints.size() != 0))
|
||||
{
|
||||
struct GenericParamPair
|
||||
{
|
||||
BfGenericMethodParamInstance* mParams[2];
|
||||
GenericParamPair()
|
||||
{
|
||||
mParams[0] = NULL;
|
||||
mParams[1] = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
Dictionary<BfType*, GenericParamPair> externConstraints;
|
||||
|
||||
auto _GetParams = [&](int idx, BfMethodInstance* methodInstance)
|
||||
{
|
||||
for (int externConstraintIdx = 0; externConstraintIdx < (int)methodInstance->mMethodDef->mExternalConstraints.size(); externConstraintIdx++)
|
||||
{
|
||||
auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[methodInstance->mMethodDef->mGenericParams.size() + externConstraintIdx];
|
||||
BF_ASSERT(genericParam->mExternType != NULL);
|
||||
GenericParamPair* pairPtr = NULL;
|
||||
externConstraints.TryAdd(genericParam->mExternType, NULL, &pairPtr);
|
||||
pairPtr->mParams[idx] = genericParam;
|
||||
}
|
||||
};
|
||||
|
||||
_GetParams(0, newMethodInstance);
|
||||
_GetParams(0, prevMethodInstance);
|
||||
|
||||
for (auto kv : externConstraints)
|
||||
{
|
||||
SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(kv.mValue.mParams[1], kv.mValue.mParams[0]), mModule->AreConstraintsSubset(kv.mValue.mParams[0], kv.mValue.mParams[1]));
|
||||
}
|
||||
|
||||
if ((isBetter) || (isWorse))
|
||||
{
|
||||
RETURN_RESULTS;
|
||||
}
|
||||
}
|
||||
|
||||
// Does one have a body and one doesn't? Obvious!
|
||||
isBetter = prevMethodDef->IsEmptyPartial();
|
||||
isWorse = newMethodDef->IsEmptyPartial();
|
||||
|
|
50
IDEHelper/Tests/src/Generics2.bf
Normal file
50
IDEHelper/Tests/src/Generics2.bf
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Generics2
|
||||
{
|
||||
struct TestFunc<T, Del>
|
||||
{
|
||||
private int mId;
|
||||
private Del mComparer;
|
||||
|
||||
public static TestFunc<T, Del> Create(int id, Del comparer)
|
||||
{
|
||||
return .()
|
||||
{
|
||||
mId = id,
|
||||
mComparer = comparer
|
||||
};
|
||||
}
|
||||
|
||||
public bool CheckDlg(T item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CheckDlg(T item) where Del : delegate bool(T)
|
||||
{
|
||||
return mComparer(item);
|
||||
}
|
||||
|
||||
public bool CheckDlg(T item) where Del : delegate bool(int, T)
|
||||
{
|
||||
return mComparer(mId, item);
|
||||
}
|
||||
|
||||
public bool CallCheck(T val)
|
||||
{
|
||||
return CheckDlg(val);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
let testF = TestFunc<String, delegate bool(String)>.Create(10, scope (s) => s == "Str");
|
||||
Test.Assert(testF.CallCheck("Str"));
|
||||
Test.Assert(!testF.CallCheck("Str2"));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue