mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Improved handling of recursive type aliases
This commit is contained in:
parent
9ee38354f7
commit
69028249d7
3 changed files with 56 additions and 30 deletions
|
@ -3650,6 +3650,13 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usedType->IsTypeAlias())
|
||||||
|
{
|
||||||
|
usedType = SafeResolveAliasType((BfTypeAliasType*)usedType);
|
||||||
|
if (usedType == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!usedType->IsGenericTypeInstance())
|
if (!usedType->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
auto underlyingType = usedType->GetUnderlyingType();
|
auto underlyingType = usedType->GetUnderlyingType();
|
||||||
|
|
|
@ -1873,6 +1873,7 @@ public:
|
||||||
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
|
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
|
||||||
void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
|
void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
|
||||||
void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);
|
void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);
|
||||||
|
BfType* SafeResolveAliasType(BfTypeAliasType* aliasType);
|
||||||
bool ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef);
|
bool ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef);
|
||||||
BfType* ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags);
|
BfType* ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags);
|
||||||
void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef);
|
void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef);
|
||||||
|
|
|
@ -2899,22 +2899,6 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias)
|
||||||
typeAlias->mAliasToType = aliasToType;
|
typeAlias->mAliasToType = aliasToType;
|
||||||
|
|
||||||
if (aliasToType != NULL)
|
if (aliasToType != NULL)
|
||||||
{
|
|
||||||
typeAlias->mSize = aliasToType->mSize;
|
|
||||||
typeAlias->mAlign = aliasToType->mAlign;
|
|
||||||
|
|
||||||
if (auto aliasToTypeInst = aliasToType->ToTypeInstance())
|
|
||||||
{
|
|
||||||
typeAlias->mInstSize = aliasToTypeInst->mInstSize;
|
|
||||||
typeAlias->mInstAlign = aliasToTypeInst->mInstAlign;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
typeAlias->mInstSize = aliasToType->mSize;
|
|
||||||
typeAlias->mInstAlign = aliasToType->mAlign;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
typeAlias->mSize = 0;
|
typeAlias->mSize = 0;
|
||||||
typeAlias->mAlign = 1;
|
typeAlias->mAlign = 1;
|
||||||
|
@ -8741,6 +8725,28 @@ bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTy
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfType* BfModule::SafeResolveAliasType(BfTypeAliasType* aliasType)
|
||||||
|
{
|
||||||
|
int aliasDepth = 0;
|
||||||
|
HashSet<BfType*> seenAliases;
|
||||||
|
|
||||||
|
BfType* type = aliasType;
|
||||||
|
while (type->IsTypeAlias())
|
||||||
|
{
|
||||||
|
aliasDepth++;
|
||||||
|
if (aliasDepth > 8)
|
||||||
|
{
|
||||||
|
if (!seenAliases.Add(type))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = type->GetUnderlyingType();
|
||||||
|
if (type == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
|
BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags)
|
||||||
{
|
{
|
||||||
if ((mCompiler->mIsResolveOnly) && (!IsInSpecializedSection()))
|
if ((mCompiler->mIsResolveOnly) && (!IsInSpecializedSection()))
|
||||||
|
@ -8808,26 +8814,24 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
|
|
||||||
BfSourceElementType elemType = BfSourceElementType_Type;
|
BfSourceElementType elemType = BfSourceElementType_Type;
|
||||||
{
|
{
|
||||||
auto typeRef = resolvedTypeRef;
|
auto type = resolvedTypeRef;
|
||||||
while (typeRef->IsTypeAlias())
|
|
||||||
|
if (type->IsTypeAlias())
|
||||||
{
|
{
|
||||||
typeRef = typeRef->GetUnderlyingType();
|
type = SafeResolveAliasType((BfTypeAliasType*)type);
|
||||||
if (typeRef == NULL)
|
if (type == NULL)
|
||||||
{
|
type = resolvedTypeRef;
|
||||||
typeRef = resolvedTypeRef;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeRef->IsInterface())
|
if (type->IsInterface())
|
||||||
elemType = BfSourceElementType_Interface;
|
elemType = BfSourceElementType_Interface;
|
||||||
else if (typeRef->IsObject())
|
else if (type->IsObject())
|
||||||
elemType = BfSourceElementType_RefType;
|
elemType = BfSourceElementType_RefType;
|
||||||
else if (typeRef->IsGenericParam())
|
else if (type->IsGenericParam())
|
||||||
elemType = BfSourceElementType_GenericParam;
|
elemType = BfSourceElementType_GenericParam;
|
||||||
else if (typeRef->IsPrimitiveType())
|
else if (type->IsPrimitiveType())
|
||||||
elemType = BfSourceElementType_PrimitiveType;
|
elemType = BfSourceElementType_PrimitiveType;
|
||||||
else if (typeRef->IsStruct() || (typeRef->IsTypedPrimitive() && !typeRef->IsEnum()))
|
else if (type->IsStruct() || (type->IsTypedPrimitive() && !type->IsEnum()))
|
||||||
elemType = BfSourceElementType_Struct;
|
elemType = BfSourceElementType_Struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9029,8 +9033,22 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
|
|
||||||
if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias))
|
if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias))
|
||||||
{
|
{
|
||||||
|
int aliasDepth = 0;
|
||||||
|
HashSet<BfType*> seenAliases;
|
||||||
|
|
||||||
while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias()))
|
while ((resolvedTypeRef != NULL) && (resolvedTypeRef->IsTypeAlias()))
|
||||||
{
|
{
|
||||||
|
aliasDepth++;
|
||||||
|
if (aliasDepth > 8)
|
||||||
|
{
|
||||||
|
if (!seenAliases.Add(resolvedTypeRef))
|
||||||
|
{
|
||||||
|
if ((typeRef != NULL) && (!typeRef->IsTemporary()))
|
||||||
|
Fail(StrFormat("Type alias '%s' has a recursive definition", TypeToString(resolvedTypeRef).c_str()), typeRef);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mCurTypeInstance != NULL)
|
if (mCurTypeInstance != NULL)
|
||||||
AddDependency(resolvedTypeRef, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
AddDependency(resolvedTypeRef, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
||||||
if (resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined)
|
if (resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue