Do not trim generic interfaces implemented by arrays (#40260)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Wed, 5 Aug 2020 10:59:48 +0000 (12:59 +0200)
committerGitHub <noreply@github.com>
Wed, 5 Aug 2020 10:59:48 +0000 (12:59 +0200)
Logic within the CoreCLR VM depends on the order of methods on these interfaces to find methods on SZArrayHelper.

SZArrayHelper is already rooted from MscorlibBinder, but the interface methods are referenced only implicitly through their slots and need a dedicated entry.

src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml
src/libraries/Microsoft.Extensions.DependencyInjection/tests/TrimmingTests/ActivatorUtilitiesTests.cs
src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs [new file with mode: 0644]
src/libraries/System.Runtime/tests/TrimmingTests/System.Runtime.TrimmingTests.proj

index 11a67fd..8031688 100644 (file)
     <type fullname="System.Runtime.InteropServices.IDispatch" />
     <type fullname="System.Runtime.InteropServices.IMarshal" />
     <type fullname="Internal.Runtime.InteropServices.IClassFactory2" />
+
+    <!-- GetActualImplementationForArrayGenericIListOrIReadOnlyListMethod depends on slots of these interfaces not changing -->
+    <type fullname="System.Collections.Generic.IEnumerable`1" />
+    <type fullname="System.Collections.Generic.ICollection`1" />
+    <type fullname="System.Collections.Generic.IReadOnlyCollection`1" />
+    <type fullname="System.Collections.Generic.IList`1" />
+    <type fullname="System.Collections.Generic.IReadOnlyList`1" />
   </assembly>
 </linker>
index eef18d3..2a3e227 100644 (file)
@@ -10,15 +10,14 @@ class Program
     {
         ServiceProvider provider = new ServiceCollection().BuildServiceProvider();
 
-        // ActivatorUtilities.CreateFactory fails due to https://github.com/mono/linker/issues/1398
-        //ObjectFactory factory = ActivatorUtilities.CreateFactory(typeof(ServiceA), Array.Empty<Type>());
-        //ServiceA serviceA = factory(provider, null) as ServiceA;
+        ObjectFactory factory = ActivatorUtilities.CreateFactory(typeof(ServiceA), Array.Empty<Type>());
+        ServiceA serviceA = factory(provider, null) as ServiceA;
         ServiceB serviceB = ActivatorUtilities.CreateInstance(provider, typeof(ServiceB)) as ServiceB;
         ServiceC serviceC = ActivatorUtilities.CreateInstance<ServiceC>(provider);
         ServiceD serviceD = ActivatorUtilities.GetServiceOrCreateInstance(provider, typeof(ServiceD)) as ServiceD;
         ServiceE serviceE = ActivatorUtilities.GetServiceOrCreateInstance<ServiceE>(provider);
 
-        if (//serviceA is null ||
+        if (serviceA is null ||
             serviceB is null ||
             serviceC is null ||
             serviceD is null ||
diff --git a/src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs b/src/libraries/System.Runtime/tests/TrimmingTests/InterfacesOnArrays.cs
new file mode 100644 (file)
index 0000000..f8c76da
--- /dev/null
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+
+class Program
+{
+    class Mine { }
+
+    static int Main()
+    {
+        Mine[] s = new Mine[1] { new Mine() };
+        Mine[] d = new Mine[1];
+        ((ICollection<Mine>)s).CopyTo(d, 0);
+        return s[0] == d[0] ? 100 : -1;
+    }
+}
index ce96e07..ce80b61 100644 (file)
@@ -9,6 +9,7 @@
     <TestConsoleAppSourceFiles Include="DebuggerTypeProxyAttributeTests.cs" />
     <TestConsoleAppSourceFiles Include="DefaultValueAttributeCtorTest.cs" />
     <TestConsoleAppSourceFiles Include="GenericArraySortHelperTest.cs" />
+    <TestConsoleAppSourceFiles Include="InterfacesOnArrays.cs" />
     <TestConsoleAppSourceFiles Include="StackFrameHelperTest.cs">
       <!-- There is a bug with the linker where it is corrupting the pdbs while trimming
       causing the framework to not be able to get source line info any longer. This