mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Fixed cases of undetected ambiguous calls
This commit is contained in:
parent
e8b35ce0c4
commit
4cea33d96f
6 changed files with 94 additions and 14 deletions
|
@ -23,6 +23,11 @@ WaitForResolve()
|
||||||
SleepTicks(20)
|
SleepTicks(20)
|
||||||
AssertFileErrors()
|
AssertFileErrors()
|
||||||
|
|
||||||
|
ShowFile("src/Methods.bf")
|
||||||
|
WaitForResolve()
|
||||||
|
SleepTicks(20)
|
||||||
|
AssertFileErrors()
|
||||||
|
|
||||||
ShowFile("src/Properties.bf")
|
ShowFile("src/Properties.bf")
|
||||||
WaitForResolve()
|
WaitForResolve()
|
||||||
SleepTicks(20)
|
SleepTicks(20)
|
||||||
|
|
47
IDE/Tests/CompileFail001/src/Methods.bf
Normal file
47
IDE/Tests/CompileFail001/src/Methods.bf
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace IDETest
|
||||||
|
{
|
||||||
|
class Methods
|
||||||
|
{
|
||||||
|
public class ClassA
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClassB
|
||||||
|
{
|
||||||
|
public static implicit operator ClassA(ClassB zongo)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MethodA(ClassA zong, int arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MethodA(ClassB zong, params Object[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MethodB(ClassB zong, params Object[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MethodB(ClassA zong, int arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Test()
|
||||||
|
{
|
||||||
|
ClassB cb = scope .();
|
||||||
|
MethodA(cb, 123); //FAIL
|
||||||
|
MethodB(cb, 234); //FAIL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -718,10 +718,13 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
bool betterByConstExprParam = false;
|
bool betterByConstExprParam = false;
|
||||||
bool worseByConstExprParam = false;
|
bool worseByConstExprParam = false;
|
||||||
|
|
||||||
|
bool someArgWasBetter = false;
|
||||||
|
bool someArgWasWorse = 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;
|
||||||
BfResolvedArg* resolvedArg = NULL;
|
BfResolvedArg* resolvedArg = NULL;
|
||||||
|
bool wasArgDeferred = false;
|
||||||
|
|
||||||
if (argIdx == -1)
|
if (argIdx == -1)
|
||||||
{
|
{
|
||||||
|
@ -730,6 +733,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resolvedArg = &mArguments[argIdx];
|
resolvedArg = &mArguments[argIdx];
|
||||||
|
wasArgDeferred = resolvedArg->mArgFlags != 0;
|
||||||
arg = resolvedArg->mTypedValue;
|
arg = resolvedArg->mTypedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,8 +743,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
bool wasGenericParam = (newArgIdx >= 0) && newMethodInstance->WasGenericParam(newArgIdx);
|
bool wasGenericParam = (newArgIdx >= 0) && newMethodInstance->WasGenericParam(newArgIdx);
|
||||||
bool prevWasGenericParam = (prevArgIdx >= 0) && prevMethodInstance->WasGenericParam(prevArgIdx);
|
bool prevWasGenericParam = (prevArgIdx >= 0) && prevMethodInstance->WasGenericParam(prevArgIdx);
|
||||||
|
|
||||||
BfType* paramType = newMethodInstance->GetParamType(newArgIdx);
|
BfType* paramType = newMethodInstance->GetParamType(newArgIdx, true);
|
||||||
BfType* prevParamType = prevMethodInstance->GetParamType(prevArgIdx);
|
BfType* prevParamType = prevMethodInstance->GetParamType(prevArgIdx, true);
|
||||||
|
|
||||||
numUsedParams++;
|
numUsedParams++;
|
||||||
prevNumUsedParams++;
|
prevNumUsedParams++;
|
||||||
|
@ -796,9 +800,10 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
{
|
{
|
||||||
// The resolved argument type may actually match for both considered functions. IE:
|
// The resolved argument type may actually match for both considered functions. IE:
|
||||||
// Method(int8 val) and Method(int16 val) called with Method(0) will create arguments that match their param types
|
// Method(int8 val) and Method(int16 val) called with Method(0) will create arguments that match their param types
|
||||||
if ((!wasGenericParam) && (IsType(arg, paramType)) && ((resolvedArg == NULL) || (prevParamType != resolvedArg->mBestBoundType)))
|
if ((!wasArgDeferred) && (!wasGenericParam) && (IsType(arg, paramType)) && ((resolvedArg == NULL) || (prevParamType != resolvedArg->mBestBoundType)))
|
||||||
isBetter = true;
|
isBetter = true;
|
||||||
else if ((!prevWasGenericParam) && (IsType(arg, prevParamType)) && (!IsType(arg, paramType)))
|
//else if ((!prevWasGenericParam) && (IsType(arg, prevParamType)) && (!IsType(arg, paramType)))
|
||||||
|
else if ((!wasArgDeferred) && (!prevWasGenericParam) && (IsType(arg, prevParamType)) && ((resolvedArg == NULL) || (paramType != resolvedArg->mBestBoundType)))
|
||||||
isWorse = true;
|
isWorse = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -830,6 +835,10 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
isWorse = true;
|
isWorse = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((wasArgDeferred) && ((paramType->IsIntegral()) || (prevParamType->IsIntegral())))
|
||||||
|
{
|
||||||
|
SET_BETTER_OR_WORSE(paramType->IsIntegral(), prevParamType->IsIntegral());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -858,7 +867,14 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
|
|
||||||
if ((usedExtendedForm) || (prevUsedExtendedForm))
|
if ((usedExtendedForm) || (prevUsedExtendedForm))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
someArgWasBetter |= isBetter;
|
||||||
|
someArgWasWorse |= isWorse;
|
||||||
|
isBetter = false;
|
||||||
|
isWorse = false;
|
||||||
}
|
}
|
||||||
|
isBetter |= someArgWasBetter;
|
||||||
|
isWorse |= someArgWasWorse;
|
||||||
|
|
||||||
if ((!isBetter) && (!isWorse))
|
if ((!isBetter) && (!isWorse))
|
||||||
{
|
{
|
||||||
|
@ -1870,6 +1886,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
BF_ASSERT(!ambiguousEntry.mBestMethodGenericArguments.empty());
|
BF_ASSERT(!ambiguousEntry.mBestMethodGenericArguments.empty());
|
||||||
}
|
}
|
||||||
mAmbiguousEntries.push_back(ambiguousEntry);
|
mAmbiguousEntries.push_back(ambiguousEntry);
|
||||||
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16339,14 +16339,12 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
||||||
|
|
||||||
bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
|
bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
|
||||||
|
|
||||||
BfType* unresolvedType = methodInstance->GetParamType(paramIdx, false);
|
auto resolvedType = methodInstance->GetParamType(paramIdx);
|
||||||
if (unresolvedType == NULL)
|
if (resolvedType == NULL)
|
||||||
{
|
{
|
||||||
AssertErrorState();
|
AssertErrorState();
|
||||||
unresolvedType = mContext->mBfObjectType;
|
|
||||||
paramVar->mParamFailed = true;
|
paramVar->mParamFailed = true;
|
||||||
}
|
}
|
||||||
auto resolvedType = methodInstance->GetParamType(paramIdx, true);
|
|
||||||
prevIgnoreErrors.Restore();
|
prevIgnoreErrors.Restore();
|
||||||
PopulateType(resolvedType, BfPopulateType_Declaration);
|
PopulateType(resolvedType, BfPopulateType_Declaration);
|
||||||
paramVar->mResolvedType = resolvedType;
|
paramVar->mResolvedType = resolvedType;
|
||||||
|
|
|
@ -868,7 +868,7 @@ String BfMethodInstance::GetParamName(int paramIdx)
|
||||||
return paramName;
|
return paramName;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
|
BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParamsType)
|
||||||
{
|
{
|
||||||
if (paramIdx == -1)
|
if (paramIdx == -1)
|
||||||
{
|
{
|
||||||
|
@ -892,6 +892,19 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
|
||||||
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
|
||||||
return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
|
return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (returnUnderlyingParamsType)
|
||||||
|
{
|
||||||
|
BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
|
||||||
|
if (paramDef->mParamKind == BfParamKind_Params)
|
||||||
|
{
|
||||||
|
auto underlyingType = methodParam->mResolvedType->GetUnderlyingType();
|
||||||
|
if (underlyingType != NULL)
|
||||||
|
return underlyingType;
|
||||||
|
return methodParam->mResolvedType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return methodParam->mResolvedType;
|
return methodParam->mResolvedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -902,7 +902,7 @@ public:
|
||||||
int GetImplicitParamCount();
|
int GetImplicitParamCount();
|
||||||
void GetParamName(int paramIdx, StringImpl& name);
|
void GetParamName(int paramIdx, StringImpl& name);
|
||||||
String GetParamName(int paramIdx);
|
String GetParamName(int paramIdx);
|
||||||
BfType* GetParamType(int paramIdx, bool useResolvedType = true);
|
BfType* GetParamType(int paramIdx, bool returnUnderlyingParamsType = false);
|
||||||
bool GetParamIsSplat(int paramIdx);
|
bool GetParamIsSplat(int paramIdx);
|
||||||
BfParamKind GetParamKind(int paramIdx);
|
BfParamKind GetParamKind(int paramIdx);
|
||||||
bool WasGenericParam(int paramIdx);
|
bool WasGenericParam(int paramIdx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue