Bug 13704 - JIT compile exception when using ObservableCollection with custom value types
Summary: JIT compile exception when using ObservableCollection with custom value types
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 6.9.3.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Zoltan Varga
Depends on:
Reported: 2013-08-02 04:49 UTC by kissling
Modified: 2013-08-05 06:48 UTC (History)
2 users (show)

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

Sample project where the described issue occurs. (3.72 KB, application/zip)
2013-08-02 04:49 UTC, kissling

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 Developer Community or GitHub 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 kissling 2013-08-02 04:49:32 UTC
Created attachment 4521 [details]
Sample project where the described issue occurs.

When using System.Collections.ObjectModel.ObservableCollection<T> with a struct as type parameter, a JIT compile exception occurs when trying to check whether an element is contained.

    struct E : IEquatable<E>

    var c = new ObservableCollection<E>();
    c.Add(new E());
    c.Contains(new E());

Steps to reproduce:
1. Open the attached project in Xamarin Studio.
2. Choose a physical device as deployment target (not simulator).
3. Run the project.
4. When the application is launched, hit the "Test" button.

The following exception will occur:

Unhandled managed exception: Attempting to JIT compile method 'System.Collections.Generic.GenericEqualityComparer`1<E>:Equals (E,E)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.
  at (wrapper unknown) object:gsharedvt_out ()
  at System.Array.IndexOf[E] (E[] array, E value, Int32 startIndex, Int32 count) [0x0004d] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Array.cs:3024 
  at (wrapper unknown) object:gsharedvt_in ()
  at (wrapper unknown) object:gsharedvt_out ()
  at System.Collections.Generic.List`1[E].Contains (E item) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Collections.Generic/List.cs:181 
  at (wrapper unknown) object:gsharedvt_in ()
  at System.Collections.ObjectModel.Collection`1[E].Contains (E item) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:95 
  at ViewController.<LoadView>m__0 (System.Object s, System.EventArgs a) [0x00020] in /***/Main.cs:44 
  at MonoTouch.UIKit.UIControlEventProxy.Activated () [0x00000] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIControl.cs:30 
  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
  at Application.Main (System.String[] args) [0x00008] in /***/Main.cs:12 

A workaround is prepared in the project that forces AOT compilation, preventing the exception from occuring.

To enable the workaround, uncomment line 49 of Main.cs in the attached project.

EqualityComparer<E>.Default.Equals(new E(), new E());

Note that the workaround may also be put in an unreachable code section, as long as the compiler does not detect this. One way to accomplish that is to use a for loop:

for (bool workaround = false; workaround; )
    EqualityComparer<E>.Default.Equals(new E(), new E());

Version information:
Xamarin Studio
Version 4.1.7 (build 87)
Installation UUID: 938751df-f7a5-457d-b87b-379763e0ada1
	Mono 3.2.1 ((no/f3f789e)
	GTK 2.24.20
	GTK# (
	Package version: 302010001

Apple Developer Tools
Xcode 5.0 (3329.25)
Build 5A11365j

Version: (Business Edition)
Hash: 7f9e851
Build date: 2013-10-07 12:10:26-0400

Xamarin.Mac: Not Installed

Version: 4.8.1 (Business Edition)
Android SDK: /Users/***/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		4.0   (API level 14)
		4.0.3 (API level 15)
Java SDK: /usr
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-11M4509)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)

Build Information
Release ID: 401070087
Git revision: e8d353852416693588e6e53a5c2b2d70e5ddadfb
Build date: 2013-07-18 15:32:11+0000
Xamarin addins: 7a764a450cd980c7942b91f12ac36947f9c6a71f

Operating System
Mac OS X 10.8.4
Darwin ***.local 12.4.0 Darwin Kernel Version 12.4.0
    Wed May  1 17:57:12 PDT 2013
    root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64
Comment 1 Zoltan Varga 2013-08-03 00:46:16 UTC
This is caused by the missing support for constrained generic calls in gsharedvt code, in this case, the
call to IEquatable<T>.Equals().
Comment 2 Zoltan Varga 2013-08-04 03:32:21 UTC
Fixed in mono 568e0bc8031be523d506bc5ba1d30d8ce6ceff6b.
Comment 3 Rolf Bjarne Kvinge [MSFT] 2013-08-05 05:14:55 UTC
Zoltan, is it ok to put this fix in the mono 3.2 branch?
Comment 4 Zoltan Varga 2013-08-05 06:40:12 UTC
It depends on other changes, so it has to wait until the next master based release.
Comment 5 Rolf Bjarne Kvinge [MSFT] 2013-08-05 06:48:44 UTC

That'll probably be a couple of months, but it's too early to say anything more specific yet.