diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 5e0ba6c09bfd5..c8072a2731256 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -7868,8 +7868,9 @@ MethodTable::ResolveVirtualStaticMethod( ClassLoadLevel level) { CONTRACTL{ - THROWS; - GC_TRIGGERS; + MODE_ANY; + THROWS; + GC_TRIGGERS; } CONTRACTL_END; bool verifyImplemented = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::VerifyImplemented) != ResolveVirtualStaticMethodFlags::None; @@ -8029,6 +8030,12 @@ MethodTable::ResolveVirtualStaticMethod( MethodDesc* MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags, ClassLoadLevel level) { + CONTRACTL{ + MODE_ANY; + THROWS; + GC_TRIGGERS; + } CONTRACTL_END; + bool instantiateMethodParameters = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc) != ResolveVirtualStaticMethodFlags::None; bool allowVariance = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::AllowVariantMatches) != ResolveVirtualStaticMethodFlags::None; bool verifyImplemented = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::VerifyImplemented) != ResolveVirtualStaticMethodFlags::None; @@ -8084,7 +8091,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType { // Allow variant, but not equivalent interface match if (!pInterfaceType->HasSameTypeDefAs(pInterfaceMT) || - !pInterfaceMT->CanCastTo(pInterfaceType, NULL)) + !TypeHandle(pInterfaceMT).CanCastTo(pInterfaceType, NULL)) { continue; } diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.cs b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.cs new file mode 100644 index 0000000000000..8effd9e5c3335 --- /dev/null +++ b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using Xunit; + +// This test comes from https://github.com/dotnet/runtime/issues/107754 + +namespace VariantVirtualStaticDefaultDispatch +{ + interface IStaticConstraint + { + public abstract static void M(); + } + + interface IStaticConstraintDefaultImpl : IStaticConstraint + { + static void IStaticConstraint.M() { } + } + + interface IConstraintCheck where U : IStaticConstraint + { + } + + struct StructThatImplementsConstraint : IStaticConstraintDefaultImpl + { + } + + public class Tests + { + [MethodImpl(MethodImplOptions.NoInlining)] + static void M() where U: IStaticConstraint + { + U.M(); + } + + [Fact] + public static void RunTest() + { + System.Console.WriteLine(typeof(IConstraintCheck)); + M(); + } + } +} diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj new file mode 100644 index 0000000000000..a49d38ec92d3b --- /dev/null +++ b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj @@ -0,0 +1,8 @@ + + + Full + + + + +