using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; #if __MOBILE__ class GenericsTests #else class Tests #endif { struct TestStruct { public int i; public int j; public TestStruct (int i, int j) { this.i = i; this.j = j; } } #if !__MOBILE__ class Enumerator : MyIEnumerator { T MyIEnumerator.Current { get { return default(T); } } bool MyIEnumerator.MoveNext () { return true; } } class Comparer : IComparer { bool IComparer.Compare (T x, T y) { return true; } } #endif #if !__MOBILE__ static int Main (string[] args) { return TestDriver.RunTests (typeof (Tests), args); } #endif public static int test_1_nullable_unbox () { return Unbox (1).Value; } public static int test_1_nullable_unbox_null () { return Unbox (null).HasValue ? 0 : 1; } public static int test_1_nullable_box () { return (int) Box (1); } public static int test_1_nullable_box_null () { return Box (null) == null ? 1 : 0; } public static int test_1_isinst_nullable () { object o = 1; return (o is int?) ? 1 : 0; } public static int test_1_nullable_unbox_vtype () { return Unbox (new TestStruct (1, 2)).Value.i; } public static int test_1_nullable_unbox_null_vtype () { return Unbox (null).HasValue ? 0 : 1; } public static int test_1_nullable_box_vtype () { return ((TestStruct)(Box (new TestStruct (1, 2)))).i; } public static int test_1_nullable_box_null_vtype () { return Box (null) == null ? 1 : 0; } public static int test_1_isinst_nullable_vtype () { object o = new TestStruct (1, 2); return (o is TestStruct?) ? 1 : 0; } public static int test_0_nullable_normal_unbox () { int? i = 5; object o = i; // This uses unbox instead of unbox_any int? j = (int?)o; if (j != 5) return 1; return 0; } public static void stelem_any (T[] arr, T elem) { arr [0] = elem; } public static T ldelem_any (T[] arr) { return arr [0]; } public static int test_1_ldelem_stelem_any_int () { int[] arr = new int [3]; stelem_any (arr, 1); return ldelem_any (arr); } public static T return_ref (ref T t) { return t; } public static T ldelema_any (T[] arr) { return return_ref (ref arr [0]); } public static int test_0_ldelema () { string[] arr = new string [1]; arr [0] = "Hello"; if (ldelema_any (arr) == "Hello") return 0; else return 1; } public static T[,] newarr_multi () { return new T [1, 1]; } public static int test_0_newarr_multi_dim () { return newarr_multi ().GetType () == typeof (string[,]) ? 0 : 1; } interface ITest { void Foo (); } public static int test_0_iface_call_null_bug_77442 () { ITest test = null; try { test.Foo (); } catch (NullReferenceException) { return 0; } return 1; } public static int test_18_ldobj_stobj_generics () { GenericClass t = new GenericClass (); int i = 5; int j = 6; return t.ldobj_stobj (ref i, ref j) + i + j; } public static int test_5_ldelem_stelem_generics () { GenericClass t = new GenericClass (); TestStruct s = new TestStruct (5, 5); return t.ldelem_stelem (s).i; } public static int test_0_constrained_vtype_box () { GenericClass t = new GenericClass (); #if __MOBILE__ return t.toString (new TestStruct ()) == "GenericsTests+TestStruct" ? 0 : 1; #else return t.toString (new TestStruct ()) == "Tests+TestStruct" ? 0 : 1; #endif } public static int test_0_constrained_vtype () { GenericClass t = new GenericClass (); return t.toString (1234) == "1234" ? 0 : 1; } public static int test_0_constrained_reftype () { GenericClass t = new GenericClass (); return t.toString ("1234") == "1234" ? 0 : 1; } public static int test_0_box_brtrue_optimizations () { if (IsNull(5)) return 1; if (!IsNull(null)) return 1; return 0; } [Category ("!FULLAOT")] public static int test_0_generic_get_value_optimization_int () { int[] x = new int[] {100, 200}; if (GenericClass.Z (x, 0) != 100) return 2; if (GenericClass.Z (x, 1) != 200) return 3; return 0; } interface NonGenericInterface { int return_field (); } interface GenericInterface : NonGenericInterface { T not_used (); } struct ImplementGenericInterface : GenericInterface { public Object padding1; public Object padding2; public Object padding3; public T[] arr_t; public ImplementGenericInterface (T[] arr_t) { this.padding1 = null; this.padding2 = null; this.padding3 = null; this.arr_t = arr_t; } public T not_used () { return arr_t [0]; } public int return_field () { return arr_t.Length; } } public static int test_8_struct_implements_generic_interface () { int[] arr = {1, 2, 3, 4}; NonGenericInterface s = new ImplementGenericInterface (arr); return s.return_field () + s.return_field (); } public static int test_0_generic_get_value_optimization_vtype () { TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) }; IEnumerator enumerator = GenericClass.Y (arr); TestStruct s; int sum = 0; while (enumerator.MoveNext ()) { s = enumerator.Current; sum += s.i + s.j; } if (sum != 1000) return 1; s = GenericClass.Z (arr, 0); if (s.i != 100 || s.j != 200) return 2; s = GenericClass.Z (arr, 1); if (s.i != 300 || s.j != 400) return 3; return 0; } public static int test_0_nullable_ldflda () { return GenericClass.BIsAClazz == false ? 0 : 1; } public struct GenericStruct { public T t; public GenericStruct (T t) { this.t = t; } } public class GenericClass { public T t; public GenericClass (T t) { this.t = t; } public GenericClass () { } public T ldobj_stobj (ref T t1, ref T t2) { t1 = t2; T t = t1; return t; } public T ldelem_stelem (T t) { T[] arr = new T [10]; arr [0] = t; return arr [0]; } public String toString (T t) { return t.ToString (); } public static IEnumerator Y (IEnumerable x) { return x.GetEnumerator (); } public static T Z (IList x, int index) { return x [index]; } protected static T NullB = default(T); private static Nullable _BIsA = null; public static bool BIsAClazz { get { _BIsA = false; return _BIsA.Value; } } } public class MRO : MarshalByRefObject { public GenericStruct struct_field; public GenericClass class_field; } public class MRO : MarshalByRefObject { public T gen_field; public T stfld_ldfld (T t) { var m = this; m.gen_field = t; return m.gen_field; } } public static int test_0_ldfld_stfld_mro () { MRO m = new MRO (); GenericStruct s = new GenericStruct (5); // This generates stfld m.struct_field = s; // This generates ldflda if (m.struct_field.t != 5) return 1; // This generates ldfld GenericStruct s2 = m.struct_field; if (s2.t != 5) return 2; if (m.struct_field.t != 5) return 3; m.class_field = new GenericClass (5); if (m.class_field.t != 5) return 4; // gshared var m2 = new MRO (); if (m2.stfld_ldfld ("A") != "A") return 5; return 0; } // FIXME: [Category ("!FULLAOT")] public static int test_0_generic_virtual_call_on_vtype_unbox () { object o = new Object (); IFoo h = new Handler(o); if (h.Bar () != o) return 1; else return 0; } public static int test_0_box_brtrue_opt () { Foo f = new Foo (5); f [123] = 5; return 0; } public static int test_0_box_brtrue_opt_regress_81102 () { if (new Foo(5).ToString () == "null") return 0; else return 1; } struct S { public int i; } public static int test_0_ldloca_initobj_opt () { if (new Foo (new S ()).get_default ().i != 0) return 1; if (new Foo (null).get_default () != null) return 2; return 0; } #if !__MOBILE__ public static int test_0_variance_reflection () { // covariance on IEnumerator if (!typeof (MyIEnumerator).IsAssignableFrom (typeof (MyIEnumerator))) return 1; // covariance on IEnumerator and covariance on arrays if (!typeof (MyIEnumerator[]).IsAssignableFrom (typeof (MyIEnumerator[]))) return 2; // covariance and implemented interfaces if (!typeof (MyIEnumerator).IsAssignableFrom (typeof (Enumerator))) return 3; // contravariance on IComparer if (!typeof (IComparer).IsAssignableFrom (typeof (IComparer))) return 4; // contravariance on IComparer, contravariance on arrays if (!typeof (IComparer[]).IsAssignableFrom (typeof (IComparer[]))) return 5; // contravariance and interface inheritance if (!typeof (IComparer[]).IsAssignableFrom (typeof (IKeyComparer[]))) return 6; return 0; } #endif public static int test_0_ldvirtftn_generic_method () { new GenericsTests ().ldvirtftn (); return the_type == typeof (string) ? 0 : 1; } public static int test_0_throw_dead_this () { new Foo ("").throw_dead_this (); return 0; } struct S {} public static int test_0_inline_infinite_polymorphic_recursion () { f(0); return 0; } private static void f(int i) { if(i==42) f>(i); } // This cannot be made to work with full-aot, since there it is impossible to // statically determine that Foo.Bar is needed, the code only // references IFoo.Bar [Category ("!FULLAOT")] public static int test_0_generic_virtual_on_interfaces () { Foo.count1 = 0; Foo.count2 = 0; Foo.count3 = 0; IFoo f = new Foo (""); for (int i = 0; i < 1000; ++i) { f.Bar (); f.Bar (); f.NonGeneric (); } if (Foo.count1 != 1000) return 1; if (Foo.count2 != 1000) return 2; if (Foo.count3 != 1000) return 3; VirtualInterfaceCallFromGenericMethod (f); return 0; } public static int test_0_generic_virtual_on_interfaces_ref () { Foo.count1 = 0; Foo.count2 = 0; Foo.count3 = 0; Foo.count4 = 0; IFoo f = new Foo (""); for (int i = 0; i < 1000; ++i) { f.Bar (); f.Bar (); f.NonGeneric (); } if (Foo.count2 != 1000) return 2; if (Foo.count3 != 1000) return 3; if (Foo.count4 != 1000) return 4; return 0; } //repro for #505375 [Category ("!FULLAOT")] public static int test_2_cprop_bug () { int idx = 0; int a = 1; var cmp = System.Collections.Generic.Comparer.Default ; if (cmp.Compare (a, 0) > 0) a = 0; do { idx++; } while (cmp.Compare (idx - 1, a) == 0); return idx; } enum MyEnumUlong : ulong { Value_2 = 2 } public static int test_0_regress_550964_constrained_enum_long () { MyEnumUlong a = MyEnumUlong.Value_2; MyEnumUlong b = MyEnumUlong.Value_2; return Pan (a, b) ? 0 : 1; } static bool Pan (T a, T b) { return a.Equals (b); } public class XElement { public string Value { get; set; } } public static int test_0_fullaot_linq () { var allWords = new XElement [] { new XElement { Value = "one" } }; var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T")); return filteredWords.Count (); } public static int test_0_fullaot_comparer_t () { var l = new SortedList (); return l.Count; } public static int test_0_fullaot_comparer_t_2 () { var l = new Dictionary (); return l.Count; } static void enumerate (IEnumerable arr) { foreach (var o in arr) ; int c = ((ICollection)arr).Count; } /* Test that treating arrays as generic collections works with full-aot */ public static int test_0_fullaot_array_wrappers () { GenericsTests[] arr = new GenericsTests [10]; enumerate (arr); return 0; } static int cctor_count = 0; public abstract class Beta { static Beta() { cctor_count ++; } } public class Gamma : Beta { static Gamma() { } } // #519336 public static int test_2_generic_class_init_gshared_ctor () { new Gamma(); new Gamma(); return cctor_count; } static int cctor_count2 = 0; class ServiceController { static ServiceController () { cctor_count2 ++; } public ServiceController () { } } static ServiceController Create() { return new ServiceController(); } // #631409 public static int test_2_generic_class_init_gshared_ctor_from_gshared () { Create (); Create (); return cctor_count2; } public static Type get_type () { return typeof (T); } public static int test_0_gshared_delegate_rgctx () { Func t = new Func (get_type); if (t () == typeof (string)) return 0; else return 1; } // Creating a delegate from a generic method from gshared code public static int test_0_gshared_delegate_from_gshared () { if (gshared_delegate_from_gshared () != 0) return 1; if (gshared_delegate_from_gshared () != 0) return 2; return 0; } public static int gshared_delegate_from_gshared () { Func t = new Func (get_type); return t () == typeof (T) ? 0 : 1; } public static int test_0_marshalbyref_call_from_gshared_virt_elim () { /* Calling a virtual method from gshared code which is changed to a nonvirt call */ Class1 o = new Class1 (); o.Do (new Class2 ()); return 0; } class Pair { public static KeyValuePair make_pair (TKey key, TValue value) { return new KeyValuePair (key, value); } public delegate TRet Transform (TKey key, TValue value); } public static int test_0_bug_620864 () { var d = new Pair.Transform> (Pair.make_pair); var p = d ("FOO", typeof (int)); if (p.Key != "FOO" || p.Value != typeof (int)) return 1; return 0; } struct RecStruct { public void foo (RecStruct> baz) { } } public static int test_0_infinite_generic_recursion () { // Check that the AOT compile can deal with infinite generic recursion through // parameter types RecStruct bla; return 0; } struct FooStruct { } bool IsNull2 (object value) where T : struct { T? item = (T?) value; if (item.HasValue) return false; return true; } public static int test_0_full_aot_nullable_unbox_from_gshared_code () { if (!new GenericsTests ().IsNull2 (null)) return 1; if (new GenericsTests ().IsNull2 (new FooStruct ())) return 2; return 0; } public static int test_0_partial_sharing () { if (PartialShared1 (new List (), 1) != typeof (string)) return 1; if (PartialShared1 (new List (), 1) != typeof (GenericsTests)) return 2; if (PartialShared2 (new List (), 1) != typeof (int)) return 3; if (PartialShared2 (new List (), 1) != typeof (int)) return 4; return 0; } [Category ("GSHAREDVT")] public static int test_6_partial_sharing_linq () { var messages = new List (); messages.Add (new Message () { MessageID = 5 }); messages.Add (new Message () { MessageID = 6 }); return messages.Max(i => i.MessageID); } public static int test_0_partial_shared_method_in_nonshared_class () { var c = new Class1 (); return (c.Foo (5).GetType () == typeof (Class1)) ? 0 : 1; } class Message { public int MessageID { get; set; } } public static Type PartialShared1 (List list, K k) { return typeof (T); } public static Type PartialShared2 (List list, K k) { return typeof (K); } public class Class1 { public virtual void Do (Class2 t) { t.Foo (); } public virtual object Foo (T t) { return new Class1 (); } } public interface IFace1 { void Foo (); } public class Class2 : MarshalByRefObject, IFace1 { public void Foo () { } } public static void VirtualInterfaceCallFromGenericMethod (IFoo f) { f.Bar (); } public static Type the_type; public void ldvirtftn () { Foo binding = new Foo (default (T)); binding.GenericEvent += event_handler; binding.fire (); } public virtual void event_handler (Foo sender) { the_type = typeof (T); } public interface IFoo { void NonGeneric (); object Bar(); } public class Foo : IFoo { public Foo(T1 t1) { m_t1 = t1; } public override string ToString() { return Bar(m_t1 == null ? "null" : "null"); } public String Bar (String s) { return s; } public int this [T1 key] { set { if (key == null) throw new ArgumentNullException ("key"); } } public void throw_dead_this () { try { new SomeClass().ThrowAnException(); } catch { } } public T1 get_default () { return default (T1); } readonly T1 m_t1; public delegate void GenericEventHandler (Foo sender); public event GenericEventHandler GenericEvent; public void fire () { GenericEvent (this); } public static int count1, count2, count3, count4; public void NonGeneric () { count3 ++; } public object Bar () { if (typeof (T) == typeof (int)) count1 ++; else if (typeof (T) == typeof (string)) count2 ++; else if (typeof (T) == typeof (object)) count4 ++; return null; } } public class SomeClass { public void ThrowAnException() { throw new Exception ("Something went wrong"); } } struct Handler : IFoo { object o; public Handler(object o) { this.o = o; } public void NonGeneric () { } public object Bar() { return o; } } static bool IsNull (T t) { if (t == null) return true; else return false; } static object Box (T t) { return t; } static T Unbox (object o) { return (T) o; } interface IDefaultRetriever { T GetDefault(); } class DefaultRetriever : IDefaultRetriever { [MethodImpl(MethodImplOptions.Synchronized)] public T GetDefault() { return default(T); } } [Category ("!FULLAOT")] [Category ("!BITCODE")] public static int test_0_regress_668095_synchronized_gshared () { return DoSomething (new DefaultRetriever ()); } static int DoSomething(IDefaultRetriever foo) { int result = foo.GetDefault(); return result; } class SyncClass { [MethodImpl(MethodImplOptions.Synchronized)] public Type getInstance() { return typeof (T); } } [Category ("GSHAREDVT")] static int test_0_synchronized_gshared () { var c = new SyncClass (); if (c.getInstance () != typeof (string)) return 1; return 0; } class Response { } public static int test_0_687865_isinst_with_cache_wrapper () { object o = new object (); if (o is Action>) return 1; else return 0; } enum DocType { One, Two, Three } class Doc { public string Name { get; set; } public DocType Type { get; set; } } // #2155 [Category ("GSHAREDVT")] public static int test_0_fullaot_sflda_cctor () { List documents = new List(); documents.Add(new Doc { Name = "Doc1", Type = DocType.One } ); documents.Add(new Doc { Name = "Doc2", Type = DocType.Two } ); documents.Add(new Doc { Name = "Doc3", Type = DocType.Three } ); documents.Add(new Doc { Name = "Doc4", Type = DocType.One } ); documents.Add(new Doc { Name = "Doc5", Type = DocType.Two } ); documents.Add(new Doc { Name = "Doc6", Type = DocType.Three } ); documents.Add(new Doc { Name = "Doc7", Type = DocType.One } ); documents.Add(new Doc { Name = "Doc8", Type = DocType.Two } ); documents.Add(new Doc { Name = "Doc9", Type = DocType.Three } ); List categories = documents.Select(d=>d.Type).Distinct().ToList().OrderBy(d => d).ToList(); foreach(DocType cat in categories) { List catDocs = documents.Where(d => d.Type == cat).OrderBy(d => d.Name).ToList(); } return 0; } class A { } static List sources = new List(); // #6112 public static int test_0_fullaot_imt () { sources.Add(null); sources.Add(null); int a = sources.Count; var enumerator = sources.GetEnumerator() as IEnumerator; while (enumerator.MoveNext()) { object o = enumerator.Current; } return 0; } class AClass { } class BClass : AClass { } public static int test_0_fullaot_variant_iface () { var arr = new BClass [10]; var enumerable = (IEnumerable)arr; enumerable.GetEnumerator (); return 0; } struct Record : Foo2.IRecord { int counter; int Foo2.IRecord.DoSomething () { return counter++; } } class Foo2 where T : Foo2.IRecord { public interface IRecord { int DoSomething (); } public static int Extract (T[] t) { return t[0].DoSomething (); } } class Foo3 where T : IComparable { public static int CompareTo (T[] t) { // This is a constrained call to Enum.CompareTo () return t[0].CompareTo (t [0]); } } public static int test_1_regress_constrained_iface_call_7571 () { var r = new Record [10]; Foo2.Extract (r); return Foo2.Extract (r); } enum ConstrainedEnum { Val = 1 } public static int test_0_regress_constrained_iface_call_enum () { var r = new ConstrainedEnum [10]; return Foo3.CompareTo (r); } public interface IFoo2 { void MoveNext (); } public struct Foo2 : IFoo2 { public void MoveNext () { } } public static Action Dingus (ref Foo2 f) { return new Action (f.MoveNext); } public static int test_0_delegate_unbox_full_aot () { Foo2 foo = new Foo2 (); Dingus (ref foo) (); return 0; } public static int test_0_arrays_ireadonly () { int[] arr = new int [10]; for (int i = 0; i < 10; ++i) arr [i] = i; IReadOnlyList a = (IReadOnlyList)(object)arr; if (a.Count != 10) return 1; if (a [0] != 0) return 2; if (a [1] != 1) return 3; return 0; } public static int test_0_volatile_read_write () { string foo = "ABC"; Volatile.Write (ref foo, "DEF"); return Volatile.Read (ref foo) == "DEF" ? 0 : 1; } // FIXME: Doesn't work with --regression as Interlocked.Add(ref long) is only implemented as an intrinsic #if FALSE public static async Task FooAsync (int i, int j) { Task t = new Task (delegate () { Console.WriteLine ("HIT!"); return 0; }); var response = await t; return default(T); } public static int test_0_fullaot_generic_async () { Task t = FooAsync (1, 2); t.RunSynchronously (); return 0; } #endif public static int test_0_delegate_callvirt_fullaot () { Func f = delegate () { return "A"; }; var f2 = (Func, string>)Delegate.CreateDelegate (typeof (Func, string>), null, f.GetType ().GetMethod ("Invoke")); var s = f2 (f); return s == "A" ? 0 : 1; } public interface ICovariant { } // Deleting the `out` modifier from this line stop the problem public interface IExtCovariant : ICovariant { } public class Sample : ICovariant { } public interface IMyInterface { } public static int test_0_variant_cast_cache () { object covariant = new Sample(); var foo = (ICovariant)(covariant); try { var extCovariant = (IExtCovariant)covariant; return 1; } catch { return 0; } } struct FooStruct2 { public int a1, a2, a3; } class MyClass where T: struct { [MethodImplAttribute (MethodImplOptions.NoInlining)] public MyClass(int a1, int a2, int a3, int a4, int a5, int a6, Nullable a) { } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static MyClass foo () { Nullable a = new Nullable (); return new MyClass (0, 0, 0, 0, 0, 0, a); } } public static int test_0_newobj_generic_context () { MyClass.foo (); return 0; } enum AnEnum { A, B } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static string constrained_tostring (T t) { return t.ToString (); } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static bool constrained_equals (T t1, T t2) { var c = EqualityComparer.Default; return c.Equals (t1, t2); } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static int constrained_gethashcode (T t) { return t.GetHashCode (); } public static int test_0_constrained_partial_sharing () { string s; s = constrained_tostring (5); if (s != "5") return 1; s = constrained_tostring (AnEnum.B); if (s != "B") return 2; if (!constrained_equals (1, 1)) return 3; if (constrained_equals (1, 2)) return 4; if (!constrained_equals (AnEnum.A, AnEnum.A)) return 5; if (constrained_equals (AnEnum.A, AnEnum.B)) return 6; int i = constrained_gethashcode (5); if (i != 5) return 7; i = constrained_gethashcode (AnEnum.B); if (i != 1) return 8; return 0; } enum Enum1 { A, B } enum Enum2 { A, B } public static int test_0_partial_sharing_ginst () { var l1 = new List> (); l1.Add (new KeyValuePair(5, Enum1.A)); if (l1 [0].Key != 5) return 1; if (l1 [0].Value != Enum1.A) return 2; var l2 = new List> (); l2.Add (new KeyValuePair(5, Enum2.B)); if (l2 [0].Key != 5) return 3; if (l2 [0].Value != Enum2.B) return 4; return 0; } static object delegate_8_args_res; public static int test_0_delegate_8_args () { delegate_8_args_res = null; Action test = (a, b, c, d, e, f, g, h) => { delegate_8_args_res = h; }; test("a", "b", "c", "d", "e", "f", "g", "h"); return delegate_8_args_res == "h" ? 0 : 1; } static void throw_catch_t () where T: Exception { try { throw new NotSupportedException (); } catch (T) { } } public static int test_0_gshared_catch_open_type () { throw_catch_t (); return 0; } class ThrowClass where T: Exception { public void throw_catch_t () { try { throw new NotSupportedException (); } catch (T) { } } } public static int test_0_gshared_catch_open_type_instance () { var c = new ThrowClass (); c.throw_catch_t (); return 0; } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static bool is_ref_or_contains_refs () { return RuntimeHelpers.IsReferenceOrContainsReferences (); } class IsRefClass { [MethodImplAttribute (MethodImplOptions.NoInlining)] public bool is_ref () { return RuntimeHelpers.IsReferenceOrContainsReferences (); } } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static bool is_ref_or_contains_refs_gen_ref () { return RuntimeHelpers.IsReferenceOrContainsReferences> (); } [MethodImplAttribute (MethodImplOptions.NoInlining)] public static bool is_ref_or_contains_refs_gen_noref () { return RuntimeHelpers.IsReferenceOrContainsReferences> (); } struct GenStruct { T t; } struct NoRefGenStruct { } struct RefStruct { string s; } struct NestedRefStruct { RefStruct r; } struct NoRefStruct { int i; } struct AStruct3 { T1 t1; T2 t2; T3 t3; } public static int test_0_isreference_intrins () { if (RuntimeHelpers.IsReferenceOrContainsReferences ()) return 1; if (!RuntimeHelpers.IsReferenceOrContainsReferences ()) return 2; if (!RuntimeHelpers.IsReferenceOrContainsReferences ()) return 3; if (!RuntimeHelpers.IsReferenceOrContainsReferences ()) return 4; if (RuntimeHelpers.IsReferenceOrContainsReferences ()) return 5; // Generic code if (is_ref_or_contains_refs ()) return 6; // Shared code if (!is_ref_or_contains_refs ()) return 7; // Complex type from shared code if (!is_ref_or_contains_refs_gen_ref ()) return 8; if (is_ref_or_contains_refs_gen_ref ()) return 9; if (is_ref_or_contains_refs_gen_noref ()) return 10; // Complex type from shared class method var c1 = new IsRefClass> (); if (c1.is_ref ()) return 11; var c2 = new IsRefClass> (); if (!c2.is_ref ()) return 12; return 0; } } #if !__MOBILE__ class GenericsTests : Tests { } #endif