diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs index 4b3f387a390151..f89602a1950551 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs @@ -15,6 +15,12 @@ public Task DefaultInterfaceMethodCallIntoClass () return RunTest (allowMissingWarnings: true); } + [Fact] + public Task DimProvidedByUnreferencedIfaceInHierarchy () + { + return RunTest (allowMissingWarnings: true); + } + [Fact] public Task GenericDefaultInterfaceMethods () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/Dependencies/DimProvidedByUnreferencedIfaceInHierarchy.il b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/Dependencies/DimProvidedByUnreferencedIfaceInHierarchy.il new file mode 100644 index 00000000000000..416f1202c682ca --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/Dependencies/DimProvidedByUnreferencedIfaceInHierarchy.il @@ -0,0 +1,87 @@ + +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +.assembly extern mscorlib { } + +.assembly 'library' { } + +.class public auto ansi abstract sealed beforefieldinit Program + extends [mscorlib]System.Object +{ + // Nested Types + .class interface nested public auto ansi abstract beforefieldinit IFoo + { + // Methods + .method public hidebysig newslot abstract virtual + instance void Method () cil managed + { + } // end of method IFoo::Method + + } // end of class IFoo + + .class interface nested public auto ansi abstract beforefieldinit IBar + implements Program/IFoo + { + // Methods + .method public final hidebysig virtual + instance void Program.IFoo.Method () cil managed + { + .override method instance void Program/IFoo::Method() + // Method begins at RVA 0x2068 + // Code size 2 (0x2) + .maxstack 8 + + IL_0000: nop + IL_0001: ret + } // end of method IBar::Program.IFoo.Method + + } // end of class IBar + + .class interface nested public auto ansi abstract beforefieldinit IBaz + implements Program/IBar + { + } // end of class IBaz + + .class nested public auto ansi beforefieldinit MyFoo + extends [mscorlib]System.Object + implements Program/IBaz + { + // Methods + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + // Method begins at RVA 0x2076 + // Code size 8 (0x8) + .maxstack 8 + + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method MyFoo::.ctor + + } // end of class MyFoo + + + // Methods + .method public hidebysig static + void CallMethod ( + class Program/IFoo foo + ) cil managed + { + .custom instance void [mscorlib]mscorlib.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( + 01 00 01 00 00 + ) + // Method begins at RVA 0x2050 + // Code size 9 (0x9) + .maxstack 8 + + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: callvirt instance void Program/IFoo::Method() + IL_0007: nop + IL_0008: ret + } // end of method Program::CallMethod + +} // end of class Program diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/Dependencies/StaticDimProvidedByUnreferencedIfaceInHierarchy.il b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/Dependencies/StaticDimProvidedByUnreferencedIfaceInHierarchy.il new file mode 100644 index 00000000000000..949d5e6fbf4aba --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/Dependencies/StaticDimProvidedByUnreferencedIfaceInHierarchy.il @@ -0,0 +1,70 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +.assembly extern mscorlib { } + +.assembly 'library' { } + +.class public auto ansi abstract sealed beforefieldinit Program + extends [mscorlib]System.Object +{ + // Nested Types + .class interface nested public auto ansi abstract beforefieldinit IBase + { + // Methods + .method public hidebysig abstract virtual static + void Method () cil managed + { + } // end of method IBase::Method + + } // end of class IBase + + .class interface nested public auto ansi abstract beforefieldinit I2 + implements Program/IBase + { + // Methods + .method public hidebysig static + void Program.IBase.Method () cil managed + { + .override method void Program/IBase::Method() + // Method begins at RVA 0x205f + // Code size 2 (0x2) + .maxstack 8 + + IL_0000: nop + IL_0001: ret + } // end of method I2::Program.IBase.Method + + } // end of class I2 + + .class interface nested public auto ansi abstract beforefieldinit I3 + implements Program/I2 + { + } // end of class I3 + + .class interface nested public auto ansi abstract beforefieldinit I4 + implements Program/I3 + { + } // end of class I4 + + + // Methods + .method public hidebysig static + void CallMethod<(Program/IBase) T> () cil managed + { + .param constraint T, Program/IBase + .custom instance void [mscorlib]mscorlib.CompilerServices.NullableAttribute::.ctor(uint8) = ( + 01 00 01 00 00 + ) + // Method begins at RVA 0x2050 + // Code size 14 (0xe) + .maxstack 8 + + IL_0000: nop + IL_0001: constrained. !!T + IL_0007: call void Program/IBase::Method() + IL_000c: nop + IL_000d: ret + } // end of method Program::CallMethod + +} // end of class Program diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByUnreferencedIfaceInHierarchy.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByUnreferencedIfaceInHierarchy.cs new file mode 100644 index 00000000000000..7b749d20d46c24 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByUnreferencedIfaceInHierarchy.cs @@ -0,0 +1,68 @@ + + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.DefaultInterfaceMethods +{ + [SetupLinkerArgument ("--skip-unresolved", "true")] + [TestCaseRequirements (TestRunCharacteristics.SupportsDefaultInterfaceMethods, "Requires support for default interface methods")] + [Define ("IL_ASSEMBLY_AVAILABLE")] + [SetupCompileBefore ("library.dll", new[] { "Dependencies/DimProvidedByUnreferencedIfaceInHierarchy.il" })] + [SkipILVerify] + +#if IL_ASSEMBLY_AVAILABLE + [KeptMemberInAssembly ("library.dll", typeof(Program.IFoo), "Method()")] + // https://github.com/dotnet/runtime/issues/98536 + // [KeptTypeInAssembly ("library.dll", typeof(Program.IBar))] + // [KeptMemberInAssembly ("library.dll", typeof(Program.IBar), "Program.IFoo.Method()")] + // [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.IBar), "library.dll", typeof (Program.IFoo))] + // [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.MyFoo), "library.dll", typeof (Program.IBaz))] + // [KeptTypeInAssembly ("library.dll", typeof(Program.IBaz))] + // [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.IBaz), "library.dll", typeof (Program.IBar))] + [KeptMemberInAssembly ("library.dll", typeof(Program), "CallMethod(Program/IFoo)")] +#endif + class DimProvidedByUnreferencedIfaceInHierarchy + { + static void Main () + { +#if IL_ASSEMBLY_AVAILABLE + Program.IFoo foo = new Program.MyFoo (); + Program.CallMethod(foo); +#endif + } + } +} + + + +// public static class Program +// { +// [Kept] +// interface IFoo +// { +// void Method(); +// } + +// [Kept] +// interface IBar : IFoo +// { +// [Kept] +// void IFoo.Method() { } +// } + +// [Kept] +// interface IBaz: IBar /* not IFoo */ +// { +// } + +// [Kept] +// [KeptInterface(typeof(IBaz))] +// class MyFoo : IBaz /* not IBar, not IFoo */ +// { } + +// static void CallMethod(IFoo foo) +// { +// foo.Method(); +// } +// } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs new file mode 100644 index 00000000000000..1cb85f6c0e0c4f --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs @@ -0,0 +1,70 @@ + + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.DefaultInterfaceMethods +{ + [SetupLinkerArgument ("--skip-unresolved", "true")] + [TestCaseRequirements (TestRunCharacteristics.SupportsDefaultInterfaceMethods, "Requires support for default interface methods")] + [Define ("IL_ASSEMBLY_AVAILABLE")] + [SetupCompileBefore ("library.dll", new[] { "Dependencies/StaticDimProvidedByUnreferencedIfaceInHierarchy.il" })] + [SkipILVerify] + +#if IL_ASSEMBLY_AVAILABLE + [KeptMemberInAssembly ("library.dll", typeof(Program), "CallMethod<#1>()")] + [KeptTypeInAssembly ("library.dll", typeof(Program.IBase))] + [KeptMemberInAssembly ("library.dll", typeof(Program.IBase), "Method()")] + [KeptTypeInAssembly ("library.dll", typeof(Program.I4))] + // https://github.com/dotnet/runtime/issues/98536 + // [KeptTypeInAssembly ("library.dll", typeof(Program.I2))] + // [KeptMemberInAssembly ("library.dll", typeof(Program.I2), "Program.IBase.Method()")] + // [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I2), "library.dll", typeof (Program.IBase))] + // [KeptTypeInAssembly ("library.dll", typeof(Program.I3))] + // [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I3), "library.dll", typeof (Program.I2))] + // [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I4), "library.dll", typeof (Program.I3))] +#endif + class StaticDimProvidedByUnreferencedIfaceInHierarchy + { + static void Main () + { +#if IL_ASSEMBLY_AVAILABLE + Program.CallMethod(); +#endif + } + } +} + + + +// public static class Program +// { +// [Kept] +// interface IBase +// { +// [Kept] +// static abstract void Method(); +// } + +// [Kept] +// [KeptInterface(typeof(IBase)] +// interface I2 : IBase +// { +// [Kept] +// static void IBase.Method() { } +// } + +// [Kept] +// [KeptInterface(typeof(I2)] +// interface I3 : I2 { } + +// [Kept] +// [KeptInterface(typeof(I3)] +// interface I4 : I3 { } + +// [Kept] +// static void CallMethod() where T : IBase +// { +// T.Method(); +// } +// }