Bug 60545 - Multiple argument generic with contravariant interface as an argument causes MissingMethodException.
Summary: Multiple argument generic with contravariant interface as an argument causes ...
Alias: None
Product: Runtime
Classification: Mono
Component: General ()
Version: 5.8 (2017-10)
Hardware: PC All
: Normal normal
Target Milestone: Future Cycle (TBD)
Assignee: Aleksey Kliger
Depends on:
Reported: 2017-11-07 05:04 UTC by Timofey Pokhilenko
Modified: 2018-01-05 13:27 UTC (History)
4 users (show)

Tags: bugpool-archive
Is this bug a regression?: ---
Last known good build:

Minimal code reproducing this bug. See the readme file. (2.85 KB, application/gzip)
2017-11-07 05:04 UTC, Timofey Pokhilenko

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Timofey Pokhilenko 2017-11-07 05:04:27 UTC
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)
Comment 1 Ludovic Henry 2017-11-08 18:08:06 UTC
I can reproduce with Mono (2017-10/ce494e3d152)
Comment 2 Aleksey Kliger 2017-11-14 16:30:18 UTC
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
Comment 3 Aleksey Kliger 2017-11-16 22:36:38 UTC
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*.
Comment 4 Ludovic Henry 2017-11-21 20:30:31 UTC
Comment 5 Ludovic Henry 2017-11-21 20:31:16 UTC
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
Comment 6 Aleksey Kliger 2017-11-22 21:52:05 UTC
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).