@@ -9189,7 +9189,7 @@ MethodDesc *MethodTable::GetDefaultConstructor(BOOL forceBoxedEntryPoint /* = FA
91899189// ==========================================================================================
91909190// Finds the (non-unboxing) MethodDesc that implements the interface virtual static method pInterfaceMD.
91919191MethodDesc *
9192- MethodTable::ResolveVirtualStaticMethod (MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, BOOL allowNullResult, BOOL checkDuplicates)
9192+ MethodTable::ResolveVirtualStaticMethod (MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, BOOL allowNullResult, BOOL checkDuplicates, BOOL allowVariantMatches )
91939193{
91949194 if (!pInterfaceMD->IsSharedByGenericMethodInstantiations () && !pInterfaceType->IsSharedByGenericInstantiations ())
91959195 {
@@ -9225,7 +9225,7 @@ MethodTable::ResolveVirtualStaticMethod(MethodTable* pInterfaceType, MethodDesc*
92259225 return pMD;
92269226 }
92279227
9228- if (pInterfaceType->HasVariance ())
9228+ if (pInterfaceType->HasVariance () || pInterfaceType-> HasTypeEquivalence () )
92299229 {
92309230 // Variant interface dispatch
92319231 MethodTable::InterfaceMapIterator it = IterateInterfaceMap ();
@@ -9240,12 +9240,26 @@ MethodTable::ResolveVirtualStaticMethod(MethodTable* pInterfaceType, MethodDesc*
92409240 if (!it.GetInterface ()->HasSameTypeDefAs (pInterfaceType))
92419241 {
92429242 // Variance matches require a typedef match
9243+ // Equivalence isn't sufficient, and is uninteresting as equivalent interfaces cannot have static virtuals.
92439244 continue ;
92449245 }
92459246
9246- if (it.GetInterface ()->CanCastTo (pInterfaceType, NULL ))
9247+ BOOL equivalentOrVariantCompatible;
9248+
9249+ if (allowVariantMatches)
9250+ {
9251+ equivalentOrVariantCompatible = it.GetInterface ()->CanCastTo (pInterfaceType, NULL );
9252+ }
9253+ else
9254+ {
9255+ // When performing override checking to ensure that a concrete type is valid, require the implementation
9256+ // actually implement the exact or equivalent interface.
9257+ equivalentOrVariantCompatible = it.GetInterface ()->IsEquivalentTo (pInterfaceType, NULL );
9258+ }
9259+
9260+ if (equivalentOrVariantCompatible)
92479261 {
9248- // Variant matching interface found
9262+ // Variant or equivalent matching interface found
92499263 // Attempt to resolve on variance matched interface
92509264 pMD = pMT->TryResolveVirtualStaticMethodOnThisType (it.GetInterface (), pInterfaceMD, checkDuplicates);
92519265 if (pMD != nullptr )
@@ -9406,7 +9420,7 @@ MethodTable::VerifyThatAllVirtualStaticMethodsAreImplemented()
94069420 MethodDesc *pMD = it.GetMethodDesc ();
94079421 if (pMD->IsVirtual () &&
94089422 pMD->IsStatic () &&
9409- !ResolveVirtualStaticMethod (pInterfaceMT, pMD, /* allowNullResult */ TRUE , /* checkDuplicates */ TRUE ))
9423+ !ResolveVirtualStaticMethod (pInterfaceMT, pMD, /* allowNullResult */ TRUE , /* checkDuplicates */ TRUE , /* allowVariantMatches */ FALSE ))
94109424 {
94119425 IMDInternalImport* pInternalImport = GetModule ()->GetMDImport ();
94129426 GetModule ()->GetAssembly ()->ThrowTypeLoadException (pInternalImport, GetCl (), pMD->GetName (), IDS_CLASSLOAD_STATICVIRTUAL_NOTIMPL);
0 commit comments