1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Fixed cases of undetected ambiguous calls

This commit is contained in:
Brian Fiete 2020-10-08 12:09:04 -07:00
parent e8b35ce0c4
commit 4cea33d96f
6 changed files with 94 additions and 14 deletions

View file

@ -23,6 +23,11 @@ WaitForResolve()
SleepTicks(20)
AssertFileErrors()
ShowFile("src/Methods.bf")
WaitForResolve()
SleepTicks(20)
AssertFileErrors()
ShowFile("src/Properties.bf")
WaitForResolve()
SleepTicks(20)

View 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
}
}
}

View file

@ -718,18 +718,22 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
bool betterByConstExprParam = false;
bool worseByConstExprParam = false;
bool someArgWasBetter = false;
bool someArgWasWorse = false;
for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++)
{
BfTypedValue arg;
BfResolvedArg* resolvedArg = NULL;
BfResolvedArg* resolvedArg = NULL;
bool wasArgDeferred = false;
if (argIdx == -1)
{
arg = mTarget;
}
else
{
{
resolvedArg = &mArguments[argIdx];
wasArgDeferred = resolvedArg->mArgFlags != 0;
arg = resolvedArg->mTypedValue;
}
@ -739,8 +743,8 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
bool wasGenericParam = (newArgIdx >= 0) && newMethodInstance->WasGenericParam(newArgIdx);
bool prevWasGenericParam = (prevArgIdx >= 0) && prevMethodInstance->WasGenericParam(prevArgIdx);
BfType* paramType = newMethodInstance->GetParamType(newArgIdx);
BfType* prevParamType = prevMethodInstance->GetParamType(prevArgIdx);
BfType* paramType = newMethodInstance->GetParamType(newArgIdx, true);
BfType* prevParamType = prevMethodInstance->GetParamType(prevArgIdx, true);
numUsedParams++;
prevNumUsedParams++;
@ -796,9 +800,10 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
{
// 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
if ((!wasGenericParam) && (IsType(arg, paramType)) && ((resolvedArg == NULL) || (prevParamType != resolvedArg->mBestBoundType)))
if ((!wasArgDeferred) && (!wasGenericParam) && (IsType(arg, paramType)) && ((resolvedArg == NULL) || (prevParamType != resolvedArg->mBestBoundType)))
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;
else
{
@ -830,6 +835,10 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
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))
break;
someArgWasBetter |= isBetter;
someArgWasWorse |= isWorse;
isBetter = false;
isWorse = false;
}
isBetter |= someArgWasBetter;
isWorse |= someArgWasWorse;
if ((!isBetter) && (!isWorse))
{
@ -1869,7 +1885,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
{
BF_ASSERT(!ambiguousEntry.mBestMethodGenericArguments.empty());
}
mAmbiguousEntries.push_back(ambiguousEntry);
mAmbiguousEntries.push_back(ambiguousEntry);
goto Done;
}
}

View file

@ -16338,15 +16338,13 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
BfType* unresolvedType = methodInstance->GetParamType(paramIdx, false);
if (unresolvedType == NULL)
auto resolvedType = methodInstance->GetParamType(paramIdx);
if (resolvedType == NULL)
{
AssertErrorState();
unresolvedType = mContext->mBfObjectType;
paramVar->mParamFailed = true;
}
auto resolvedType = methodInstance->GetParamType(paramIdx, true);
prevIgnoreErrors.Restore();
PopulateType(resolvedType, BfPopulateType_Declaration);
paramVar->mResolvedType = resolvedType;

View file

@ -868,7 +868,7 @@ String BfMethodInstance::GetParamName(int paramIdx)
return paramName;
}
BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParamsType)
{
if (paramIdx == -1)
{
@ -892,6 +892,19 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke();
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;
}

View file

@ -902,7 +902,7 @@ public:
int GetImplicitParamCount();
void GetParamName(int paramIdx, StringImpl& name);
String GetParamName(int paramIdx);
BfType* GetParamType(int paramIdx, bool useResolvedType = true);
BfType* GetParamType(int paramIdx, bool returnUnderlyingParamsType = false);
bool GetParamIsSplat(int paramIdx);
BfParamKind GetParamKind(int paramIdx);
bool WasGenericParam(int paramIdx);