1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 20:42:21 +02:00

Fixed type lookup for comptime emitted type refs in specialized generics

This commit is contained in:
Brian Fiete 2023-03-14 07:01:44 -07:00
parent d34976864c
commit 723010fd9d
4 changed files with 103 additions and 28 deletions

View file

@ -10025,6 +10025,8 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
skipCheckBaseType = mContext->mCurTypeState->mType->ToTypeInstance();
}
BfProject* useProject = useTypeDef->mProject;
BfTypeDefLookupContext lookupCtx;
bool allowPrivate = true;
@ -10036,6 +10038,13 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
BfTypeDef* foundInnerType = NULL;
if ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0)
{
if (typeInstance->mGenericTypeInfo->mProjectsReferenced.empty())
typeInstance->GenerateProjectsReferenced();
lookupCtx.mCheckProjects = &typeInstance->mGenericTypeInfo->mProjectsReferenced;
}
if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify))
{
if (lookupResultCtx->mResult->mFoundInnerType)
@ -10053,7 +10062,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
{
if (!checkTypeInst->mTypeDef->mNestedTypes.IsEmpty())
{
if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
if (mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkTypeInst->mTypeDef->mFullNameEx, allowPrivate, &lookupCtx))
{
foundInnerType = lookupCtx.mBestTypeDef;
@ -10101,14 +10110,14 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
if (!lookupCtx.HasValidMatch())
{
if (mSystem->mTypeDefs.TryGet(findName, NULL))
mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, BfAtomComposite(), allowPrivate, &lookupCtx);
mSystem->FindTypeDef(findName, numGenericArgs, useProject, BfAtomComposite(), allowPrivate, &lookupCtx);
for (auto& checkNamespace : useTypeDef->mNamespaceSearch)
{
BfAtom* atom = findName.mParts[0];
BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1];
if (atom->mPrevNamesMap.ContainsKey(prevAtom))
mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx);
mSystem->FindTypeDef(findName, numGenericArgs, useProject, checkNamespace, allowPrivate, &lookupCtx);
}
}
@ -10119,7 +10128,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
{
for (auto staticTypeInstance : staticSearch->mStaticTypes)
{
if (mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx))
if (mSystem->FindTypeDef(findName, numGenericArgs, useProject, staticTypeInstance->mTypeDef->mFullNameEx, false, &lookupCtx))
{
if (lookupCtx.HasValidMatch())
break;
@ -10232,6 +10241,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric
BfTypeLookupEntry typeLookupEntry;
typeLookupEntry.mName.Reference(findName);
typeLookupEntry.mNumGenericParams = numGenericArgs;
typeLookupEntry.mFlags = ((resolveFlags & BfResolveTypeRefFlag_SpecializedProject) != 0) ? BfTypeLookupEntry::Flags_SpecializedProject : BfTypeLookupEntry::Flags_None;
typeLookupEntry.mUseTypeDef = useTypeDef;
BfTypeLookupEntry* typeLookupEntryPtr = NULL;
@ -10799,10 +10809,27 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
}
BfTypeDef* curTypeDef = NULL;
Array<BfProject*>* checkProjects = NULL;
if (contextTypeInstance != NULL)
{
curTypeDef = contextTypeInstance->mTypeDef;
if ((curTypeDef->IsEmitted()) && (!typeRef->IsTemporary()))
{
auto parser = typeRef->GetParser();
if ((parser != NULL) && (parser->mIsEmitted))
{
if (contextTypeInstance->IsGenericTypeInstance())
{
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_SpecializedProject);
if (contextTypeInstance->mGenericTypeInfo->mProjectsReferenced.empty())
contextTypeInstance->GenerateProjectsReferenced();
checkProjects = &contextTypeInstance->mGenericTypeInfo->mProjectsReferenced;
}
}
}
// Check generics first
auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef);
auto directStrTypeRef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
@ -11166,7 +11193,24 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
if (activeTypeDef != NULL)
bfProject = activeTypeDef->mProject;
bool leftIsNamespace = false;
if (mSystem->ContainsNamespace(leftComposite, bfProject))
{
leftIsNamespace = true;
}
else if (checkProjects != NULL)
{
for (auto checkProject : *checkProjects)
{
if (mSystem->ContainsNamespace(leftComposite, checkProject))
{
leftIsNamespace = true;
break;
}
}
}
if (leftIsNamespace)
{
qualifiedTypeRef->mLeft->ToString(findName);
findName.Append('.');
@ -11496,7 +11540,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
(BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_DisallowComptime |
BfResolveTypeRefFlag_AllowInferredSizedArray | BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_AllowUnboundGeneric |
BfResolveTypeRefFlag_ForceUnboundGeneric | BfResolveTypeRefFlag_AllowGenericParamConstValue |
BfResolveTypeRefFlag_AllowImplicitConstExpr));
BfResolveTypeRefFlag_AllowImplicitConstExpr | BfResolveTypeRefFlag_SpecializedProject));
lookupCtx.mRootTypeRef = typeRef;
lookupCtx.mRootTypeDef = typeDef;
lookupCtx.mModule = this;

