mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Improved recursive checks in InferGenericArgument
This commit is contained in:
parent
f1257fb7fc
commit
0c34e62df2
2 changed files with 25 additions and 24 deletions
|
@ -255,22 +255,25 @@ bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* de
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue)
|
bool BfGenericInferContext::AddToCheckedSet(BfType* argType, BfType* wantType)
|
||||||
|
{
|
||||||
|
int64 idPair = ((int64)argType->mTypeId << 32) | (wantType->mTypeId);
|
||||||
|
return mCheckedTypeSet.Add(idPair);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, bool checkCheckedSet)
|
||||||
{
|
{
|
||||||
if (argType == NULL)
|
if (argType == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!wantType->IsUnspecializedType())
|
if (!wantType->IsUnspecializedType())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool alreadyChecked = false;
|
if (checkCheckedSet)
|
||||||
auto _AddToCheckedSet = [](BfType* type, HashSet<BfType*>& checkedTypeSet, bool& alreadyChecked)
|
|
||||||
{
|
{
|
||||||
if (alreadyChecked)
|
if (!AddToCheckedSet(argType, wantType))
|
||||||
return true;
|
return true;
|
||||||
alreadyChecked = true;
|
}
|
||||||
return checkedTypeSet.Add(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (wantType->IsGenericParam())
|
if (wantType->IsGenericParam())
|
||||||
{
|
{
|
||||||
|
@ -305,7 +308,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
if (argGenericType->mTypeDef->GetLatest() == wantGenericType->mTypeDef->GetLatest())
|
if (argGenericType->mTypeDef->GetLatest() == wantGenericType->mTypeDef->GetLatest())
|
||||||
{
|
{
|
||||||
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
|
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], BfIRValue());
|
InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], BfIRValue(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (checkArgType->IsSizedArray())
|
else if (checkArgType->IsSizedArray())
|
||||||
|
@ -316,7 +319,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
|
InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
|
||||||
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType);
|
BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType);
|
||||||
InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mGenericTypeInfo->mTypeGenericArguments[1], BfIRValue());
|
InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mGenericTypeInfo->mTypeGenericArguments[1], BfIRValue(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (checkArgType->IsPointer())
|
else if (checkArgType->IsPointer())
|
||||||
|
@ -324,7 +327,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
auto pointerType = (BfPointerType*)checkArgType;
|
auto pointerType = (BfPointerType*)checkArgType;
|
||||||
if (wantGenericType->IsInstanceOf(mModule->mCompiler->mPointerTTypeDef))
|
if (wantGenericType->IsInstanceOf(mModule->mCompiler->mPointerTTypeDef))
|
||||||
{
|
{
|
||||||
InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue());
|
InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mGenericTypeInfo->mTypeGenericArguments[0], BfIRValue(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,10 +505,8 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
{
|
{
|
||||||
BfType* wantGenericArgument = wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
|
BfType* wantGenericArgument = wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx];
|
||||||
if (!wantGenericArgument->IsUnspecializedType())
|
if (!wantGenericArgument->IsUnspecializedType())
|
||||||
continue;
|
continue;
|
||||||
if (!_AddToCheckedSet(argType, mCheckedTypeSet, alreadyChecked))
|
InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericArgument, BfIRValue(), true);
|
||||||
return true;
|
|
||||||
InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericArgument, BfIRValue());
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +568,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
if (((argType->IsDelegate()) || (argType->IsFunction())) &&
|
if (((argType->IsDelegate()) || (argType->IsFunction())) &&
|
||||||
(wantType->IsDelegate() == argType->IsDelegate()))
|
(wantType->IsDelegate() == argType->IsDelegate()))
|
||||||
{
|
{
|
||||||
if (!_AddToCheckedSet(argType, mCheckedTypeSet, alreadyChecked))
|
if (!AddToCheckedSet(argType, wantType))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto argInvokeMethod = mModule->GetRawMethodByName(argType->ToTypeInstance(), "Invoke");
|
auto argInvokeMethod = mModule->GetRawMethodByName(argType->ToTypeInstance(), "Invoke");
|
||||||
|
@ -583,7 +584,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
else if (argType->IsMethodRef())
|
else if (argType->IsMethodRef())
|
||||||
{
|
{
|
||||||
auto methodTypeRef = (BfMethodRefType*)argType;
|
auto methodTypeRef = (BfMethodRefType*)argType;
|
||||||
if (!_AddToCheckedSet(argType, mCheckedTypeSet, alreadyChecked))
|
if (!AddToCheckedSet(argType, wantType))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto argInvokeMethod = methodTypeRef->mMethodRef;
|
auto argInvokeMethod = methodTypeRef->mMethodRef;
|
||||||
|
@ -1687,7 +1688,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
|
|
||||||
BfGenericInferContext genericInferContext;
|
BfGenericInferContext genericInferContext;
|
||||||
genericInferContext.mModule = mModule;
|
genericInferContext.mModule = mModule;
|
||||||
genericInferContext.mCheckMethodGenericArguments = &mCheckMethodGenericArguments;
|
genericInferContext.mCheckMethodGenericArguments = &mCheckMethodGenericArguments;
|
||||||
|
|
||||||
HashSet<int> allowEmptyGenericSet;
|
HashSet<int> allowEmptyGenericSet;
|
||||||
BfAutoComplete* autoComplete = NULL;
|
BfAutoComplete* autoComplete = NULL;
|
||||||
|
@ -1900,8 +1901,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
||||||
wantType = wantType->GetUnderlyingType();
|
wantType = wantType->GetUnderlyingType();
|
||||||
}
|
}
|
||||||
|
|
||||||
genericInferContext.mCheckedTypeSet.Clear();
|
|
||||||
if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))
|
if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))
|
||||||
return ResultKind_Failed;
|
return ResultKind_Failed;
|
||||||
}
|
}
|
||||||
|
@ -1994,8 +1994,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType()))
|
if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType()))
|
||||||
{
|
{
|
||||||
genericInferContext.mCheckedTypeSet.Clear();
|
|
||||||
if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue()))
|
if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue()))
|
||||||
return ResultKind_Failed;
|
return ResultKind_Failed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public:
|
||||||
class BfGenericInferContext
|
class BfGenericInferContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HashSet<BfType*> mCheckedTypeSet;
|
HashSet<int64> mCheckedTypeSet;
|
||||||
BfModule* mModule;
|
BfModule* mModule;
|
||||||
BfTypeVector* mCheckMethodGenericArguments;
|
BfTypeVector* mCheckMethodGenericArguments;
|
||||||
SizedArray<BfIRValue, 4> mPrevArgValues;
|
SizedArray<BfIRValue, 4> mPrevArgValues;
|
||||||
|
@ -148,7 +148,9 @@ public:
|
||||||
mModule = NULL;
|
mModule = NULL;
|
||||||
mInferredCount = 0;
|
mInferredCount = 0;
|
||||||
}
|
}
|
||||||
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
|
|
||||||
|
bool AddToCheckedSet(BfType* argType, BfType* wantType);
|
||||||
|
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, bool checkCheckedSet = false);
|
||||||
int GetUnresolvedCount()
|
int GetUnresolvedCount()
|
||||||
{
|
{
|
||||||
return (int)mCheckMethodGenericArguments->size() - mInferredCount;
|
return (int)mCheckMethodGenericArguments->size() - mInferredCount;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue