mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Fixed some constraint and generic type lifetime issues
This commit is contained in:
parent
88926da1ed
commit
dacbcf4eb3
8 changed files with 145 additions and 47 deletions
|
@ -2052,6 +2052,13 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
||||||
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL))
|
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL))
|
||||||
madeFullPass = false;
|
madeFullPass = false;
|
||||||
|
|
||||||
|
if ((deleteUnusued) && (madeFullPass))
|
||||||
|
{
|
||||||
|
// Work queues should be empty if we're not canceling
|
||||||
|
BF_ASSERT(mContext->mPopulateTypeWorkList.size() == 0);
|
||||||
|
BF_ASSERT(mContext->mMethodWorkList.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove old data in dependency maps, and find types which don't have any references (direct or indirect)
|
// Remove old data in dependency maps, and find types which don't have any references (direct or indirect)
|
||||||
// to a non-generic type and remove them
|
// to a non-generic type and remove them
|
||||||
for (int pass = 0; true; pass++)
|
for (int pass = 0; true; pass++)
|
||||||
|
@ -2090,7 +2097,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
||||||
auto depTypeInst = dependentType->ToTypeInstance();
|
auto depTypeInst = dependentType->ToTypeInstance();
|
||||||
auto& depData = itr->mValue;
|
auto& depData = itr->mValue;
|
||||||
|
|
||||||
bool isInvalidVersion = (dependentType->mRevision > depData.mRevision) && (deleteUnusued) && (madeFullPass);
|
bool isInvalidVersion = (dependentType->mRevision > depData.mRevision);// && (deleteUnusued) && (madeFullPass);
|
||||||
|
|
||||||
//TODO: Just to cause crash if dependentType is deleted
|
//TODO: Just to cause crash if dependentType is deleted
|
||||||
bool isIncomplete = dependentType->IsIncomplete();
|
bool isIncomplete = dependentType->IsIncomplete();
|
||||||
|
@ -2109,11 +2116,16 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
||||||
|
|
||||||
if ((dependentType->IsDeleting()) || (isInvalidVersion))
|
if ((dependentType->IsDeleting()) || (isInvalidVersion))
|
||||||
{
|
{
|
||||||
// If we're deleting the type, OR the dependency of the type has been removed.
|
if (dependentType->IsDeleting() || ((deleteUnusued) && (madeFullPass)))
|
||||||
// We detect a removed dependency by the dependent type changing but the dependency revision
|
{
|
||||||
// is older than the dependent type.
|
// If we're deleting the type, OR the dependency of the type has been removed.
|
||||||
BfLogSysM("Removing old dependent %p from %p\n", dependentType, depType);
|
// We detect a removed dependency by the dependent type changing but the dependency revision
|
||||||
itr = depType->mDependencyMap.erase(itr);
|
// is older than the dependent type.
|
||||||
|
BfLogSysM("Removing old dependent %p from %p\n", dependentType, depType);
|
||||||
|
itr = depType->mDependencyMap.erase(itr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++itr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2121,20 +2133,30 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
||||||
// Keep in mind that actually invoking a generic method creates a DependencyFlag_LocalUsage dependency. The
|
// Keep in mind that actually invoking a generic method creates a DependencyFlag_LocalUsage dependency. The
|
||||||
// DependencyFlag_MethodGenericArg is just used by the owner during creation of the method specialization
|
// DependencyFlag_MethodGenericArg is just used by the owner during creation of the method specialization
|
||||||
bool isDependentUsage =
|
bool isDependentUsage =
|
||||||
(depData.mFlags != BfDependencyMap::DependencyFlag_UnspecializedType) &&
|
(depData.mFlags & ~(
|
||||||
(depData.mFlags != BfDependencyMap::DependencyFlag_MethodGenericArg);
|
BfDependencyMap::DependencyFlag_UnspecializedType |
|
||||||
|
BfDependencyMap::DependencyFlag_MethodGenericArg |
|
||||||
|
BfDependencyMap::DependencyFlag_GenericArgRef)) != 0;
|
||||||
|
|
||||||
// We need to consider specialized generic types separately, to remove unused specializations
|
// We need to consider specialized generic types separately, to remove unused specializations
|
||||||
if (typeInst != NULL)
|
if (typeInst != NULL)
|
||||||
{
|
{
|
||||||
|
bool isDirectReference = (depTypeInst != NULL) && (!depTypeInst->IsOnDemand()) && (!dependentType->IsGenericTypeInstance());
|
||||||
|
|
||||||
if ((depTypeInst != NULL) && (typeInst->mLastNonGenericUsedRevision != mRevision) && (isDependentUsage) &&
|
if ((depTypeInst != NULL) && (typeInst->mLastNonGenericUsedRevision != mRevision) && (isDependentUsage) &&
|
||||||
((!dependentType->IsGenericTypeInstance()) || (dependentType->IsUnspecializedType()) || (depTypeInst->mLastNonGenericUsedRevision == mRevision)))
|
((isDirectReference) || (dependentType->IsUnspecializedType()) || (depTypeInst->mLastNonGenericUsedRevision == mRevision)))
|
||||||
{
|
{
|
||||||
typeInst->mLastNonGenericUsedRevision = mRevision;
|
//if (deleteUnusued)
|
||||||
foundNew = true;
|
{
|
||||||
|
typeInst->mLastNonGenericUsedRevision = mRevision;
|
||||||
|
foundNew = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!typeInst->HasBeenReferenced())
|
if (!typeInst->HasBeenReferenced())
|
||||||
|
{
|
||||||
mContext->AddTypeToWorkList(typeInst);
|
mContext->AddTypeToWorkList(typeInst);
|
||||||
|
foundNew = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2301,6 +2323,9 @@ void BfCompiler::ProcessPurgatory(bool reifiedOnly)
|
||||||
if ((reifiedOnly) && (!type->IsReified()))
|
if ((reifiedOnly) && (!type->IsReified()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if ((reifiedOnly) && ((type->mRebuildFlags & BfTypeRebuildFlag_AwaitingReference) != 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!type->IsDeleting())
|
if (!type->IsDeleting())
|
||||||
{
|
{
|
||||||
auto module = type->GetModule();
|
auto module = type->GetModule();
|
||||||
|
|
|
@ -1527,7 +1527,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dependencyEntry.mFlags & ~(BfDependencyMap::DependencyFlag_UnspecializedType)) == 0)
|
if ((dependencyEntry.mFlags & ~(BfDependencyMap::DependencyFlag_UnspecializedType | BfDependencyMap::DependencyFlag_WeakReference)) == 0)
|
||||||
continue; // Not a cause for rebuilding
|
continue; // Not a cause for rebuilding
|
||||||
|
|
||||||
if ((deferDepRebuilds) && (dependentTypeInst != NULL))
|
if ((deferDepRebuilds) && (dependentTypeInst != NULL))
|
||||||
|
|
|
@ -415,11 +415,22 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto typeInstance = argType->ToTypeInstance();
|
||||||
|
if (typeInstance == NULL)
|
||||||
|
return true;
|
||||||
|
if (wantGenericType->IsInterface())
|
||||||
|
{
|
||||||
|
for (auto& ifaceEntry : typeInstance->mInterfaces)
|
||||||
|
InferGenericArgument(methodInstance, ifaceEntry.mInterfaceType, wantType, BfIRValue());
|
||||||
|
}
|
||||||
|
else if (typeInstance->mBaseType != NULL)
|
||||||
|
InferGenericArgument(methodInstance, typeInstance->mBaseType, wantType, BfIRValue());
|
||||||
|
|
||||||
if (!argType->IsGenericTypeInstance())
|
if (!argType->IsGenericTypeInstance())
|
||||||
return true;
|
return true;
|
||||||
auto argGenericType = (BfGenericTypeInstance*)argType;
|
auto argGenericType = (BfGenericTypeInstance*)argType;
|
||||||
if (argGenericType->mTypeDef != wantGenericType->mTypeDef)
|
if (argGenericType->mTypeDef != wantGenericType->mTypeDef)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
{
|
{
|
||||||
|
@ -1546,7 +1557,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
auto wantType = methodInstance->GetParamType(paramIdx);
|
auto wantType = methodInstance->GetParamType(paramIdx);
|
||||||
if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
|
if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
|
||||||
{
|
{
|
||||||
auto resolvedType = mModule->ResolveGenericType(wantType, NULL, genericArgumentsSubstitute);
|
auto resolvedType = mModule->ResolveGenericType(wantType, NULL, genericArgumentsSubstitute, false);
|
||||||
if (resolvedType == NULL)
|
if (resolvedType == NULL)
|
||||||
goto NoMatch;
|
goto NoMatch;
|
||||||
wantType = resolvedType;
|
wantType = resolvedType;
|
||||||
|
@ -2164,7 +2175,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori
|
||||||
auto useModule = mModule->mContext->mUnreifiedModule;
|
auto useModule = mModule->mContext->mUnreifiedModule;
|
||||||
boxedType = useModule->CreateBoxedType(target.mType);
|
boxedType = useModule->CreateBoxedType(target.mType);
|
||||||
useModule->PopulateType(boxedType, BfPopulateType_DataAndMethods);
|
useModule->PopulateType(boxedType, BfPopulateType_DataAndMethods);
|
||||||
useModule->AddDependency(boxedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls);
|
useModule->AddDependency(boxedType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_WeakReference);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -12739,8 +12750,9 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
else
|
else
|
||||||
paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
|
paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
|
||||||
|
|
||||||
|
// Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
|
||||||
BfError* error = NULL;
|
BfError* error = NULL;
|
||||||
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance.mMethodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], &methodMatcher.mBestMethodGenericArguments,
|
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance.mMethodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], NULL,
|
||||||
failed ? NULL : &error))
|
failed ? NULL : &error))
|
||||||
{
|
{
|
||||||
if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
|
if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
|
||||||
|
|
|
@ -1224,7 +1224,9 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mContext->RebuildType(typeInst, false, false, false);
|
//TODO: Why weren't we placing specialzied in purgatory here originally? This caused failed types to stick around too long
|
||||||
|
mContext->RebuildType(typeInst, false, false, true);
|
||||||
|
//mContext->RebuildType(typeInst, false, false, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2978,9 +2980,9 @@ bool BfModule::CheckDefineMemberProtection(BfProtection protection, BfType* memb
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::AddDependency(BfType* usedType, BfType* usingType, BfDependencyMap::DependencyDependencyFlag flags)
|
void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyDependencyFlag flags)
|
||||||
{
|
{
|
||||||
if (usedType == usingType)
|
if (usedType == userType)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsAutocompleteMethod))
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsAutocompleteMethod))
|
||||||
|
@ -3051,7 +3053,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* usingType, BfDependencyMa
|
||||||
|
|
||||||
if ((!mCompiler->mIsResolveOnly) && (mIsReified))
|
if ((!mCompiler->mIsResolveOnly) && (mIsReified))
|
||||||
{
|
{
|
||||||
auto usingModule = usingType->GetModule();
|
auto usingModule = userType->GetModule();
|
||||||
BfModule* usedModule;
|
BfModule* usedModule;
|
||||||
if (usedType->IsFunction())
|
if (usedType->IsFunction())
|
||||||
{
|
{
|
||||||
|
@ -3080,7 +3082,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* usingType, BfDependencyMa
|
||||||
|
|
||||||
auto underlyingType = usedType->GetUnderlyingType();
|
auto underlyingType = usedType->GetUnderlyingType();
|
||||||
if (underlyingType != NULL) // Not really a "GenericArg", but... same purpose.
|
if (underlyingType != NULL) // Not really a "GenericArg", but... same purpose.
|
||||||
AddDependency(underlyingType, usingType, BfDependencyMap::DependencyFlag_GenericArgRef);
|
AddDependency(underlyingType, userType, BfDependencyMap::DependencyFlag_GenericArgRef);
|
||||||
|
|
||||||
BfDependedType* checkDType = usedType->ToDependedType();
|
BfDependedType* checkDType = usedType->ToDependedType();
|
||||||
if (checkDType == NULL)
|
if (checkDType == NULL)
|
||||||
|
@ -3089,13 +3091,22 @@ void BfModule::AddDependency(BfType* usedType, BfType* usingType, BfDependencyMa
|
||||||
if ((usedType->mRebuildFlags & BfTypeRebuildFlag_AwaitingReference) != 0)
|
if ((usedType->mRebuildFlags & BfTypeRebuildFlag_AwaitingReference) != 0)
|
||||||
mContext->MarkAsReferenced(checkDType);
|
mContext->MarkAsReferenced(checkDType);
|
||||||
|
|
||||||
checkDType->mDependencyMap.AddUsedBy(usingType, flags);
|
if (!checkDType->mDependencyMap.AddUsedBy(userType, flags))
|
||||||
|
return;
|
||||||
if (checkDType->IsGenericTypeInstance())
|
if (checkDType->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
auto genericTypeInstance = (BfGenericTypeInstance*) checkDType;
|
auto genericTypeInstance = (BfGenericTypeInstance*) checkDType;
|
||||||
for (auto genericArg : genericTypeInstance->mTypeGenericArguments)
|
for (auto genericArg : genericTypeInstance->mTypeGenericArguments)
|
||||||
{
|
{
|
||||||
AddDependency(genericArg, usingType, BfDependencyMap::DependencyFlag_GenericArgRef);
|
AddDependency(genericArg, userType, BfDependencyMap::DependencyFlag_GenericArgRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (checkDType->IsTuple())
|
||||||
|
{
|
||||||
|
for (auto& field : checkDType->ToTypeInstance()->mFieldInstances)
|
||||||
|
{
|
||||||
|
if (field.mDataIdx != -1)
|
||||||
|
AddDependency(field.mResolvedType, userType, BfDependencyMap::DependencyFlag_GenericArgRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1603,7 +1603,7 @@ public:
|
||||||
bool CheckAccessMemberProtection(BfProtection protection, BfType* memberType);
|
bool CheckAccessMemberProtection(BfProtection protection, BfType* memberType);
|
||||||
bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType);
|
bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType);
|
||||||
void CheckMemberNames(BfTypeInstance* typeInst);
|
void CheckMemberNames(BfTypeInstance* typeInst);
|
||||||
void AddDependency(BfType* usedType, BfType* usingType, BfDependencyMap::DependencyDependencyFlag flags);
|
void AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyDependencyFlag flags);
|
||||||
void AddCallDependency(BfMethodInstance* methodInstance, bool devirtualized = false);
|
void AddCallDependency(BfMethodInstance* methodInstance, bool devirtualized = false);
|
||||||
void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType);
|
void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType);
|
||||||
void TypeFailed(BfTypeInstance* typeInstance);
|
void TypeFailed(BfTypeInstance* typeInstance);
|
||||||
|
|
|
@ -103,11 +103,12 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
|
||||||
BfTypeState typeState;
|
BfTypeState typeState;
|
||||||
typeState.mPrevState = mContext->mCurTypeState;
|
typeState.mPrevState = mContext->mCurTypeState;
|
||||||
typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
|
typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
|
||||||
|
typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance();
|
||||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
BF_ASSERT(mCurMethodInstance == NULL);
|
BF_ASSERT(mCurMethodInstance == NULL);
|
||||||
|
|
||||||
auto genericTypeInst = (BfGenericTypeInstance*)resolvedTypeRef;
|
auto genericTypeInst = resolvedTypeRef->ToGenericTypeInstance();
|
||||||
|
|
||||||
if (genericTypeInst->mTypeGenericArguments[0]->IsGenericParam())
|
if (genericTypeInst->mTypeGenericArguments[0]->IsGenericParam())
|
||||||
{
|
{
|
||||||
|
@ -195,7 +196,7 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfGenericTypeInstance* genericTypeInst, bool ignoreErrors)
|
bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfGenericTypeInstance* genericTypeInst, bool ignoreErrors)
|
||||||
{
|
|
||||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsTypeAlias()))
|
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsTypeAlias()))
|
||||||
{
|
{
|
||||||
// Don't validate constraints during the population of a concrete generic type alias instance, we want to
|
// Don't validate constraints during the population of a concrete generic type alias instance, we want to
|
||||||
|
@ -2064,9 +2065,22 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
BF_ASSERT(typeInstance->mBaseType == baseTypeInst);
|
BF_ASSERT(typeInstance->mBaseType == baseTypeInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* outerType = GetOuterType(typeInstance);
|
|
||||||
if (outerType != NULL)
|
if (auto genericTypeInst = typeInstance->ToGenericTypeInstance())
|
||||||
AddDependency(outerType, typeInstance, BfDependencyMap::DependencyFlag_OuterType);
|
{
|
||||||
|
if ((genericTypeInst->IsSpecializedType()) && (!genericTypeInst->mValidatedGenericConstraints) && (!typeInstance->IsBoxed()))
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, true);
|
||||||
|
ValidateGenericConstraints(NULL, genericTypeInst, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!typeInstance->IsBoxed())
|
||||||
|
{
|
||||||
|
BfType* outerType = GetOuterType(typeInstance);
|
||||||
|
if (outerType != NULL)
|
||||||
|
AddDependency(outerType, typeInstance, BfDependencyMap::DependencyFlag_OuterType);
|
||||||
|
}
|
||||||
|
|
||||||
if ((baseTypeInst != NULL) && (typeInstance->mBaseType == NULL))
|
if ((baseTypeInst != NULL) && (typeInstance->mBaseType == NULL))
|
||||||
{
|
{
|
||||||
|
@ -5966,7 +5980,17 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
genericArgs.push_back(genericArg);
|
genericArgs.push_back(genericArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolveTypeDef(genericTypeInst->mTypeDef, genericArgs);
|
auto resolvedType = ResolveTypeDef(genericTypeInst->mTypeDef, genericArgs, BfPopulateType_BaseType);
|
||||||
|
BfGenericTypeInstance* specializedType = NULL;
|
||||||
|
if (resolvedType != NULL)
|
||||||
|
specializedType = resolvedType->ToGenericTypeInstance();
|
||||||
|
if (specializedType != NULL)
|
||||||
|
{
|
||||||
|
if (specializedType->mHadValidateErrors)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return specializedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return unspecializedType;
|
return unspecializedType;
|
||||||
|
@ -6286,10 +6310,23 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
|
|
||||||
if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance) && (populateType > BfPopulateType_Identity))
|
if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance) && (populateType > BfPopulateType_Identity))
|
||||||
{
|
{
|
||||||
if (((genericTypeInstance->mHadValidateErrors) || (!genericTypeInstance->mValidatedGenericConstraints) || (genericTypeInstance->mIsUnspecializedVariation)) &&
|
bool doValidate = (genericTypeInstance->mHadValidateErrors) || (!genericTypeInstance->mValidatedGenericConstraints) || (genericTypeInstance->mIsUnspecializedVariation);
|
||||||
((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecializedVariation)) &&
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation))
|
||||||
((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsUnspecializedTypeVariation())) &&
|
doValidate = false;
|
||||||
((mContext->mCurTypeState == NULL) || (mContext->mCurTypeState->mCurBaseTypeRef == NULL))) // We validate constraints for base types later
|
if (mCurTypeInstance != NULL)
|
||||||
|
{
|
||||||
|
if (mCurTypeInstance->IsUnspecializedTypeVariation())
|
||||||
|
doValidate = false;
|
||||||
|
if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
|
||||||
|
{
|
||||||
|
if (curGenericTypeInstance->mHadValidateErrors)
|
||||||
|
doValidate = false;
|
||||||
|
}
|
||||||
|
if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL)) // We validate constraints for base types later
|
||||||
|
doValidate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doValidate)
|
||||||
ValidateGenericConstraints(typeRef, genericTypeInstance, false);
|
ValidateGenericConstraints(typeRef, genericTypeInstance, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6396,8 +6433,13 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeInstance* skipCheckBaseType = NULL;
|
BfTypeInstance* skipCheckBaseType = NULL;
|
||||||
if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mCurBaseTypeRef != NULL))
|
if (mContext->mCurTypeState != NULL)
|
||||||
skipCheckBaseType = mContext->mCurTypeState->mTypeInstance;
|
{
|
||||||
|
if (mContext->mCurTypeState->mCurBaseTypeRef != NULL)
|
||||||
|
skipCheckBaseType = mContext->mCurTypeState->mTypeInstance;
|
||||||
|
if (mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_BuildingGenericParams)
|
||||||
|
skipCheckBaseType = mContext->mCurTypeState->mTypeInstance;
|
||||||
|
}
|
||||||
|
|
||||||
BfTypeDefLookupContext lookupCtx;
|
BfTypeDefLookupContext lookupCtx;
|
||||||
bool allowPrivate = true;
|
bool allowPrivate = true;
|
||||||
|
@ -6408,6 +6450,8 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene
|
||||||
BfTypeDef* protErrorTypeDef = NULL;
|
BfTypeDef* protErrorTypeDef = NULL;
|
||||||
BfTypeInstance* protErrorOuterType = NULL;
|
BfTypeInstance* protErrorOuterType = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!lookupCtx.HasValidMatch())
|
if (!lookupCtx.HasValidMatch())
|
||||||
{
|
{
|
||||||
std::function<bool(BfTypeInstance*)> _CheckType = [&](BfTypeInstance* typeInstance)
|
std::function<bool(BfTypeInstance*)> _CheckType = [&](BfTypeInstance* typeInstance)
|
||||||
|
|
|
@ -58,7 +58,7 @@ bool BfTypedValue::IsValuelessType() const
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyDependencyFlag flags)
|
bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyDependencyFlag flags)
|
||||||
{
|
{
|
||||||
BF_ASSERT(dependentType != NULL);
|
BF_ASSERT(dependentType != NULL);
|
||||||
BF_ASSERT(dependentType->mRevision != -1);
|
BF_ASSERT(dependentType->mRevision != -1);
|
||||||
|
@ -71,6 +71,7 @@ void BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen
|
||||||
{
|
{
|
||||||
dependencyEntry->mRevision = dependentType->mRevision;
|
dependencyEntry->mRevision = dependentType->mRevision;
|
||||||
dependencyEntry->mFlags = flags;
|
dependencyEntry->mFlags = flags;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -78,10 +79,14 @@ void BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen
|
||||||
{
|
{
|
||||||
dependencyEntry->mRevision = dependentType->mRevision;
|
dependencyEntry->mRevision = dependentType->mRevision;
|
||||||
dependencyEntry->mFlags = flags;
|
dependencyEntry->mFlags = flags;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if ((dependencyEntry->mFlags & flags) == flags)
|
||||||
|
return false;
|
||||||
dependencyEntry->mFlags = (BfDependencyMap::DependencyDependencyFlag)(dependencyEntry->mFlags | flags);
|
dependencyEntry->mFlags = (BfDependencyMap::DependencyDependencyFlag)(dependencyEntry->mFlags | flags);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,8 @@ public:
|
||||||
DependencyFlag_TypeReference = 0x100000, // Explicit type reference for things like tuples, so all referencing types get passed over on symbol reference
|
DependencyFlag_TypeReference = 0x100000, // Explicit type reference for things like tuples, so all referencing types get passed over on symbol reference
|
||||||
DependencyFlag_Allocates = 0x200000,
|
DependencyFlag_Allocates = 0x200000,
|
||||||
DependencyFlag_NameReference = 0x400000,
|
DependencyFlag_NameReference = 0x400000,
|
||||||
DependencyFlag_VirtualCall = 0x800000
|
DependencyFlag_VirtualCall = 0x800000,
|
||||||
|
DependencyFlag_WeakReference = 0x1000000, // Keeps alive but won't rebuild
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DependencyEntry
|
struct DependencyEntry
|
||||||
|
@ -102,7 +103,7 @@ public:
|
||||||
TypeMap mTypeSet;
|
TypeMap mTypeSet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void AddUsedBy(BfType* dependentType, DependencyDependencyFlag flags);
|
bool AddUsedBy(BfType* dependentType, DependencyDependencyFlag flags);
|
||||||
bool IsEmpty();
|
bool IsEmpty();
|
||||||
TypeMap::iterator begin();
|
TypeMap::iterator begin();
|
||||||
TypeMap::iterator end();
|
TypeMap::iterator end();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue