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:
parent
e8b35ce0c4
commit
4cea33d96f
6 changed files with 94 additions and 14 deletions
|
@ -23,6 +23,11 @@ WaitForResolve()
|
|||
SleepTicks(20)
|
||||
AssertFileErrors()
|
||||
|
||||
ShowFile("src/Methods.bf")
|
||||
WaitForResolve()
|
||||
SleepTicks(20)
|
||||
AssertFileErrors()
|
||||
|
||||
ShowFile("src/Properties.bf")
|
||||
WaitForResolve()
|
||||
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,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue