Merge pull request #637 from LogosBible/enetdown
[mono.git] / mono / mini / generics.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Runtime.CompilerServices;
5 using System.Threading;
6 using System.Threading.Tasks;
7
8 class Tests {
9
10         struct TestStruct {
11                 public int i;
12                 public int j;
13
14                 public TestStruct (int i, int j) {
15                         this.i = i;
16                         this.j = j;
17                 }
18         }
19
20         class Enumerator <T> : MyIEnumerator <T> {
21                 T MyIEnumerator<T>.Current {
22                         get {
23                                 return default(T);
24                         }
25                 }
26
27                 bool MyIEnumerator<T>.MoveNext () {
28                         return true;
29                 }
30         }
31
32         class Comparer <T> : IComparer <T> {
33                 bool IComparer<T>.Compare (T x, T y) {
34                         return true;
35                 }
36         }
37
38         static int Main (string[] args)
39         {
40                 return TestDriver.RunTests (typeof (Tests), args);
41         }
42
43         public static int test_1_nullable_unbox ()
44         {
45                 return Unbox<int?> (1).Value;
46         }
47
48         public static int test_1_nullable_unbox_null ()
49         {
50                 return Unbox<int?> (null).HasValue ? 0 : 1;
51         }
52
53         public static int test_1_nullable_box ()
54         {
55                 return (int) Box<int?> (1);
56         }
57
58         public static int test_1_nullable_box_null ()
59         {
60                 return Box<int?> (null) == null ? 1 : 0;
61         }
62
63         public static int test_1_isinst_nullable ()
64         {
65                 object o = 1;
66                 return (o is int?) ? 1 : 0;
67         }
68
69         public static int test_1_nullable_unbox_vtype ()
70         {
71                 return Unbox<TestStruct?> (new TestStruct (1, 2)).Value.i;
72         }
73
74         public static int test_1_nullable_unbox_null_vtype ()
75         {
76                 return Unbox<TestStruct?> (null).HasValue ? 0 : 1;
77         }
78
79         public static int test_1_nullable_box_vtype ()
80         {
81                 return ((TestStruct)(Box<TestStruct?> (new TestStruct (1, 2)))).i;
82         }
83
84         public static int test_1_nullable_box_null_vtype ()
85         {
86                 return Box<TestStruct?> (null) == null ? 1 : 0;
87         }
88
89         public static int test_1_isinst_nullable_vtype ()
90         {
91                 object o = new TestStruct (1, 2);
92                 return (o is TestStruct?) ? 1 : 0;
93         }
94
95         public static int test_0_nullable_normal_unbox ()
96         {
97                 int? i = 5;
98
99                 object o = i;
100                 // This uses unbox instead of unbox_any
101                 int? j = (int?)o;
102
103                 if (j != 5)
104                         return 1;
105
106                 return 0;
107         }
108
109         public static void stelem_any<T> (T[] arr, T elem) {
110                 arr [0] = elem;
111         }
112
113         public static T ldelem_any<T> (T[] arr) {
114                 return arr [0];
115         }
116
117         public static int test_1_ldelem_stelem_any_int () {
118                 int[] arr = new int [3];
119                 stelem_any (arr, 1);
120
121                 return ldelem_any (arr);
122         }
123
124         public static T return_ref<T> (ref T t) {
125                 return t;
126         }
127
128         public static T ldelema_any<T> (T[] arr) {
129                 return return_ref<T> (ref arr [0]);
130         }
131
132         public static int test_0_ldelema () {
133                 string[] arr = new string [1];
134
135                 arr [0] = "Hello";
136
137                 if (ldelema_any <string> (arr) == "Hello")
138                         return 0;
139                 else
140                         return 1;
141         }
142
143         public static T[,] newarr_multi<T> () {
144                 return new T [1, 1];
145         }
146
147         public static int test_0_newarr_multi_dim () {
148                 return newarr_multi<string> ().GetType () == typeof (string[,]) ? 0 : 1;
149         }
150
151         interface ITest
152         {
153                 void Foo<T> ();
154         }
155
156         public static int test_0_iface_call_null_bug_77442 () {
157                 ITest test = null;
158
159                 try {
160                         test.Foo<int> ();
161                 }
162                 catch (NullReferenceException) {
163                         return 0;
164                 }
165                 
166                 return 1;
167         }
168
169         public static int test_18_ldobj_stobj_generics () {
170                 GenericClass<int> t = new GenericClass <int> ();
171                 int i = 5;
172                 int j = 6;
173                 return t.ldobj_stobj (ref i, ref j) + i + j;
174         }
175
176         public static int test_5_ldelem_stelem_generics () {
177                 GenericClass<TestStruct> t = new GenericClass<TestStruct> ();
178
179                 TestStruct s = new TestStruct (5, 5);
180                 return t.ldelem_stelem (s).i;
181         }
182
183         public static int test_0_constrained_vtype_box () {
184                 GenericClass<TestStruct> t = new GenericClass<TestStruct> ();
185
186                 return t.toString (new TestStruct ()) == "Tests+TestStruct" ? 0 : 1;
187         }
188
189         public static int test_0_constrained_vtype () {
190                 GenericClass<int> t = new GenericClass<int> ();
191
192                 return t.toString (1234) == "1234" ? 0 : 1;
193         }
194
195         public static int test_0_constrained_reftype () {
196                 GenericClass<String> t = new GenericClass<String> ();
197
198                 return t.toString ("1234") == "1234" ? 0 : 1;
199         }
200
201         public static int test_0_box_brtrue_optimizations () {
202                 if (IsNull<int>(5))
203                         return 1;
204
205                 if (!IsNull<object>(null))
206                         return 1;
207
208                 return 0;
209         }
210
211         [Category ("!FULLAOT")]
212         public static int test_0_generic_get_value_optimization_int () {
213                 int[] x = new int[] {100, 200};
214
215                 if (GenericClass<int>.Z (x, 0) != 100)
216                         return 2;
217
218                 if (GenericClass<int>.Z (x, 1) != 200)
219                         return 3;
220
221                 return 0;
222         }
223
224         public static int test_0_generic_get_value_optimization_vtype () {
225                 TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) };
226                 IEnumerator<TestStruct> enumerator = GenericClass<TestStruct>.Y (arr);
227                 TestStruct s;
228                 int sum = 0;
229                 while (enumerator.MoveNext ()) {
230                         s = enumerator.Current;
231                         sum += s.i + s.j;
232                 }
233
234                 if (sum != 1000)
235                         return 1;
236
237                 s = GenericClass<TestStruct>.Z (arr, 0);
238                 if (s.i != 100 || s.j != 200)
239                         return 2;
240
241                 s = GenericClass<TestStruct>.Z (arr, 1);
242                 if (s.i != 300 || s.j != 400)
243                         return 3;
244
245                 return 0;
246         }
247
248         public static int test_0_nullable_ldflda () {
249                 return GenericClass<string>.BIsAClazz == false ? 0 : 1;
250         }
251
252         public struct GenericStruct<T> {
253                 public T t;
254
255                 public GenericStruct (T t) {
256                         this.t = t;
257                 }
258         }
259
260         public class GenericClass<T> {
261                 public T t;
262
263                 public GenericClass (T t) {
264                         this.t = t;
265                 }
266
267                 public GenericClass () {
268                 }
269
270                 public T ldobj_stobj (ref T t1, ref T t2) {
271                         t1 = t2;
272                         T t = t1;
273
274                         return t;
275                 }
276
277                 public T ldelem_stelem (T t) {
278                         T[] arr = new T [10];
279                         arr [0] = t;
280
281                         return arr [0];
282                 }
283
284                 public String toString (T t) {
285                         return t.ToString ();
286                 }
287
288                 public static IEnumerator<T> Y (IEnumerable <T> x)
289                 {
290                         return x.GetEnumerator ();
291                 }
292
293                 public static T Z (IList<T> x, int index)
294                 {
295                         return x [index];
296                 }
297
298         protected static T NullB = default(T);       
299         private static Nullable<bool>  _BIsA = null;
300         public static bool BIsAClazz {
301             get {
302                 _BIsA = false;
303                 return _BIsA.Value;
304             }
305         }
306         }
307
308         public class MRO : MarshalByRefObject {
309                 public GenericStruct<int> struct_field;
310                 public GenericClass<int> class_field;
311         }
312
313         public class MRO<T> : MarshalByRefObject {
314                 public T gen_field;
315
316                 public T stfld_ldfld (T t) {
317                         var m = this;
318                         m.gen_field = t;
319                         return m.gen_field;
320                 }
321         }
322
323         public static int test_0_ldfld_stfld_mro () {
324                 MRO m = new MRO ();
325                 GenericStruct<int> s = new GenericStruct<int> (5);
326                 // This generates stfld
327                 m.struct_field = s;
328
329                 // This generates ldflda
330                 if (m.struct_field.t != 5)
331                         return 1;
332
333                 // This generates ldfld
334                 GenericStruct<int> s2 = m.struct_field;
335                 if (s2.t != 5)
336                         return 2;
337
338                 if (m.struct_field.t != 5)
339                         return 3;
340
341                 m.class_field = new GenericClass<int> (5);
342                 if (m.class_field.t != 5)
343                         return 4;
344
345                 // gshared
346                 var m2 = new MRO<string> ();
347                 if (m2.stfld_ldfld ("A") != "A")
348                         return 5;
349
350                 return 0;
351         }
352
353         // FIXME:
354         [Category ("!FULLAOT")]
355     public static int test_0_generic_virtual_call_on_vtype_unbox () {
356                 object o = new Object ();
357         IFoo h = new Handler(o);
358
359         if (h.Bar<object> () != o)
360                         return 1;
361                 else
362                         return 0;
363     }
364
365         public static int test_0_box_brtrue_opt () {
366                 Foo<int> f = new Foo<int> (5);
367
368                 f [123] = 5;
369
370                 return 0;
371         }
372
373         public static int test_0_box_brtrue_opt_regress_81102 () {
374                 if (new Foo<int>(5).ToString () == "null")
375                         return 0;
376                 else
377                         return 1;
378         }
379
380         struct S {
381                 public int i;
382         }
383
384         public static int test_0_ldloca_initobj_opt () {
385                 if (new Foo<S> (new S ()).get_default ().i != 0)
386                         return 1;
387                 if (new Foo<object> (null).get_default () != null)
388                         return 2;
389                 return 0;
390         }
391
392         public static int test_0_variance_reflection () {
393                 // covariance on IEnumerator
394                 if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (MyIEnumerator<string>)))
395                         return 1;
396                 // covariance on IEnumerator and covariance on arrays
397                 if (!typeof (MyIEnumerator<object>[]).IsAssignableFrom (typeof (MyIEnumerator<string>[])))
398                         return 2;
399                 // covariance and implemented interfaces
400                 if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (Enumerator<string>)))
401                         return 3;
402
403                 // contravariance on IComparer
404                 if (!typeof (IComparer<string>).IsAssignableFrom (typeof (IComparer<object>)))
405                         return 4;
406                 // contravariance on IComparer, contravariance on arrays
407                 if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IComparer<object>[])))
408                         return 5;
409                 // contravariance and interface inheritance
410                 if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IKeyComparer<object>[])))
411                         return 6;
412                 return 0;
413         }
414
415         public static int test_0_ldvirtftn_generic_method () {
416                 new Tests ().ldvirtftn<string> ();              
417
418                 return the_type == typeof (string) ? 0 : 1;
419         }
420
421         public static int test_0_throw_dead_this () {
422         new Foo<string> ("").throw_dead_this ();
423                 return 0;
424         }
425
426         struct S<T> {}
427
428         public static int test_0_inline_infinite_polymorphic_recursion () {
429            f<int>(0);
430
431                    return 0;
432         }
433
434         private static void f<T>(int i) {
435                 if(i==42) f<S<T>>(i);
436         }
437
438         // This cannot be made to work with full-aot, since there it is impossible to
439         // statically determine that Foo<string>.Bar <int> is needed, the code only
440         // references IFoo.Bar<int>
441         [Category ("!FULLAOT")]
442         public static int test_0_generic_virtual_on_interfaces () {
443                 Foo<string>.count1 = 0;
444                 Foo<string>.count2 = 0;
445                 Foo<string>.count3 = 0;
446
447                 IFoo f = new Foo<string> ("");
448                 for (int i = 0; i < 1000; ++i) {
449                         f.Bar <int> ();
450                         f.Bar <string> ();
451                         f.NonGeneric ();
452                 }
453
454                 if (Foo<string>.count1 != 1000)
455                         return 1;
456                 if (Foo<string>.count2 != 1000)
457                         return 2;
458                 if (Foo<string>.count3 != 1000)
459                         return 3;
460
461                 VirtualInterfaceCallFromGenericMethod<long> (f);
462
463                 return 0;
464         }
465
466         public static int test_0_generic_virtual_on_interfaces_ref () {
467                 Foo<string>.count1 = 0;
468                 Foo<string>.count2 = 0;
469                 Foo<string>.count3 = 0;
470                 Foo<string>.count4 = 0;
471
472                 IFoo f = new Foo<string> ("");
473                 for (int i = 0; i < 1000; ++i) {
474                         f.Bar <string> ();
475                         f.Bar <object> ();
476                         f.NonGeneric ();
477                 }
478
479                 if (Foo<string>.count2 != 1000)
480                         return 2;
481                 if (Foo<string>.count3 != 1000)
482                         return 3;
483                 if (Foo<string>.count4 != 1000)
484                         return 4;
485
486                 return 0;
487         }
488
489         //repro for #505375
490         [Category ("!FULLAOT")]
491         public static int test_2_cprop_bug () {
492                 int idx = 0;
493                 int a = 1;
494                 var cmp = System.Collections.Generic.Comparer<int>.Default ;
495                 if (cmp.Compare (a, 0) > 0)
496                         a = 0;
497                 do { idx++; } while (cmp.Compare (idx - 1, a) == 0);
498                 return idx;
499         }
500
501         enum MyEnumUlong : ulong {
502                 Value_2 = 2
503         }
504
505         public static int test_0_regress_550964_constrained_enum_long () {
506         MyEnumUlong a = MyEnumUlong.Value_2;
507         MyEnumUlong b = MyEnumUlong.Value_2;
508
509         return Pan (a, b) ? 0 : 1;
510         }
511
512     static bool Pan<T> (T a, T b)
513     {
514         return a.Equals (b);
515     }
516
517         public class XElement {
518                 public string Value {
519                         get; set;
520                 }
521         }
522
523         public static int test_0_fullaot_linq () {
524                 var allWords = new XElement [] { new XElement { Value = "one" } };
525                 var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T"));
526                 return filteredWords.Count ();
527         }
528
529         public static int test_0_fullaot_comparer_t () {
530                 var l = new SortedList <TimeSpan, int> ();
531                 return l.Count;
532         }
533
534         public static int test_0_fullaot_comparer_t_2 () {
535                 var l = new Dictionary <TimeSpan, int> ();
536                 return l.Count;
537         }
538
539         static void enumerate<T> (IEnumerable<T> arr) {
540                 foreach (var o in arr)
541                         ;
542                 int c = ((ICollection<T>)arr).Count;
543         }
544
545         /* Test that treating arrays as generic collections works with full-aot */
546         public static int test_0_fullaot_array_wrappers () {
547                 Tests[] arr = new Tests [10];
548                 enumerate<Tests> (arr);
549                 return 0;
550         }
551
552         static int cctor_count = 0;
553
554     public abstract class Beta<TChanged> 
555     {           
556         static Beta()
557         {
558                         cctor_count ++;
559         }
560     }   
561     
562     public class Gamma<T> : Beta<T> 
563     {   
564         static Gamma()
565         {
566         }
567     }
568
569         // #519336    
570         public static int test_2_generic_class_init_gshared_ctor () {
571                 new Gamma<object>();
572                 new Gamma<string>();
573
574                 return cctor_count;
575         }
576
577         static int cctor_count2 = 0;
578
579         class ServiceController<T> {
580                 static ServiceController () {
581                         cctor_count2 ++;
582                 }
583
584                 public ServiceController () {
585                 }
586         }
587
588         static ServiceController<T> Create<T>() {
589                 return new ServiceController<T>();
590         }
591
592         // #631409
593         public static int test_2_generic_class_init_gshared_ctor_from_gshared () {
594                 Create<object> ();
595                 Create<string> ();
596
597                 return cctor_count2;
598         }
599
600         public static Type get_type<T> () {
601                 return typeof (T);
602         }
603
604         public static int test_0_gshared_delegate_rgctx () {
605                 Func<Type> t = new Func<Type> (get_type<string>);
606
607                 if (t () == typeof (string))
608                         return 0;
609                 else
610                         return 1;
611         }
612
613         // Creating a delegate from a generic method from gshared code
614         public static int test_0_gshared_delegate_from_gshared () {
615                 if (gshared_delegate_from_gshared <object> () != 0)
616                         return 1;
617                 if (gshared_delegate_from_gshared <string> () != 0)
618                         return 2;
619                 return 0;
620         }
621
622         public static int gshared_delegate_from_gshared <T> () {
623                 Func<Type> t = new Func<Type> (get_type<T>);
624
625                 return t () == typeof (T) ? 0 : 1;
626         }
627
628         public static int test_0_marshalbyref_call_from_gshared_virt_elim () {
629                 /* Calling a virtual method from gshared code which is changed to a nonvirt call */
630                 Class1<object> o = new Class1<object> ();
631                 o.Do (new Class2<object> ());
632                 return 0;
633         }
634
635         class Pair<TKey, TValue> {
636                 public static KeyValuePair<TKey, TValue> make_pair (TKey key, TValue value)
637                         {
638                                 return new KeyValuePair<TKey, TValue> (key, value);
639                         }
640
641                 public delegate TRet Transform<TRet> (TKey key, TValue value);
642         }
643
644         public static int test_0_bug_620864 () {
645                 var d = new Pair<string, Type>.Transform<KeyValuePair<string, Type>> (Pair<string, Type>.make_pair);
646
647                 var p = d ("FOO", typeof (int));
648                 if (p.Key != "FOO" || p.Value != typeof (int))
649                         return 1;
650
651                 return 0;
652         }
653
654
655         struct RecStruct<T> {
656                 public void foo (RecStruct<RecStruct<T>> baz) {
657                 }
658         }
659
660         public static int test_0_infinite_generic_recursion () {
661                 // Check that the AOT compile can deal with infinite generic recursion through
662                 // parameter types
663                 RecStruct<int> bla;
664
665                 return 0;
666         }
667
668         struct FooStruct {
669         }
670
671         bool IsNull2 <T> (object value) where T : struct {
672                 T? item = (T?) value;
673
674                 if (item.HasValue)
675                         return false;
676
677                 return true;
678         }
679
680         public static int test_0_full_aot_nullable_unbox_from_gshared_code () {
681                 if (!new Tests ().IsNull2<FooStruct> (null))
682                         return 1;
683                 if (new Tests ().IsNull2<FooStruct> (new FooStruct ()))
684                         return 2;
685                 return 0;
686         }
687
688         public static int test_0_partial_sharing () {
689                 if (PartialShared1 (new List<string> (), 1) != typeof (string))
690                         return 1;
691                 if (PartialShared1 (new List<Tests> (), 1) != typeof (Tests))
692                         return 2;
693                 if (PartialShared2 (new List<string> (), 1) != typeof (int))
694                         return 3;
695                 if (PartialShared2 (new List<Tests> (), 1) != typeof (int))
696                         return 4;
697                 return 0;
698         }
699
700         public static int test_6_partial_sharing_linq () {
701                 var messages = new List<Message> ();
702
703                 messages.Add (new Message () { MessageID = 5 });
704                 messages.Add (new Message () { MessageID = 6 });
705
706                 return messages.Max(i => i.MessageID);
707         }
708
709         public static int test_0_partial_shared_method_in_nonshared_class () {
710                 var c = new Class1<double> ();
711                 return (c.Foo<string> (5).GetType () == typeof (Class1<string>)) ? 0 : 1;
712         }
713
714         class Message {
715                 public int MessageID {
716                         get; set;
717                 }
718         }
719
720         public static Type PartialShared1<T, K> (List<T> list, K k) {
721                 return typeof (T);
722         }
723
724         public static Type PartialShared2<T, K> (List<T> list, K k) {
725                 return typeof (K);
726         }
727
728     public class Class1<T> {
729                 public virtual void Do (Class2<T> t) {
730                         t.Foo ();
731                 }
732
733                 public virtual object Foo<U> (T t) {
734                         return new Class1<U> ();
735                 }
736         }
737
738         public interface IFace1<T> {
739                 void Foo ();
740         }
741
742         public class Class2<T> : MarshalByRefObject, IFace1<T> {
743                 public void Foo () {
744                 }
745         }
746
747
748
749         public static void VirtualInterfaceCallFromGenericMethod <T> (IFoo f) {
750                 f.Bar <T> ();
751         }
752
753         public static Type the_type;
754
755         public void ldvirtftn<T> () {
756                 Foo <T> binding = new Foo <T> (default (T));
757
758                 binding.GenericEvent += event_handler;
759                 binding.fire ();
760         }
761
762         public virtual void event_handler<T> (Foo<T> sender) {
763                 the_type = typeof (T);
764         }
765
766         public interface IFoo {
767                 void NonGeneric ();
768                 object Bar<T>();
769         }
770
771         public class Foo<T1> : IFoo
772         {
773                 public Foo(T1 t1)
774                 {
775                         m_t1 = t1;
776                 }
777                 
778                 public override string ToString()
779                 {
780                         return Bar(m_t1 == null ? "null" : "null");
781                 }
782
783                 public String Bar (String s) {
784                         return s;
785                 }
786
787                 public int this [T1 key] {
788                         set {
789                                 if (key == null)
790                                         throw new ArgumentNullException ("key");
791                         }
792                 }
793
794                 public void throw_dead_this () {
795                         try {
796                                 new SomeClass().ThrowAnException();
797                         }
798                         catch {
799                         }
800                 }
801
802                 public T1 get_default () {
803                         return default (T1);
804                 }
805                 
806                 readonly T1 m_t1;
807
808                 public delegate void GenericEventHandler (Foo<T1> sender);
809
810                 public event GenericEventHandler GenericEvent;
811
812                 public void fire () {
813                         GenericEvent (this);
814                 }
815
816                 public static int count1, count2, count3, count4;
817
818                 public void NonGeneric () {
819                         count3 ++;
820                 }
821
822                 public object Bar <T> () {
823                         if (typeof (T) == typeof (int))
824                                 count1 ++;
825                         else if (typeof (T) == typeof (string))
826                                 count2 ++;
827                         else if (typeof (T) == typeof (object))
828                                 count4 ++;
829                         return null;
830                 }
831         }
832
833         public class SomeClass {
834                 public void ThrowAnException() {
835                         throw new Exception ("Something went wrong");
836                 }
837         }               
838
839         struct Handler : IFoo {
840                 object o;
841
842                 public Handler(object o) {
843                         this.o = o;
844                 }
845
846                 public void NonGeneric () {
847                 }
848
849                 public object Bar<T>() {
850                         return o;
851                 }
852         }
853
854         static bool IsNull<T> (T t)
855         {
856                 if (t == null)
857                         return true;
858                 else
859                         return false;
860         }
861
862         static object Box<T> (T t)
863         {
864                 return t;
865         }
866         
867         static T Unbox <T> (object o) {
868                 return (T) o;
869         }
870
871         interface IDefaultRetriever
872         {
873                 T GetDefault<T>();
874         }
875
876         class DefaultRetriever : IDefaultRetriever
877         {
878                 [MethodImpl(MethodImplOptions.Synchronized)]
879                 public T GetDefault<T>()
880                 {
881                         return default(T);
882                 }
883         }
884
885         [Category ("!FULLAOT")]
886         public static int test_0_regress_668095_synchronized_gshared () {
887                 return DoSomething (new DefaultRetriever ());
888         }
889
890     static int DoSomething(IDefaultRetriever foo) {
891                 int result = foo.GetDefault<int>();
892                 return result;
893         }
894
895         class Response {
896         }
897
898         public static int test_0_687865_isinst_with_cache_wrapper () {
899                 object o = new object ();
900                 if (o is Action<IEnumerable<Response>>)
901                         return 1;
902                 else
903                         return 0;
904         }
905
906         enum DocType {
907                 One,
908                 Two,
909                 Three
910         }
911
912         class Doc {
913                 public string Name {
914                         get; set;
915                 }
916
917                 public DocType Type {
918                         get; set;
919                 }
920         }
921
922         // #2155
923         public static int test_0_fullaot_sflda_cctor () {
924                 List<Doc> documents = new List<Doc>();
925                 documents.Add(new Doc { Name = "Doc1", Type = DocType.One } );
926                 documents.Add(new Doc { Name = "Doc2", Type = DocType.Two } );
927                 documents.Add(new Doc { Name = "Doc3", Type = DocType.Three } );
928                 documents.Add(new Doc { Name = "Doc4", Type = DocType.One } );
929                 documents.Add(new Doc { Name = "Doc5", Type = DocType.Two } );
930                 documents.Add(new Doc { Name = "Doc6", Type = DocType.Three } );
931                 documents.Add(new Doc { Name = "Doc7", Type = DocType.One } );
932                 documents.Add(new Doc { Name = "Doc8", Type = DocType.Two } );
933                 documents.Add(new Doc { Name = "Doc9", Type = DocType.Three } );
934
935                 List<DocType> categories = documents.Select(d=>d.Type).Distinct().ToList<DocType>().OrderBy(d => d).ToList();
936                 foreach(DocType cat in categories) {
937                         List<Doc> catDocs = documents.Where(d => d.Type == cat).OrderBy(d => d.Name).ToList<Doc>();
938                 }
939                 return 0;
940         }
941
942         class A { }
943
944     static List<A> sources = new List<A>();
945
946         // #6112
947     public static int test_0_fullaot_imt () {
948         sources.Add(null);
949         sources.Add(null);
950
951         int a = sources.Count;
952         var enumerator = sources.GetEnumerator() as IEnumerator<object>;
953
954         while (enumerator.MoveNext())
955         {
956             object o = enumerator.Current;
957         }
958
959                 return 0;
960         }
961
962         struct Record : Foo2<Record>.IRecord {
963                 int counter;
964                 int Foo2<Record>.IRecord.DoSomething () {
965                         return counter++;
966                 }
967         }
968
969         class Foo2<T> where T : Foo2<T>.IRecord {
970                 public interface IRecord {
971                         int DoSomething ();
972                 }
973
974                 public static int Extract (T[] t) {
975                         return t[0].DoSomething ();
976                 }
977         }
978
979         class Foo3<T> where T : IComparable {
980                 public static int CompareTo (T[] t) {
981                         // This is a constrained call to Enum.CompareTo ()
982                         return t[0].CompareTo (t [0]);
983                 }
984         }
985
986         public static int test_1_regress_constrained_iface_call_7571 () {
987         var r = new Record [10];
988         Foo2<Record>.Extract (r);
989                 return Foo2<Record>.Extract (r);
990         }
991
992         enum ConstrainedEnum {
993                 Val = 1
994         }
995
996         public static int test_0_regress_constrained_iface_call_enum () {
997                 var r = new ConstrainedEnum [10];
998                 return Foo3<ConstrainedEnum>.CompareTo (r);
999         }
1000
1001         public interface IFoo2 {
1002                 void MoveNext ();
1003         }
1004
1005         public struct Foo2 : IFoo2 {
1006                 public void MoveNext () {
1007                 }
1008         }
1009
1010         public static Action Dingus (ref Foo2 f) {
1011                 return new Action (f.MoveNext);
1012         }
1013
1014         public static int test_0_delegate_unbox_full_aot () {
1015                 Foo2 foo = new Foo2 ();
1016                 Dingus (ref foo) ();
1017                 return 0;
1018         }
1019
1020         public static int test_0_arrays_ireadonly () {
1021                 int[] arr = new int [10];
1022                 for (int i = 0; i < 10; ++i)
1023                         arr [i] = i;
1024                 IReadOnlyList<int> a = (IReadOnlyList<int>)(object)arr;
1025                 if (a.Count != 10)
1026                         return 1;
1027                 if (a [0] != 0)
1028                         return 2;
1029                 if (a [1] != 1)
1030                         return 3;
1031                 return 0;
1032         }
1033
1034         public static int test_0_volatile_read_write () {
1035                 string foo = "ABC";
1036                 Volatile.Write (ref foo, "DEF");
1037                 return Volatile.Read (ref foo) == "DEF" ? 0 : 1;
1038         }
1039
1040         // FIXME: Doesn't work with --regression as Interlocked.Add(ref long) is only implemented as an intrinsic
1041 #if FALSE
1042         public static async Task<T> FooAsync<T> (int i, int j) {
1043                 Task<int> t = new Task<int> (delegate () { Console.WriteLine ("HIT!"); return 0; });
1044                 var response = await t;
1045                 return default(T);
1046         }
1047
1048         public static int test_0_fullaot_generic_async () {
1049                 Task<string> t = FooAsync<string> (1, 2);
1050                 t.RunSynchronously ();
1051                 return 0;
1052         }
1053 #endif
1054 }