From 12a3ba937a089caf4234aafa9c3651632b05052c Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 23 Nov 2021 09:12:10 -0800 Subject: [PATCH] Allow comptime extern constraint typerefs --- IDEHelper/Compiler/BfExprEvaluator.cpp | 36 ++++++++++++----------- IDEHelper/Compiler/BfModule.cpp | 2 ++ IDEHelper/Compiler/BfModule.h | 1 + IDEHelper/Compiler/BfModuleTypeUtils.cpp | 26 ++++++++++++++++ IDEHelper/Compiler/BfSourceClassifier.cpp | 7 ++++- 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index ce012e44..fe85f7cc 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -1547,7 +1547,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL, BfUnaryOpFlag_IsConstraintCheck); if (exprEvaluator.mResult) - checkArgType = exprEvaluator.mResult.mType; + checkArgType = exprEvaluator.mResult.mType; } } } @@ -1557,21 +1557,9 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan { for (auto comptypeConstraint : genericParamInst->mComptypeConstraint) { - BfConstraintState constraintSet; - constraintSet.mPrevState = mModule->mContext->mCurConstraintState; - constraintSet.mGenericParamInstance = genericParamInst; - constraintSet.mMethodInstance = methodInstance; - constraintSet.mMethodGenericArgsOverride = methodGenericArgs; - - SetAndRestoreValue prevConstraintSet(mModule->mContext->mCurConstraintState, &constraintSet); - if (!mModule->CheckConstraintState(NULL)) - return false; - - SetAndRestoreValue prevMethodInstance(mModule->mCurMethodInstance, methodInstance); - SetAndRestoreValue prevTypeInstance(mModule->mCurTypeInstance, methodInstance->GetOwner()); - SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); - - checkArgType = mModule->ResolveTypeRef(comptypeConstraint); + checkArgType = mModule->ResolveGenericMethodTypeRef(comptypeConstraint, methodInstance, genericParamInst, methodGenericArgs); + if (checkArgType == NULL) + return false; } } @@ -2138,7 +2126,21 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst { auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[checkMethod->mGenericParams.size() + externConstraintIdx]; BF_ASSERT(genericParam->mExternType != NULL); - if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericParam->mExternType, NULL, genericParam, genericArgumentsSubstitute, NULL)) + auto externType = genericParam->mExternType; + BfTypeVector* externGenericArgumentsSubstitute = genericArgumentsSubstitute; + + if (externType->IsVar()) + { + auto& externConstraint = checkMethod->mExternalConstraints[externConstraintIdx]; + if (externConstraint.mTypeRef != NULL) + { + externType = mModule->ResolveGenericMethodTypeRef(externConstraint.mTypeRef, methodInstance, genericParam, genericArgumentsSubstitute); + if (externType == NULL) + goto NoMatch; + } + } + + if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), externType, NULL, genericParam, externGenericArgumentsSubstitute, NULL)) goto NoMatch; } diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 3caabc4d..91b171db 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -21956,6 +21956,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool for (auto genericParam : methodInstance->mMethodInfoEx->mGenericParams) { + if (!genericParam->mExternType->IsGenericParam()) + AddDependency(genericParam->mExternType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); for (auto constraintTypeInst : genericParam->mInterfaceConstraints) AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); if (genericParam->mTypeConstraint != NULL) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 2b1acfcb..383946be 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1708,6 +1708,7 @@ public: bool InitGenericParams(BfType* resolvedTypeRef); bool FinishGenericParams(BfType* resolvedTypeRef); bool ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstance* genericTypeInstance, bool ignoreErrors); + BfType* ResolveGenericMethodTypeRef(BfTypeReference* typeRef, BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInstance, BfTypeVector* methodGenericArgsOverride); bool AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter); bool CheckConstraintState(BfAstNode* refNode); bool ShouldAllowMultipleDefinitions(BfTypeInstance* typeInst, BfTypeDef* firstDeclaringTypeDef, BfTypeDef* secondDeclaringTypeDef); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 5d9759ef..d0eec3d2 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -109,6 +109,8 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen for (auto genericParam : genericExEntry->mGenericParams) { + if (!genericParam->mExternType->IsGenericParam()) + AddDependency(genericParam->mExternType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); for (auto constraintTypeInst : genericParam->mInterfaceConstraints) AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); if (genericParam->mTypeConstraint != NULL) @@ -301,6 +303,8 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams) { + if (!genericParam->mExternType->IsGenericParam()) + AddDependency(genericParam->mExternType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); for (auto constraintTypeInst : genericParam->mInterfaceConstraints) AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint); if (genericParam->mTypeConstraint != NULL) @@ -377,6 +381,28 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan return true; } +BfType* BfModule::ResolveGenericMethodTypeRef(BfTypeReference* typeRef, BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInstance, BfTypeVector* methodGenericArgsOverride) +{ + BfConstraintState constraintSet; + constraintSet.mPrevState = mContext->mCurConstraintState; + constraintSet.mGenericParamInstance = genericParamInstance; + constraintSet.mMethodInstance = methodInstance; + constraintSet.mMethodGenericArgsOverride = methodGenericArgsOverride; + + SetAndRestoreValue prevConstraintSet(mContext->mCurConstraintState, &constraintSet); + if (!CheckConstraintState(NULL)) + return NULL; + + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, methodInstance); + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, methodInstance->GetOwner()); + SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); + + BfType* type = ResolveTypeRef(typeRef); + if (type == NULL) + type = GetPrimitiveType(BfTypeCode_Var); + return type; +} + bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter) { if (checkOuter == NULL) diff --git a/IDEHelper/Compiler/BfSourceClassifier.cpp b/IDEHelper/Compiler/BfSourceClassifier.cpp index 0a43776d..31858dba 100644 --- a/IDEHelper/Compiler/BfSourceClassifier.cpp +++ b/IDEHelper/Compiler/BfSourceClassifier.cpp @@ -572,7 +572,12 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration) { BfTypeReference* typeRef = genericConstraint->mTypeRef; if (typeRef != NULL) - SetElementType(typeRef, BfSourceElementType_GenericParam); + { + if (auto namedTypeRef = BfNodeDynCast(typeRef)) + SetElementType(typeRef, BfSourceElementType_GenericParam); + else + VisitChild(typeRef); + } } } }