Repro1:
RuntimeLookupDelegateGenericVirtual.Test<string>();internalclassRuntimeLookupDelegateGenericVirtual{internalstaticvoidTest<T>(){vartest2=newDerived();Delegatem1=test2.Foo<List<T>>();Delegatem2=test2.Foo<List<List<T>>>;if(m1.Method!=m2.Method){thrownewException($"Unexpected different methods returned from generic virtual method.");}}}internalinterfaceBase{publicvirtualDelegateFoo<U>(){returnFoo<U>;}}internalstructDerived:Base{publicDelegateFoo<U1>(){returnFoo<List<U1>>;}}Repro2 (changing the struct to class):
RuntimeLookupDelegateGenericVirtual.Test<string>();internalclassRuntimeLookupDelegateGenericVirtual{internalstaticvoidTest<T>(){vartest2=newDerived();Delegatem1=test2.Foo<List<T>>();Delegatem2=test2.Foo<List<List<T>>>;if(m1.Method!=m2.Method){thrownewException($"Unexpected different methods returned from generic virtual method.");}}}internalinterfaceBase{publicvirtualDelegateFoo<U>(){returnFoo<U>;}}internalclassDerived:Base{publicDelegateFoo<U1>(){returnFoo<List<U1>>;}}Repro3 (changing the interface to a base class, but don't override the method in derived class):
RuntimeLookupDelegateGenericVirtual.Test<string>();internalclassRuntimeLookupDelegateGenericVirtual{internalstaticvoidTest<T>(){vartest2=newDerived();Delegatem1=test2.Foo<List<T>>();Delegatem2=test2.Foo<List<List<T>>>;if(m1.Method!=m2.Method){thrownewException($"Unexpected different methods returned from generic virtual method.");}}}internalclassBase{publicvirtualDelegateFoo<U>(){returnFoo<U>;}}internalclassDerived:Base{publicnewDelegateFoo<U1>(){returnFoo<List<U1>>;}}Ilc will never complete compiling the above snippets and will stick there forever.
It only compiles when you are overriding the base method of a class.
RuntimeLookupDelegateGenericVirtual.Test<string>();internalclassRuntimeLookupDelegateGenericVirtual{internalstaticvoidTest<T>(){vartest2=newDerived();Delegatem1=test2.Foo<List<T>>();Delegatem2=test2.Foo<List<List<T>>>;if(m1.Method!=m2.Method){thrownewException($"Unexpected different methods returned from generic virtual method.");}}}internalclassBase{publicvirtualDelegateFoo<U>(){returnFoo<U>;}}internalclassDerived:Base{publicoverrideDelegateFoo<U1>(){returnFoo<List<U1>>;}}cc: @MichalStrehovsky
Repro1:
Repro2 (changing the struct to class):
Repro3 (changing the interface to a base class, but don't override the method in derived class):
Ilc will never complete compiling the above snippets and will stick there forever.
It only compiles when you are overriding the base method of a class.
cc: @MichalStrehovsky