1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Fixed missing generic type validation errors with elemented types

This commit is contained in:
Brian Fiete 2021-01-18 16:01:22 -08:00
parent 95fe97496c
commit 733f7ec983
3 changed files with 62 additions and 32 deletions

View file

@ -6543,7 +6543,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, true);
BfMethodFlags methodFlags = moduleMethodInstance.mMethodInstance->GetMethodFlags();
BfMethodFlags methodFlags = defaultMethod->GetMethodFlags();
int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes);

View file

@ -1808,6 +1808,7 @@ public:
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);
bool ResolveTypeResult_Validate(BfTypeReference* typeRef, BfType* resolvedTypeRef);
BfType* ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags);
void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef);
void ShowGenericArgCountError(BfTypeReference* typeRef, int wantedGenericParams);

View file

@ -7695,6 +7695,63 @@ BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* ty
return GetGenericTypeParamInstance(type->mGenericParamIdx);
}
bool BfModule::ResolveTypeResult_Validate(BfTypeReference* typeRef, BfType* resolvedTypeRef)
{
if ((typeRef == NULL) || (resolvedTypeRef == NULL))
return true;
BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance();
if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance))
{
bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) ||
(!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) ||
(genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation);
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
doValidate = false;
if (mCurTypeInstance != NULL)
{
if (mCurTypeInstance->IsUnspecializedTypeVariation())
doValidate = false;
if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
{
if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) &&
(genericTypeInstance->mDependencyMap.mMinDependDepth > 32))
{
Fail(StrFormat("Generic type dependency depth exceeded for type '{}'", TypeToString(genericTypeInstance).c_str()), typeRef);
return false;
}
if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors)
doValidate = false;
}
if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL) && (!mContext->mCurTypeState->mTypeInstance->IsTypeAlias())) // We validate constraints for base types later
doValidate = false;
}
if (doValidate)
ValidateGenericConstraints(typeRef, genericTypeInstance, false);
}
if (auto genericInstanceTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
{
if (genericTypeInstance != NULL)
{
auto genericTypeInfo = genericTypeInstance->GetGenericTypeInfo();
for (int argIdx = 0; argIdx < (int)genericInstanceTypeRef->mGenericArguments.size(); argIdx++)
{
ResolveTypeResult_Validate(genericInstanceTypeRef->mGenericArguments[argIdx], genericTypeInfo->mTypeGenericArguments[argIdx]);
}
}
}
else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
{
return ResolveTypeResult_Validate(elementedTypeRef, resolvedTypeRef->GetUnderlyingType());
}
return true;
}
BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
{
if ((mCompiler->mIsResolveOnly) && (!IsInSpecializedSection()))
@ -7946,36 +8003,8 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
populateModule->PopulateType(resolvedTypeRef, populateType);
if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance) && (populateType > BfPopulateType_Identity))
{
bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) ||
(!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) ||
(genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation);
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
doValidate = false;
if (mCurTypeInstance != NULL)
{
if (mCurTypeInstance->IsUnspecializedTypeVariation())
doValidate = false;
if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
{
if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) &&
(genericTypeInstance->mDependencyMap.mMinDependDepth > 32))
{
Fail(StrFormat("Generic type dependency depth exceeded for type '{}'", TypeToString(genericTypeInstance).c_str()), typeRef);
if ((populateType > BfPopulateType_Identity) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef)))
return NULL;
}
if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors)
doValidate = false;
}
if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL) && (!mContext->mCurTypeState->mTypeInstance->IsTypeAlias())) // We validate constraints for base types later
doValidate = false;
}
if (doValidate)
ValidateGenericConstraints(typeRef, genericTypeInstance, false);
}
if (populateType != BfPopulateType_IdentityNoRemapAlias)
{