Created attachment 25575 [details]
Minimal code reproducing this bug. See the readme file.
Somehow a contravariant interface used as an argument for a generic with more than two arguments causes contravariance failure with MissingMethodException under certain conditions.
See the attached solution with the minimal code. (Readme file with some suggestions is included).
Bug reproduces on:
Mono (both Windows and Linux)
Unity3D (.NET 4.6 runtime, tested on Windows)
Xamarin (tested via x86 Android emulator)
I can reproduce with Mono 220.127.116.11 (2017-10/ce494e3d152)
Interestingly, if you AOT the .exe (and mscorlib.dll) and then run with fullaot, the test passes.
$ mono --full-aot BrokenContravariance.exe
Action performed on String
loader.c:get_constrained_method() is doing complicated things for `constrained.callvirt` calls, to find the method that implements an interface in the constraining class (and gets it wrong in the case of variant interfaces).
But vtable and interface setup already do all the hard work for us. To computer the constrained MonoMethod*:
if constraining a virtual method of a class consult the corresponding vtable entry of the constraining class and return that MonoMethod*.
if constraining an interface method, find the base interface offset of the interface on the constraining class, bump it the interface slot of the method, and look in the corresponding vtable entry for the MonoMethod*.
https://github.com/mono/mono/pull/6067 is a fix for the interpreter which was broken by PR from https://bugzilla.xamarin.com/show_bug.cgi?id=60545#c4
Fixed on mono master after https://github.com/mono/mono/commit/9d6f4309948ef9a967accb6d15ab92cfe3d98e63
(this is a follow-on commit; the original partly incorrect fix was https://github.com/mono/mono/commit/3259e04ace67552fc8d63a8f1ddbb830e526f05f)
Fixed on mono 2017-10 https://github.com/mono/mono/commit/ef5b3b466368252f532d89cf97f10f8b785eca01
(This has the corrected fix).