Skip to content

Commit

Permalink
Enable support for generic methods with IDIC (#90180)
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronRobinsonMSFT authored Aug 9, 2023
1 parent 40b39ff commit a3dde4a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
1 change: 0 additions & 1 deletion src/coreclr/vm/methodtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,6 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule
// we call GetInterfaceImplementation on the object and call GetMethodDescForInterfaceMethod
// with whatever type it returns.
if (pServerMT->IsIDynamicInterfaceCastable()
&& !pItfMD->HasMethodInstantiation()
&& !TypeHandle(pServerMT).CanCastTo(ownerType)) // we need to make sure object doesn't implement this interface in a natural way
{
TypeHandle implTypeHandle;
Expand Down
43 changes: 43 additions & 0 deletions src/tests/Interop/IDynamicInterfaceCastable/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public interface ITest
public interface ITestGeneric<in T, out U>
{
U ReturnArg(T t);
V DoubleGenericArg<V>(V t);
}

public interface IDirectlyImplemented
Expand Down Expand Up @@ -140,6 +141,23 @@ U ITestGeneric<T, U>.ReturnArg(T t)

return Unsafe.As<T, U>(ref t);
}

V ITestGeneric<T, U>.DoubleGenericArg<V>(V v)
{
if (v is int i)
{
Assert.True(typeof(V) == typeof(int));
i *= 2;
return Unsafe.As<int, V>(ref i);
}
else if (v is string s)
{
Assert.True(typeof(V) == typeof(string));
s += s;
return Unsafe.As<string, V>(ref s);
}
throw new Exception("Unable to double");
}
}

[DynamicInterfaceCastableImplementation]
Expand All @@ -149,6 +167,23 @@ int ITestGeneric<int, int>.ReturnArg(int i)
{
return i;
}

V ITestGeneric<int, int>.DoubleGenericArg<V>(V v)
{
if (v is int i)
{
Assert.True(typeof(V) == typeof(int));
i *= 2;
return Unsafe.As<int, V>(ref i);
}
else if (v is string s)
{
Assert.True(typeof(V) == typeof(string));
s += s;
return Unsafe.As<string, V>(ref s);
}
throw new Exception("Unable to double");
}
}

[DynamicInterfaceCastableImplementation]
Expand Down Expand Up @@ -374,6 +409,14 @@ private static void ValidateGenericInterface()
Assert.Equal(expectedStr, testStr.ReturnArg(expectedStr));
Assert.Equal(expectedStr, testVar.ReturnArg(expectedStr));

Console.WriteLine(" -- Validate generic method call");
Assert.Equal(expectedInt * 2, testInt.DoubleGenericArg<int>(42));
Assert.Equal(expectedStr + expectedStr, testInt.DoubleGenericArg<string>("str"));
Assert.Equal(expectedInt * 2, testStr.DoubleGenericArg<int>(42));
Assert.Equal(expectedStr + expectedStr, testStr.DoubleGenericArg<string>("str"));
Assert.Equal(expectedInt * 2, testVar.DoubleGenericArg<int>(42));
Assert.Equal(expectedStr + expectedStr, testVar.DoubleGenericArg<string>("str"));

Console.WriteLine(" -- Validate delegate call");
Func<int, int> funcInt = new Func<int, int>(testInt.ReturnArg);
Assert.Equal(expectedInt, funcInt(expectedInt));
Expand Down

0 comments on commit a3dde4a

Please sign in to comment.