Added tests for Task.WhenAll w/ empty list
[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 static int test_0_ldfld_stfld_mro () {
314                 MRO m = new MRO ();
315                 GenericStruct<int> s = new GenericStruct<int> (5);
316                 // This generates stfld
317                 m.struct_field = s;
318
319                 // This generates ldflda
320                 if (m.struct_field.t != 5)
321                         return 1;
322
323                 // This generates ldfld
324                 GenericStruct<int> s2 = m.struct_field;
325                 if (s2.t != 5)
326                         return 2;
327
328                 if (m.struct_field.t != 5)
329                         return 3;
330
331                 m.class_field = new GenericClass<int> (5);
332                 if (m.class_field.t != 5)
333                         return 4;
334
335                 return 0;
336         }
337
338         // FIXME:
339         [Category ("!FULLAOT")]
340     public static int test_0_generic_virtual_call_on_vtype_unbox () {
341                 object o = new Object ();
342         IFoo h = new Handler(o);
343
344         if (h.Bar<object> () != o)
345                         return 1;
346                 else
347                         return 0;
348     }
349
350         public static int test_0_box_brtrue_opt () {
351                 Foo<int> f = new Foo<int> (5);
352
353                 f [123] = 5;
354
355                 return 0;
356         }
357
358         public static int test_0_box_brtrue_opt_regress_81102 () {
359                 if (new Foo<int>(5).ToString () == "null")
360                         return 0;
361                 else
362                         return 1;
363         }
364
365         struct S {
366                 public int i;
367         }
368
369         public static int test_0_ldloca_initobj_opt () {
370                 if (new Foo<S> (new S ()).get_default ().i != 0)
371                         return 1;
372                 if (new Foo<object> (null).get_default () != null)
373                         return 2;
374                 return 0;
375         }
376
377         public static int test_0_variance_reflection () {
378                 // covariance on IEnumerator
379                 if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (MyIEnumerator<string>)))
380                         return 1;
381                 // covariance on IEnumerator and covariance on arrays
382                 if (!typeof (MyIEnumerator<object>[]).IsAssignableFrom (typeof (MyIEnumerator<string>[])))
383                         return 2;
384                 // covariance and implemented interfaces
385                 if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (Enumerator<string>)))
386                         return 3;
387
388                 // contravariance on IComparer
389                 if (!typeof (IComparer<string>).IsAssignableFrom (typeof (IComparer<object>)))
390                         return 4;
391                 // contravariance on IComparer, contravariance on arrays
392                 if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IComparer<object>[])))
393                         return 5;
394                 // contravariance and interface inheritance
395                 if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IKeyComparer<object>[])))
396                         return 6;
397                 return 0;
398         }
399
400         public static int test_0_ldvirtftn_generic_method () {
401                 new Tests ().ldvirtftn<string> ();              
402
403                 return the_type == typeof (string) ? 0 : 1;
404         }
405
406         public static int test_0_throw_dead_this () {
407         new Foo<string> ("").throw_dead_this ();
408                 return 0;
409         }
410
411         struct S<T> {}
412
413         public static int test_0_inline_infinite_polymorphic_recursion () {
414            f<int>(0);
415
416                    return 0;
417         }
418
419         private static void f<T>(int i) {
420                 if(i==42) f<S<T>>(i);
421         }
422
423         // This cannot be made to work with full-aot, since there it is impossible to
424         // statically determine that Foo<string>.Bar <int> is needed, the code only
425         // references IFoo.Bar<int>
426         [Category ("!FULLAOT")]
427         public static int test_0_generic_virtual_on_interfaces () {
428                 Foo<string>.count1 = 0;
429                 Foo<string>.count2 = 0;
430                 Foo<string>.count3 = 0;
431
432                 IFoo f = new Foo<string> ("");
433                 for (int i = 0; i < 1000; ++i) {
434                         f.Bar <int> ();
435                         f.Bar <string> ();
436                         f.NonGeneric ();
437                 }
438
439                 if (Foo<string>.count1 != 1000)
440                         return 1;
441                 if (Foo<string>.count2 != 1000)
442                         return 2;
443                 if (Foo<string>.count3 != 1000)
444                         return 3;
445
446                 VirtualInterfaceCallFromGenericMethod<long> (f);
447
448                 return 0;
449         }
450
451         public static int test_0_generic_virtual_on_interfaces_ref () {
452                 Foo<string>.count1 = 0;
453                 Foo<string>.count2 = 0;
454                 Foo<string>.count3 = 0;
455                 Foo<string>.count4 = 0;
456
457                 IFoo f = new Foo<string> ("");
458                 for (int i = 0; i < 1000; ++i) {
459                         f.Bar <string> ();
460                         f.Bar <object> ();
461                         f.NonGeneric ();
462                 }
463
464                 if (Foo<string>.count2 != 1000)
465                         return 2;
466                 if (Foo<string>.count3 != 1000)
467                         return 3;
468                 if (Foo<string>.count4 != 1000)
469                         return 4;
470
471                 return 0;
472         }
473
474         //repro for #505375
475         [Category ("!FULLAOT")]
476         public static int test_2_cprop_bug () {
477                 int idx = 0;
478                 int a = 1;
479                 var cmp = System.Collections.Generic.Comparer<int>.Default ;
480                 if (cmp.Compare (a, 0) > 0)
481                         a = 0;
482                 do { idx++; } while (cmp.Compare (idx - 1, a) == 0);
483                 return idx;
484         }
485
486         enum MyEnumUlong : ulong {
487                 Value_2 = 2
488         }
489
490         public static int test_0_regress_550964_constrained_enum_long () {
491         MyEnumUlong a = MyEnumUlong.Value_2;
492         MyEnumUlong b = MyEnumUlong.Value_2;
493
494         return Pan (a, b) ? 0 : 1;
495         }
496
497     static bool Pan<T> (T a, T b)
498     {
499         return a.Equals (b);
500     }
501
502         public class XElement {
503                 public string Value {
504                         get; set;
505                 }
506         }
507
508         public static int test_0_fullaot_linq () {
509                 var allWords = new XElement [] { new XElement { Value = "one" } };
510                 var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T"));
511                 return filteredWords.Count ();
512         }
513
514         public static int test_0_fullaot_comparer_t () {
515                 var l = new SortedList <TimeSpan, int> ();
516                 return l.Count;
517         }
518
519         public static int test_0_fullaot_comparer_t_2 () {
520                 var l = new Dictionary <TimeSpan, int> ();
521                 return l.Count;
522         }
523
524         static void enumerate<T> (IEnumerable<T> arr) {
525                 foreach (var o in arr)
526                         ;
527                 int c = ((ICollection<T>)arr).Count;
528         }
529
530         /* Test that treating arrays as generic collections works with full-aot */
531         public static int test_0_fullaot_array_wrappers () {
532                 Tests[] arr = new Tests [10];
533                 enumerate<Tests> (arr);
534                 return 0;
535         }
536
537         static int cctor_count = 0;
538
539     public abstract class Beta<TChanged> 
540     {           
541         static Beta()
542         {
543                         cctor_count ++;
544         }
545     }   
546     
547     public class Gamma<T> : Beta<T> 
548     {   
549         static Gamma()
550         {
551         }
552     }
553
554         // #519336    
555         public static int test_2_generic_class_init_gshared_ctor () {
556                 new Gamma<object>();
557                 new Gamma<string>();
558
559                 return cctor_count;
560         }
561
562         static int cctor_count2 = 0;
563
564         class ServiceController<T> {
565                 static ServiceController () {
566                         cctor_count2 ++;
567                 }
568
569                 public ServiceController () {
570                 }
571         }
572
573         static ServiceController<T> Create<T>() {
574                 return new ServiceController<T>();
575         }
576
577         // #631409
578         public static int test_2_generic_class_init_gshared_ctor_from_gshared () {
579                 Create<object> ();
580                 Create<string> ();
581
582                 return cctor_count2;
583         }
584
585         public static Type get_type<T> () {
586                 return typeof (T);
587         }
588
589         public static int test_0_gshared_delegate_rgctx () {
590                 Func<Type> t = new Func<Type> (get_type<string>);
591
592                 if (t () == typeof (string))
593                         return 0;
594                 else
595                         return 1;
596         }
597
598         // Creating a delegate from a generic method from gshared code
599         public static int test_0_gshared_delegate_from_gshared () {
600                 if (gshared_delegate_from_gshared <object> () != 0)
601                         return 1;
602                 if (gshared_delegate_from_gshared <string> () != 0)
603                         return 2;
604                 return 0;
605         }
606
607         public static int gshared_delegate_from_gshared <T> () {
608                 Func<Type> t = new Func<Type> (get_type<T>);
609
610                 return t () == typeof (T) ? 0 : 1;
611         }
612
613         public static int test_0_marshalbyref_call_from_gshared_virt_elim () {
614                 /* Calling a virtual method from gshared code which is changed to a nonvirt call */
615                 Class1<object> o = new Class1<object> ();
616                 o.Do (new Class2<object> ());
617                 return 0;
618         }
619
620         class Pair<TKey, TValue> {
621                 public static KeyValuePair<TKey, TValue> make_pair (TKey key, TValue value)
622                         {
623                                 return new KeyValuePair<TKey, TValue> (key, value);
624                         }
625
626                 public delegate TRet Transform<TRet> (TKey key, TValue value);
627         }
628
629         public static int test_0_bug_620864 () {
630                 var d = new Pair<string, Type>.Transform<KeyValuePair<string, Type>> (Pair<string, Type>.make_pair);
631
632                 var p = d ("FOO", typeof (int));
633                 if (p.Key != "FOO" || p.Value != typeof (int))
634                         return 1;
635
636                 return 0;
637         }
638
639
640         struct RecStruct<T> {
641                 public void foo (RecStruct<RecStruct<T>> baz) {
642                 }
643         }
644
645         public static int test_0_infinite_generic_recursion () {
646                 // Check that the AOT compile can deal with infinite generic recursion through
647                 // parameter types
648                 RecStruct<int> bla;
649
650                 return 0;
651         }
652
653         struct FooStruct {
654         }
655
656         bool IsNull2 <T> (object value) where T : struct {
657                 T? item = (T?) value;
658
659                 if (item.HasValue)
660                         return false;
661
662                 return true;
663         }
664
665         public static int test_0_full_aot_nullable_unbox_from_gshared_code () {
666                 if (!new Tests ().IsNull2<FooStruct> (null))
667                         return 1;
668                 if (new Tests ().IsNull2<FooStruct> (new FooStruct ()))
669                         return 2;
670                 return 0;
671         }
672
673         public static int test_0_partial_sharing () {
674                 if (PartialShared1 (new List<string> (), 1) != typeof (string))
675                         return 1;
676                 if (PartialShared1 (new List<Tests> (), 1) != typeof (Tests))
677                         return 2;
678                 if (PartialShared2 (new List<string> (), 1) != typeof (int))
679                         return 3;
680                 if (PartialShared2 (new List<Tests> (), 1) != typeof (int))
681                         return 4;
682                 return 0;
683         }
684
685         public static int test_6_partial_sharing_linq () {
686                 var messages = new List<Message> ();
687
688                 messages.Add (new Message () { MessageID = 5 });
689                 messages.Add (new Message () { MessageID = 6 });
690
691                 return messages.Max(i => i.MessageID);
692         }
693
694         public static int test_0_partial_shared_method_in_nonshared_class () {
695                 var c = new Class1<double> ();
696                 return (c.Foo<string> (5).GetType () == typeof (Class1<string>)) ? 0 : 1;
697         }
698
699         class Message {
700                 public int MessageID {
701                         get; set;
702                 }
703         }
704
705         public static Type PartialShared1<T, K> (List<T> list, K k) {
706                 return typeof (T);
707         }
708
709         public static Type PartialShared2<T, K> (List<T> list, K k) {
710                 return typeof (K);
711         }
712
713     public class Class1<T> {
714                 public virtual void Do (Class2<T> t) {
715                         t.Foo ();
716                 }
717
718                 public virtual object Foo<U> (T t) {
719                         return new Class1<U> ();
720                 }
721         }
722
723         public interface IFace1<T> {
724                 void Foo ();
725         }
726
727         public class Class2<T> : MarshalByRefObject, IFace1<T> {
728                 public void Foo () {
729                 }
730         }
731
732
733
734         public static void VirtualInterfaceCallFromGenericMethod <T> (IFoo f) {
735                 f.Bar <T> ();
736         }
737
738         public static Type the_type;
739
740         public void ldvirtftn<T> () {
741                 Foo <T> binding = new Foo <T> (default (T));
742
743                 binding.GenericEvent += event_handler;
744                 binding.fire ();
745         }
746
747         public virtual void event_handler<T> (Foo<T> sender) {
748                 the_type = typeof (T);
749         }
750
751         public interface IFoo {
752                 void NonGeneric ();
753                 object Bar<T>();
754         }
755
756         public class Foo<T1> : IFoo
757         {
758                 public Foo(T1 t1)
759                 {
760                         m_t1 = t1;
761                 }
762                 
763                 public override string ToString()
764                 {
765                         return Bar(m_t1 == null ? "null" : "null");
766                 }
767
768                 public String Bar (String s) {
769                         return s;
770                 }
771
772                 public int this [T1 key] {
773                         set {
774                                 if (key == null)
775                                         throw new ArgumentNullException ("key");
776                         }
777                 }
778
779                 public void throw_dead_this () {
780                         try {
781                                 new SomeClass().ThrowAnException();
782                         }
783                         catch {
784                         }
785                 }
786
787                 public T1 get_default () {
788                         return default (T1);
789                 }
790                 
791                 readonly T1 m_t1;
792
793                 public delegate void GenericEventHandler (Foo<T1> sender);
794
795                 public event GenericEventHandler GenericEvent;
796
797                 public void fire () {
798                         GenericEvent (this);
799                 }
800
801                 public static int count1, count2, count3, count4;
802
803                 public void NonGeneric () {
804                         count3 ++;
805                 }
806
807                 public object Bar <T> () {
808                         if (typeof (T) == typeof (int))
809                                 count1 ++;
810                         else if (typeof (T) == typeof (string))
811                                 count2 ++;
812                         else if (typeof (T) == typeof (object))
813                                 count4 ++;
814                         return null;
815                 }
816         }
817
818         public class SomeClass {
819                 public void ThrowAnException() {
820                         throw new Exception ("Something went wrong");
821                 }
822         }               
823
824         struct Handler : IFoo {
825                 object o;
826
827                 public Handler(object o) {
828                         this.o = o;
829                 }
830
831                 public void NonGeneric () {
832                 }
833
834                 public object Bar<T>() {
835                         return o;
836                 }
837         }
838
839         static bool IsNull<T> (T t)
840         {
841                 if (t == null)
842                         return true;
843                 else
844                         return false;
845         }
846
847         static object Box<T> (T t)
848         {
849                 return t;
850         }
851         
852         static T Unbox <T> (object o) {
853                 return (T) o;
854         }
855
856         interface IDefaultRetriever
857         {
858                 T GetDefault<T>();
859         }
860
861         class DefaultRetriever : IDefaultRetriever
862         {
863                 [MethodImpl(MethodImplOptions.Synchronized)]
864                 public T GetDefault<T>()
865                 {
866                         return default(T);
867                 }
868         }
869
870         [Category ("!FULLAOT")]
871         public static int test_0_regress_668095_synchronized_gshared () {
872                 return DoSomething (new DefaultRetriever ());
873         }
874
875     static int DoSomething(IDefaultRetriever foo) {
876                 int result = foo.GetDefault<int>();
877                 return result;
878         }
879
880         class Response {
881         }
882
883         public static int test_0_687865_isinst_with_cache_wrapper () {
884                 object o = new object ();
885                 if (o is Action<IEnumerable<Response>>)
886                         return 1;
887                 else
888                         return 0;
889         }
890
891         enum DocType {
892                 One,
893                 Two,
894                 Three
895         }
896
897         class Doc {
898                 public string Name {
899                         get; set;
900                 }
901
902                 public DocType Type {
903                         get; set;
904                 }
905         }
906
907         // #2155
908         public static int test_0_fullaot_sflda_cctor () {
909                 List<Doc> documents = new List<Doc>();
910                 documents.Add(new Doc { Name = "Doc1", Type = DocType.One } );
911                 documents.Add(new Doc { Name = "Doc2", Type = DocType.Two } );
912                 documents.Add(new Doc { Name = "Doc3", Type = DocType.Three } );
913                 documents.Add(new Doc { Name = "Doc4", Type = DocType.One } );
914                 documents.Add(new Doc { Name = "Doc5", Type = DocType.Two } );
915                 documents.Add(new Doc { Name = "Doc6", Type = DocType.Three } );
916                 documents.Add(new Doc { Name = "Doc7", Type = DocType.One } );
917                 documents.Add(new Doc { Name = "Doc8", Type = DocType.Two } );
918                 documents.Add(new Doc { Name = "Doc9", Type = DocType.Three } );
919
920                 List<DocType> categories = documents.Select(d=>d.Type).Distinct().ToList<DocType>().OrderBy(d => d).ToList();
921                 foreach(DocType cat in categories) {
922                         List<Doc> catDocs = documents.Where(d => d.Type == cat).OrderBy(d => d.Name).ToList<Doc>();
923                 }
924                 return 0;
925         }
926
927         class A { }
928
929     static List<A> sources = new List<A>();
930
931         // #6112
932     public static int test_0_fullaot_imt () {
933         sources.Add(null);
934         sources.Add(null);
935
936         int a = sources.Count;
937         var enumerator = sources.GetEnumerator() as IEnumerator<object>;
938
939         while (enumerator.MoveNext())
940         {
941             object o = enumerator.Current;
942         }
943
944                 return 0;
945         }
946
947         struct Record : Foo2<Record>.IRecord {
948                 int counter;
949                 int Foo2<Record>.IRecord.DoSomething () {
950                         return counter++;
951                 }
952         }
953
954         class Foo2<T> where T : Foo2<T>.IRecord {
955                 public interface IRecord {
956                         int DoSomething ();
957                 }
958
959                 public static int Extract (T[] t) {
960                         return t[0].DoSomething ();
961                 }
962         }
963
964         class Foo3<T> where T : IComparable {
965                 public static int CompareTo (T[] t) {
966                         // This is a constrained call to Enum.CompareTo ()
967                         return t[0].CompareTo (t [0]);
968                 }
969         }
970
971         public static int test_1_regress_constrained_iface_call_7571 () {
972         var r = new Record [10];
973         Foo2<Record>.Extract (r);
974                 return Foo2<Record>.Extract (r);
975         }
976
977         enum ConstrainedEnum {
978                 Val = 1
979         }
980
981         public static int test_0_regress_constrained_iface_call_enum () {
982                 var r = new ConstrainedEnum [10];
983                 return Foo3<ConstrainedEnum>.CompareTo (r);
984         }
985
986         public interface IFoo2 {
987                 void MoveNext ();
988         }
989
990         public struct Foo2 : IFoo2 {
991                 public void MoveNext () {
992                 }
993         }
994
995         public static Action Dingus (ref Foo2 f) {
996                 return new Action (f.MoveNext);
997         }
998
999         public static int test_0_delegate_unbox_full_aot () {
1000                 Foo2 foo = new Foo2 ();
1001                 Dingus (ref foo) ();
1002                 return 0;
1003         }
1004
1005         public static int test_0_arrays_ireadonly () {
1006                 int[] arr = new int [10];
1007                 for (int i = 0; i < 10; ++i)
1008                         arr [i] = i;
1009                 IReadOnlyList<int> a = (IReadOnlyList<int>)(object)arr;
1010                 if (a.Count != 10)
1011                         return 1;
1012                 if (a [0] != 0)
1013                         return 2;
1014                 if (a [1] != 1)
1015                         return 3;
1016                 return 0;
1017         }
1018
1019         public static int test_0_volatile_read_write () {
1020                 string foo = "ABC";
1021                 Volatile.Write (ref foo, "DEF");
1022                 return Volatile.Read (ref foo) == "DEF" ? 0 : 1;
1023         }
1024
1025         // FIXME: Doesn't work with --regression as Interlocked.Add(ref long) is only implemented as an intrinsic
1026 #if FALSE
1027         public static async Task<T> FooAsync<T> (int i, int j) {
1028                 Task<int> t = new Task<int> (delegate () { Console.WriteLine ("HIT!"); return 0; });
1029                 var response = await t;
1030                 return default(T);
1031         }
1032
1033         public static int test_0_fullaot_generic_async () {
1034                 Task<string> t = FooAsync<string> (1, 2);
1035                 t.RunSynchronously ();
1036                 return 0;
1037         }
1038 #endif
1039 }