mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed issue choose 'int unknown' overload over generic method
This commit is contained in:
parent
c8055f0a38
commit
7bd29b5b69
6 changed files with 84 additions and 10 deletions
|
@ -350,6 +350,13 @@ public:
|
||||||
return mVals[idx];
|
return mVals[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetSafe(intptr idx, T& val)
|
||||||
|
{
|
||||||
|
if ((idx < 0) || (idx >= mSize))
|
||||||
|
return;
|
||||||
|
val = mVals[idx];
|
||||||
|
}
|
||||||
|
|
||||||
T GetLastSafe()
|
T GetLastSafe()
|
||||||
{
|
{
|
||||||
if (mSize == 0)
|
if (mSize == 0)
|
||||||
|
|
|
@ -112,6 +112,13 @@ public:
|
||||||
return mVals[idx];
|
return mVals[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetSafe(intptr idx, T& val)
|
||||||
|
{
|
||||||
|
if ((idx < 0) || (idx >= mSize))
|
||||||
|
return;
|
||||||
|
val = mVals[idx];
|
||||||
|
}
|
||||||
|
|
||||||
Iterator begin() const
|
Iterator begin() const
|
||||||
{
|
{
|
||||||
return mVals;
|
return mVals;
|
||||||
|
|
|
@ -545,7 +545,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
{
|
{
|
||||||
BfResolvedArg resolvedArg = mArguments[argIdx];;
|
BfResolvedArg resolvedArg = mArguments[argIdx];;
|
||||||
BfTypedValue arg = resolvedArg.mTypedValue;
|
BfTypedValue arg = resolvedArg.mTypedValue;
|
||||||
|
|
||||||
int newArgIdx = argIdx + newImplicitParamCount;
|
int newArgIdx = argIdx + newImplicitParamCount;
|
||||||
int prevArgIdx = argIdx + prevImplicitParamCount;
|
int prevArgIdx = argIdx + prevImplicitParamCount;
|
||||||
|
|
||||||
|
@ -562,9 +562,15 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
BfType* origPrevParamType = prevParamType;
|
BfType* origPrevParamType = prevParamType;
|
||||||
|
|
||||||
if ((genericArgumentsSubstitute != NULL) && (paramType->IsUnspecializedType()))
|
if ((genericArgumentsSubstitute != NULL) && (paramType->IsUnspecializedType()))
|
||||||
|
{
|
||||||
paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, allowSpecializeFail);
|
paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, allowSpecializeFail);
|
||||||
|
paramType = mModule->FixIntUnknown(paramType);
|
||||||
|
}
|
||||||
if ((prevGenericArgumentsSubstitute != NULL) && (prevParamType->IsUnspecializedType()))
|
if ((prevGenericArgumentsSubstitute != NULL) && (prevParamType->IsUnspecializedType()))
|
||||||
|
{
|
||||||
prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, allowSpecializeFail);
|
prevParamType = mModule->ResolveGenericType(prevParamType, NULL, prevGenericArgumentsSubstitute, allowSpecializeFail);
|
||||||
|
prevParamType = mModule->FixIntUnknown(prevParamType);
|
||||||
|
}
|
||||||
|
|
||||||
if ((wasGenericParam) || (prevWasGenericParam))
|
if ((wasGenericParam) || (prevWasGenericParam))
|
||||||
{
|
{
|
||||||
|
@ -596,9 +602,9 @@ 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 ((paramType == arg.mType) && (prevParamType != resolvedArg.mBestBoundType))
|
if ((IsType(arg, paramType)) && (prevParamType != resolvedArg.mBestBoundType))
|
||||||
isBetter = true;
|
isBetter = true;
|
||||||
else if ((prevParamType == arg.mType) && (paramType != arg.mType))
|
else if ((IsType(arg, prevParamType)) && (!IsType(arg, paramType)))
|
||||||
isWorse = true;
|
isWorse = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -629,7 +635,6 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*if ((paramType->IsIntegral()) && (prevParamType->IsIntegral()))
|
/*if ((paramType->IsIntegral()) && (prevParamType->IsIntegral()))
|
||||||
{
|
{
|
||||||
if (paramType == arg.mType)
|
if (paramType == arg.mType)
|
||||||
|
@ -1692,6 +1697,40 @@ void BfMethodMatcher::FlushAmbiguityError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfMethodMatcher::IsType(BfTypedValue& typedVal, BfType* type)
|
||||||
|
{
|
||||||
|
if (typedVal.mType == type)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!typedVal.mType->IsPrimitiveType())
|
||||||
|
return false;
|
||||||
|
if (!type->IsPrimitiveType())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto fromPrimType = typedVal.mType->ToPrimitiveType();
|
||||||
|
if ((fromPrimType->mTypeDef->mTypeCode != BfTypeCode_IntUnknown) &&
|
||||||
|
(fromPrimType->mTypeDef->mTypeCode != BfTypeCode_UIntUnknown))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto constant = mModule->mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||||
|
if (constant == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto toPrimType = type->ToPrimitiveType();
|
||||||
|
if (!mModule->mBfIRBuilder->IsInt(toPrimType->mTypeDef->mTypeCode))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (type->mSize == 8)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int64 minVal = -(1LL << (8 * type->mSize - 1));
|
||||||
|
int64 maxVal = (1LL << (8 * type->mSize - 1)) - 1;
|
||||||
|
if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// This method checks all base classes before checking interfaces. Is that correct?
|
// This method checks all base classes before checking interfaces. Is that correct?
|
||||||
bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass)
|
bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass)
|
||||||
{
|
{
|
||||||
|
@ -12131,7 +12170,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN
|
||||||
{
|
{
|
||||||
auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(scopeNode->mTargetNode);
|
auto targetIdentifier = BfNodeDynCast<BfIdentifierNode>(scopeNode->mTargetNode);
|
||||||
if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
|
if ((scopeNode->mTargetNode == NULL) || (targetIdentifier != NULL))
|
||||||
autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken);
|
autoComplete->CheckLabel(targetIdentifier, scopeNode->mColonToken, allocTarget.mScopeData);
|
||||||
}
|
}
|
||||||
attributeDirective = scopeNode->mAttributes;
|
attributeDirective = scopeNode->mAttributes;
|
||||||
}
|
}
|
||||||
|
@ -12309,8 +12348,10 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
|
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
|
||||||
{
|
{
|
||||||
errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
|
errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
|
||||||
if ((errorNode == NULL) && (!invocationExpr->mGenericArgs->mCommas.IsEmpty()))
|
if (errorNode == NULL)
|
||||||
errorNode = invocationExpr->mGenericArgs->mCommas[(int)methodDef->mGenericParams.size() - 1];
|
invocationExpr->mGenericArgs->mCommas.GetSafe((int)methodDef->mGenericParams.size() - 1, errorNode);
|
||||||
|
if (errorNode == NULL)
|
||||||
|
errorNode = targetSrc;
|
||||||
}
|
}
|
||||||
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
|
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);
|
||||||
}
|
}
|
||||||
|
@ -13388,7 +13429,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
{
|
{
|
||||||
if (auto identifier = BfNodeDynCast<BfIdentifierNode>(scopedTarget->mScopeName))
|
if (auto identifier = BfNodeDynCast<BfIdentifierNode>(scopedTarget->mScopeName))
|
||||||
autoComplete->CheckLabel(identifier, scopedTarget->mColonToken);
|
autoComplete->CheckLabel(identifier, scopedTarget->mColonToken, NULL);
|
||||||
}
|
}
|
||||||
//mModule->FindScope(scopedTarget->mScopeName);
|
//mModule->FindScope(scopedTarget->mScopeName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,7 @@ public:
|
||||||
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
||||||
bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail);
|
bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail);
|
||||||
void FlushAmbiguityError();
|
void FlushAmbiguityError();
|
||||||
|
bool IsType(BfTypedValue& val, BfType* type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments);
|
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments);
|
||||||
|
|
|
@ -1646,8 +1646,9 @@ public:
|
||||||
BfPrimitiveType* GetPrimitiveType(BfTypeCode typeCode);
|
BfPrimitiveType* GetPrimitiveType(BfTypeCode typeCode);
|
||||||
BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false);
|
BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false);
|
||||||
BfType* FixIntUnknown(BfType* type);
|
BfType* FixIntUnknown(BfType* type);
|
||||||
void FixIntUnknown(BfTypedValue& typedVal);
|
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);
|
||||||
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
|
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
|
||||||
|
bool TypeEquals(BfTypedValue& val, BfType* type);
|
||||||
BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL);
|
BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL);
|
||||||
BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data);
|
BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data);
|
||||||
void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized);
|
void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized);
|
||||||
|
|
|
@ -4806,7 +4806,7 @@ BfType* BfModule::FixIntUnknown(BfType* type)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::FixIntUnknown(BfTypedValue& typedVal)
|
void BfModule::FixIntUnknown(BfTypedValue& typedVal, BfType* matchType)
|
||||||
{
|
{
|
||||||
if (!typedVal.mValue.IsConst())
|
if (!typedVal.mValue.IsConst())
|
||||||
{
|
{
|
||||||
|
@ -4832,6 +4832,23 @@ void BfModule::FixIntUnknown(BfTypedValue& typedVal)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||||
|
|
||||||
|
if ((matchType != NULL) && (matchType->IsPrimitiveType()) && (mBfIRBuilder->IsInt(matchType->ToPrimitiveType()->mTypeDef->mTypeCode)))
|
||||||
|
{
|
||||||
|
auto wantTypeCode = matchType->ToPrimitiveType()->mTypeDef->mTypeCode;
|
||||||
|
if (matchType->mSize < 8)
|
||||||
|
{
|
||||||
|
int64 minVal = -(1LL << (8 * matchType->mSize - 1));
|
||||||
|
int64 maxVal = (1LL << (8 * matchType->mSize - 1)) - 1;
|
||||||
|
if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal))
|
||||||
|
{
|
||||||
|
typedVal.mValue = mBfIRBuilder->CreateNumericCast(typedVal.mValue, mBfIRBuilder->IsSigned(wantTypeCode), wantTypeCode);
|
||||||
|
typedVal.mType = GetPrimitiveType(wantTypeCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mSystem->mPtrSize == 4)
|
if (mSystem->mPtrSize == 4)
|
||||||
{
|
{
|
||||||
if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
|
if (primType->mTypeDef->mTypeCode == BfTypeCode_IntUnknown)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue