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

View file

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

View file

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

View file

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