View file

@ -41,7 +41,8 @@ enum BfResolveTypeRefFlags
BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000,
BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000,
BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000,
BfResolveTypeRefFlag_IgnoreProtection = 0x100000
BfResolveTypeRefFlag_IgnoreProtection = 0x100000,
BfResolveTypeRefFlag_SpecializedProject = 0x200000
};
enum BfTypeNameFlags : uint16
@ -1721,8 +1722,15 @@ public:
struct BfTypeLookupEntry
{
enum Flags : uint8
{
Flags_None,
Flags_SpecializedProject
};
BfAtomComposite mName;
int mNumGenericParams;
int16 mNumGenericParams;
Flags mFlags;
uint32 mAtomUpdateIdx;
BfTypeDef* mUseTypeDef;
@ -1730,6 +1738,7 @@ struct BfTypeLookupEntry
{
return (mName == rhs.mName) &&
(mNumGenericParams == rhs.mNumGenericParams) &&
(mFlags == rhs.mFlags) &&
(mUseTypeDef == rhs.mUseTypeDef);
}
};

View file

@ -2663,34 +2663,54 @@ bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs,
continue;
}
if ((typeDef->mFullName == *qualifiedFindNamePtr) && (CheckTypeDefReference(typeDef, project)))
if (typeDef->mFullName == *qualifiedFindNamePtr)
{
int curPri = 0;
if (typeDef->mProtection < minProtection)
curPri -= 1;
if (typeDef->IsGlobalsContainer())
curPri -= 2;
if (typeDef->mGenericParamDefs.size() != numGenericArgs)
bool isProjectValid = false;
if (CheckTypeDefReference(typeDef, project))
{
// Still allow SOME match even if we put in the wrong number of generic args
curPri -= 4;
isProjectValid = true;
}
if ((typeDef->mPartials.mSize > 0) && (typeDef->mPartials[0]->IsExtension()))
else if ((ctx != NULL) && (ctx->mCheckProjects != NULL))
{
// Is a failed extension
curPri -= 8;
for (auto checkProject : *ctx->mCheckProjects)
{
if (CheckTypeDefReference(typeDef, checkProject))
{
isProjectValid = true;
break;
}
}
}
if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL))
if (isProjectValid)
{
ctx->mBestTypeDef = typeDef;
ctx->mAmbiguousTypeDef = NULL;
ctx->mBestPri = curPri;
hadMatch = true;
}
else if (curPri == ctx->mBestPri)
{
ctx->mAmbiguousTypeDef = typeDef;
int curPri = 0;
if (typeDef->mProtection < minProtection)
curPri -= 1;
if (typeDef->IsGlobalsContainer())
curPri -= 2;
if (typeDef->mGenericParamDefs.size() != numGenericArgs)
{
// Still allow SOME match even if we put in the wrong number of generic args
curPri -= 4;
}
if ((typeDef->mPartials.mSize > 0) && (typeDef->mPartials[0]->IsExtension()))
{
// Is a failed extension
curPri -= 8;
}
if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL))
{
ctx->mBestTypeDef = typeDef;
ctx->mAmbiguousTypeDef = NULL;
ctx->mBestPri = curPri;
hadMatch = true;
}
else if (curPri == ctx->mBestPri)
{
ctx->mAmbiguousTypeDef = typeDef;
}
}
}
itr.MoveToNextHashMatch();

View file

@ -1001,6 +1001,7 @@ public:
int mBestPri;
BfTypeDef* mBestTypeDef;
BfTypeDef* mAmbiguousTypeDef;
Array<BfProject*>* mCheckProjects;
public:
BfTypeDefLookupContext()
@ -1008,6 +1009,7 @@ public:
mBestPri = (int)0x80000000;
mBestTypeDef = NULL;
mAmbiguousTypeDef = NULL;
mCheckProjects = NULL;
}
bool HasValidMatch()