mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Fixed interface method slotting issues
This commit is contained in:
parent
1c794f37b1
commit
cc3837ee49
2 changed files with 30 additions and 13 deletions
|
@ -400,21 +400,30 @@ void BfAmbiguityContext::Finish()
|
||||||
{
|
{
|
||||||
auto declMethodInstance = mTypeInstance->mVirtualMethodTable[id].mDeclaringMethod;
|
auto declMethodInstance = mTypeInstance->mVirtualMethodTable[id].mDeclaringMethod;
|
||||||
auto error = mModule->Fail(StrFormat("Method '%s' has ambiguous overrides", mModule->MethodToString(declMethodInstance).c_str()), declMethodInstance->mMethodDef->GetRefNode());
|
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
|
else
|
||||||
{
|
{
|
||||||
auto iMethodInst = entry->mInterfaceEntry->mInterfaceType->mMethodInstanceGroups[entry->mMethodIdx].mDefault;
|
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());
|
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;
|
bool isWorse = false;
|
||||||
isBetter = (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface != NULL);
|
isBetter = (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface != NULL);
|
||||||
isWorse = (prevMethod->mMethodInfoEx != NULL) && (prevMethod->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)
|
if (isBetter == isWorse)
|
||||||
CompareDeclTypes(typeInstance, methodInstance->mMethodDef->mDeclaringType, prevMethod->mMethodDef->mDeclaringType, isBetter, isWorse);
|
CompareDeclTypes(typeInstance, methodInstance->mMethodDef->mDeclaringType, prevMethod->mMethodDef->mDeclaringType, isBetter, isWorse);
|
||||||
if (isBetter == isWorse)
|
if (isBetter == isWorse)
|
||||||
|
|
|
@ -7081,7 +7081,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String methodString;
|
String ifaceMethodString;
|
||||||
///
|
///
|
||||||
{
|
{
|
||||||
BfTypeState typeState;
|
BfTypeState typeState;
|
||||||
|
@ -7090,13 +7090,15 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, ifaceMethodInst);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, ifaceMethodInst);
|
||||||
methodString = MethodToString(ifaceMethodInst);
|
ifaceMethodString = MethodToString(ifaceMethodInst, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration;
|
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))
|
if ((matchedMethod != NULL) && (error != NULL))
|
||||||
{
|
{
|
||||||
|
String matchedMethodString = MethodToString(matchedMethod, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType));
|
||||||
|
|
||||||
if (hadStaticFailure)
|
if (hadStaticFailure)
|
||||||
{
|
{
|
||||||
auto staticNodeRef = matchedMethod->mMethodDef->GetRefNode();
|
auto staticNodeRef = matchedMethod->mMethodDef->GetRefNode();
|
||||||
|
@ -7106,31 +7108,31 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
|
|
||||||
if (matchedMethod->mMethodDef->mIsStatic)
|
if (matchedMethod->mMethodDef->mIsStatic)
|
||||||
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's static",
|
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's static",
|
||||||
methodString.c_str()), staticNodeRef);
|
matchedMethodString.c_str()), staticNodeRef);
|
||||||
else
|
else
|
||||||
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not static",
|
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not static",
|
||||||
methodString.c_str()), staticNodeRef);
|
matchedMethodString.c_str()), staticNodeRef);
|
||||||
}
|
}
|
||||||
else if (hadPubFailure)
|
else if (hadPubFailure)
|
||||||
{
|
{
|
||||||
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's not public",
|
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())
|
else if (ifaceMethodInst->mReturnType->IsConcreteInterfaceType())
|
||||||
{
|
{
|
||||||
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have a concrete return type that implements '%s'",
|
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)
|
else if (hadMutFailure)
|
||||||
{
|
{
|
||||||
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's market as 'mut' but interface method does not allow it",
|
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);
|
mCompiler->mPassInstance->MoreInfo(StrFormat("Declare the interface method as 'mut' to allow matching 'mut' implementations"), ifaceMethodInst->mMethodDef->mMethodDeclaration);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have the return type '%s'",
|
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()))
|
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);
|
mCompiler->mPassInstance->MoreInfo("Declare the interface method as 'concrete' to allow matching concrete return values", ifaceMethodInst->mMethodDef->GetMethodDeclaration()->mVirtualSpecifier);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue