Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions src/coreclr/vm/methodtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9208,6 +9208,37 @@ MethodTable::ResolveVirtualStaticMethod(MethodTable* pInterfaceType, MethodDesc*
{
return pMD;
}

if (pInterfaceType->HasVariance())
{
// Variant interface dispatch
MethodTable::InterfaceMapIterator it = IterateInterfaceMap();
while (it.Next())
{
if (it.GetInterface() == pInterfaceType)
{
// This is the variant interface check logic, skip the
continue;
}

if (!it.GetInterface()->HasSameTypeDefAs(pInterfaceType))
{
// Variance matches require a typedef match
continue;
}

if (it.GetInterface()->CanCastTo(pInterfaceType, NULL))
{
// Variant matching interface found
// Attempt to resolve on variance matched interface
pMD = pMT->TryResolveVirtualStaticMethodOnThisType(it.GetInterface(), pInterfaceMD);
if (pMD != nullptr)
{
return pMD;
}
}
}
}
}
}
}
Expand Down Expand Up @@ -9238,8 +9269,6 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType
// This gets the count out of the metadata interface.
uint32_t dwNumberMethodImpls = hEnumMethodImpl.EnumMethodImplGetCount();

// TODO: support type-equivalent interface type matches and variant interface scenarios

// Iterate through each MethodImpl declared on this class
for (uint32_t i = 0; i < dwNumberMethodImpls; i++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
.method public newslot virtual abstract static int32 Method() cil managed noinlining
{
} // end of method Method
} // end of class InterfaceScenario1
} // end of class InterfaceScenario1`1

.class interface public abstract auto ansi InterfaceScenario2`1<- T>
{
.method public newslot virtual abstract static int32 Method() cil managed noinlining
Expand Down Expand Up @@ -43,7 +44,7 @@

.class public auto ansi BaseScenario2
extends [System.Runtime]System.Object
implements class InterfaceScenario1`1<string>, class InterfaceScenario1`1<object>
implements class InterfaceScenario2`1<string>, class InterfaceScenario2`1<object>
{
// NOTE: The order of the methods in this .il file is important as it controls the MethodImpl record creation order
.method public static int32 Method() cil managed noinlining
Expand Down Expand Up @@ -77,18 +78,18 @@
{
.method public static int32 Method() cil managed noinlining
{
.override method int32 class InterfaceScenario2`1<string>::Method()
.override method int32 class InterfaceScenario2`1<object>::Method()
ldc.i4 6
ret
} // end of method Method

.method public static int32 Method2() cil managed noinlining
{
.override method int32 class InterfaceScenario2`1<string>::Method2()
.override method int32 class InterfaceScenario2`1<object>::Method2()
ldc.i4 7
ret
} // end of method Method
} // end of class DerivedScenario1
} // end of class DerivedScenario2


.class public auto ansi TestEntrypoint
Expand All @@ -106,7 +107,7 @@
ret
} // end of method Test_Scenario1

.method public static string Test_Scenario2_1<T, (class InterfaceScenario1`1<!!0>) ImplType>() cil managed noinlining
.method public static string Test_Scenario2_1<T, (class InterfaceScenario2`1<!!0>) ImplType>() cil managed noinlining
{
// Variant dispatch to method on base type
.locals init (int32 V_1)
Expand All @@ -118,7 +119,7 @@
ret
} // end of method Test_Scenario1

.method public static string Test_Scenario2_2<T, (class InterfaceScenario1`1<!!0>) ImplType>() cil managed noinlining
.method public static string Test_Scenario2_2<T, (class InterfaceScenario2`1<!!0>) ImplType>() cil managed noinlining
{
// Variant dispatch to method on base type
.locals init (int32 V_1)
Expand Down