DefType defType = _type.GetClosestDefType();
+ // Interfaces don't have vtables and we don't need to track their slot use.
+ // The only exception are those interfaces that provide IDynamicInterfaceCastable implementations;
+ // those have slots and we dispatch on them.
+ bool needsDependenciesForVirtualMethodImpls = !defType.IsInterface
+ || ((MetadataType)defType).IsDynamicInterfaceCastableImplementation();
+
// If we're producing a full vtable, none of the dependencies are conditional.
- if (!factory.VTable(defType).HasFixedSlots)
+ needsDependenciesForVirtualMethodImpls &= !factory.VTable(defType).HasFixedSlots;
+
+ if (needsDependenciesForVirtualMethodImpls)
{
foreach (MethodDesc decl in defType.EnumAllVirtualSlots())
{
TestAbstractTypeNeverDerivedVirtualsOptimization.Run();
TestAbstractNeverDerivedWithDevirtualizedCall.Run();
TestAbstractDerivedByUnrelatedTypeWithDevirtualizedCall.Run();
+ TestUnusedDefaultInterfaceMethod.Run();
return 100;
}
}
}
+ class TestUnusedDefaultInterfaceMethod
+ {
+ interface IFoo<T>
+ {
+ void DoSomething();
+ }
+
+ interface IBar<T> : IFoo<T>
+ {
+ void IFoo<T>.DoSomething()
+ {
+ Activator.CreateInstance(typeof(NeverReferenced));
+ }
+ }
+
+ class NeverReferenced { }
+
+ class SomeInstance : IBar<object>
+ {
+ void IFoo<object>.DoSomething() { }
+ }
+
+ static IFoo<object> s_instance = new SomeInstance();
+
+ public static void Run()
+ {
+ s_instance.DoSomething();
+
+ ThrowIfPresent(typeof(TestUnusedDefaultInterfaceMethod), nameof(NeverReferenced));
+ }
+ }
+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "That's the point")]
private static bool IsTypePresent(Type testType, string typeName) => testType.GetNestedType(typeName, BindingFlags.NonPublic | BindingFlags.Public) != null;