From cc3837ee498815929e0806328237ca246d950f09 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 25 Aug 2022 11:44:55 -0700 Subject: [PATCH] Fixed interface method slotting issues --- IDEHelper/Compiler/BfModule.cpp | 23 +++++++++++++++++++---- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 20 +++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 8d4a1f77..51338df5 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -400,21 +400,30 @@ void BfAmbiguityContext::Finish() { auto declMethodInstance = mTypeInstance->mVirtualMethodTable[id].mDeclaringMethod; auto error = mModule->Fail(StrFormat("Method '%s' has ambiguous overrides", mModule->MethodToString(declMethodInstance).c_str()), declMethodInstance->mMethodDef->GetRefNode()); - for (auto candidate : entry->mCandidates) + if (error != NULL) { - mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(candidate).c_str()), candidate->mMethodDef->GetRefNode()); + for (auto candidate : entry->mCandidates) + { + mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", + mModule->MethodToString(candidate, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType)).c_str()), candidate->mMethodDef->GetRefNode()); + } } } else { auto iMethodInst = entry->mInterfaceEntry->mInterfaceType->mMethodInstanceGroups[entry->mMethodIdx].mDefault; auto error = mModule->Fail(StrFormat("Interface method '%s' has ambiguous implementations", mModule->MethodToString(iMethodInst).c_str()), entry->mInterfaceEntry->mDeclaringType->GetRefNode()); - for (auto candidate : entry->mCandidates) + if (error != NULL) { - mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", mModule->MethodToString(candidate).c_str()), candidate->mMethodDef->GetRefNode()); + for (auto candidate : entry->mCandidates) + { + mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", + mModule->MethodToString(candidate, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType)).c_str()), candidate->mMethodDef->GetRefNode()); + } } } } + mEntries.Clear(); } ////////////////////////////////////////////////////////////////////////// @@ -25449,6 +25458,12 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo bool isWorse = false; isBetter = (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface != NULL); isWorse = (prevMethod->mMethodInfoEx != NULL) && (prevMethod->mMethodInfoEx->mExplicitInterface != NULL); + if (isBetter == isWorse) + { + isBetter = methodInstance->mReturnType == iMethodInst->mReturnType; + isWorse = prevMethod->mReturnType == iMethodInst->mReturnType; + } + if (isBetter == isWorse) CompareDeclTypes(typeInstance, methodInstance->mMethodDef->mDeclaringType, prevMethod->mMethodDef->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 1410dc9a..583465c0 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -7081,7 +7081,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } else { - String methodString; + String ifaceMethodString; /// { BfTypeState typeState; @@ -7090,13 +7090,15 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, ifaceMethodInst); - methodString = MethodToString(ifaceMethodInst); + ifaceMethodString = MethodToString(ifaceMethodInst, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType)); } BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration; - BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), methodString.c_str()), typeDecl->mNameNode, true); + BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), ifaceMethodString.c_str()), typeDecl->mNameNode, true); if ((matchedMethod != NULL) && (error != NULL)) { + String matchedMethodString = MethodToString(matchedMethod, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType)); + if (hadStaticFailure) { auto staticNodeRef = matchedMethod->mMethodDef->GetRefNode(); @@ -7106,31 +7108,31 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (matchedMethod->mMethodDef->mIsStatic) mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's static", - methodString.c_str()), staticNodeRef); + matchedMethodString.c_str()), staticNodeRef); else mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not static", - methodString.c_str()), staticNodeRef); + matchedMethodString.c_str()), staticNodeRef); } else if (hadPubFailure) { mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not public", - methodString.c_str()), matchedMethod->mMethodDef->mReturnTypeRef); + matchedMethodString.c_str()), matchedMethod->mMethodDef->mReturnTypeRef); } else if (ifaceMethodInst->mReturnType->IsConcreteInterfaceType()) { mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have a concrete return type that implements '%s'", - methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef); + matchedMethodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef); } else if (hadMutFailure) { mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's market as 'mut' but interface method does not allow it", - methodString.c_str()), matchedMethod->mMethodDef->GetMutNode()); + matchedMethodString.c_str()), matchedMethod->mMethodDef->GetMutNode()); mCompiler->mPassInstance->MoreInfo(StrFormat("Declare the interface method as 'mut' to allow matching 'mut' implementations"), ifaceMethodInst->mMethodDef->mMethodDeclaration); } else { mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have the return type '%s'", - methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef); + matchedMethodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef); if ((ifaceMethodInst->mVirtualTableIdx != -1) && (ifaceMethodInst->mReturnType->IsInterface())) mCompiler->mPassInstance->MoreInfo("Declare the interface method as 'concrete' to allow matching concrete return values", ifaceMethodInst->mMethodDef->GetMethodDeclaration()->mVirtualSpecifier); }