From 76cd052c4ad8f86e68c025154722eae338308c1a Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 19 Sep 2020 05:12:15 -0700 Subject: [PATCH] Fixed MethodToString for unspecialized type variations --- IDE/Tests/CompileFail001/src/Generics.bf | 20 ++++++++++++++++++-- IDEHelper/Compiler/BfCompiler.cpp | 2 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 2 +- IDEHelper/Compiler/BfModule.cpp | 15 +++++++-------- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 13 ++++++++----- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 5 +++++ IDEHelper/Compiler/BfResolvedTypeUtils.h | 1 + 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/IDE/Tests/CompileFail001/src/Generics.bf b/IDE/Tests/CompileFail001/src/Generics.bf index 6527df3d..8f1d18b4 100644 --- a/IDE/Tests/CompileFail001/src/Generics.bf +++ b/IDE/Tests/CompileFail001/src/Generics.bf @@ -17,8 +17,6 @@ namespace IDETest { class Generics { - - public void Method1(T val) where T : Array { @@ -38,5 +36,23 @@ namespace IDETest { } + + interface IFaceA + { + public void MethodA(T val, M1 val2, delegate T (M1 arg) val3); + } + + class ClassA : IFaceA<(T1, T2)> //FAIL 'IDETest.Generics.ClassA' does not implement interface member 'IDETest.Generics.IFaceA<(T1, T2)>.MethodA((T1, T2) val, M1 val2, delegate (T1, T2)(M1 arg) val3)' + { + void MethodA(int a) + { + + } + + void MethodB() + { + function void() f = => MethodA; //FAIL Method 'IDETest.Generics.ClassA.MethodA(int a)' does not match function 'function void()' + } + } } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 3fbc5443..2e99d65b 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -4769,7 +4769,7 @@ void BfCompiler::GetSymbolReferences() // ++methodItr; } - if ((rebuildMethodInstance->mIsUnspecializedVariation) || (rebuildMethodInstance->IsSpecializedGenericMethod())) + if ((rebuildMethodInstance->IsOrInUnspecializedVariation()) || (rebuildMethodInstance->IsSpecializedGenericMethod())) continue; SetAndRestoreValue prevTypeInstance(rebuildModule->mCurMethodInstance, rebuildMethodInstance); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 2581b9e7..18ac9dfd 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -7655,7 +7655,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual); - if ((moduleMethodInstance.mMethodInstance->mIsUnspecializedVariation) && (!mModule->mBfIRBuilder->mIgnoreWrites)) + if ((moduleMethodInstance.mMethodInstance->IsOrInUnspecializedVariation()) && (!mModule->mBfIRBuilder->mIgnoreWrites)) { // Invalid methods such as types with a HasVar tuple generic arg will be marked as mIsUnspecializedVariation and shouldn't actually be called FinishDeferredEvals(argValues.mResolvedArgs); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index d11c9df2..d8b71acb 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -2647,7 +2647,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation())) return NULL; - if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation)) + if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation())) return NULL; // Ignore errors on unspecialized variations, they are always dups if (!mHadBuildError) mHadBuildError = true; @@ -9781,9 +9781,6 @@ String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags String methodName; if ((methodNameFlags & BfMethodNameFlag_OmitTypeName) == 0) { - // Don't use the 'mCurMethodInstance' owner for the type instance if there's one already set - SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); - methodName = TypeToString(type, typeNameFlags); if (methodName == "$") methodName = ""; @@ -13977,7 +13974,7 @@ void BfModule::AssertErrorState() if (mCurMethodInstance != NULL) { - if (mCurMethodInstance->mIsUnspecializedVariation) + if (mCurMethodInstance->IsOrInUnspecializedVariation()) return; if (mCurMethodInstance->mHasFailed) return; @@ -16925,6 +16922,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) if (!methodInstance->mIsReified) BF_ASSERT(!mIsReified); + BF_ASSERT(!methodInstance->GetOwner()->IsUnspecializedTypeVariation()); + if (methodInstance->mMethodInfoEx != NULL) { for (auto methodGenericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments) @@ -19423,7 +19422,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth bool wantsVisitBody = true; if ((methodDef->mMethodType == BfMethodType_Mixin) && (!methodGenericArguments.IsEmpty())) wantsVisitBody = false; - if (methodInstance->mIsUnspecializedVariation) + if (methodInstance->IsOrInUnspecializedVariation()) wantsVisitBody = false; if (wantsVisitBody) @@ -19681,7 +19680,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth auto deferMethodState = rootMethodState; // Since we handle errors & warnings in the capture phase, we don't need to process any local methods for resolve-only (unless we're doing a mDbgVerifyCodeGen) - if ((!localMethod->mDeclOnly) && (!methodInstance->mIsUnspecializedVariation) && + if ((!localMethod->mDeclOnly) && (!methodInstance->IsOrInUnspecializedVariation()) && (!mWantsIRIgnoreWrites) && (methodDef->mMethodType != BfMethodType_Mixin)) { BP_ZONE("BfDeferredLocalMethod:create"); @@ -20215,7 +20214,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool methodInstance->mIsUnspecialized = true; } - methodInstance->mIsUnspecializedVariation |= typeInstance->IsUnspecializedTypeVariation(); + //methodInstance->mIsUnspecializedVariation |= typeInstance->IsUnspecializedTypeVariation(); for (auto genericParamDef : methodDef->mGenericParams) { diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index a19c10c4..d24932ca 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -4841,18 +4841,20 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) if (methodInstance->IsSpecializedByAutoCompleteMethod()) return; - + BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_VData); if ((methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized)) { BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_Unreified); } - if (methodInstance->mIsUnspecializedVariation) + if (methodInstance->IsOrInUnspecializedVariation()) { return; } + BF_ASSERT(!methodInstance->GetOwner()->IsUnspecializedTypeVariation()); + BF_ASSERT(methodInstance->mMethodProcessRequest == NULL); auto defaultMethod = methodInstance->mMethodInstanceGroup->mDefault; @@ -6705,8 +6707,9 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId { // When we're evaluating a method, make sure the params refer back to that method context auto curTypeInstance = mCurTypeInstance; - if (mCurMethodInstance != NULL) - curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner; + //TODO: This caused MethodToString issues with interface "implementation method not found" errors +// if (mCurMethodInstance != NULL) +// curTypeInstance = mCurMethodInstance->mMethodInstanceGroup->mOwner; BfTypeInstance* genericTypeInst = curTypeInstance->ToGenericTypeInstance(); if ((genericTypeInst->IsIncomplete()) && (genericTypeInst->mGenericTypeInfo->mGenericParams.size() == 0)) @@ -7065,7 +7068,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) || (!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) || (genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation); - if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation)) + if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation())) doValidate = false; if (mCurTypeInstance != NULL) { diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index ae8d085e..5beaf461 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -650,6 +650,11 @@ bool BfMethodInstance::IsSpecializedByAutoCompleteMethod() return false; } +bool BfMethodInstance::IsOrInUnspecializedVariation() +{ + return (mIsUnspecializedVariation) || (GetOwner()->IsUnspecializedTypeVariation()); +} + bool BfMethodInstance::HasExternConstraints() { return (mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() > mMethodInfoEx->mMethodGenericArguments.size()); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 878a5b2c..5224d26c 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -867,6 +867,7 @@ public: bool IsSpecializedGenericMethod(); bool IsSpecializedGenericMethodOrType(); bool IsSpecializedByAutoCompleteMethod(); + bool IsOrInUnspecializedVariation(); bool HasExternConstraints(); bool HasThis(); BfType* GetThisType();