1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using Unity.Burst;
- using Unity.Collections.LowLevel.Unsafe;
- using Unity.Jobs;
- using Unity.Mathematics;
-
- namespace Burst.Compiler.IL.Tests
- {
- // TODO: We should add a lot more tests for generics
- // - instance methods with generics
- // - instance methods with generics and outer generics from declaring type
- // - check generic name collisions
- // - ...etc.
- internal partial class TestGenerics
- {
- [TestCompiler]
- public static int StructNestedGenerics()
- {
- var value = new GenericStruct<float, GenericStruct<int, int>>();
- return value.FieldMixed1.Field4.FieldMixed1.Field4;
- }
-
- private unsafe struct DataOutput2<TType>
- where TType : struct
- {
- #pragma warning disable 0649
- internal TType m_Value;
- #pragma warning restore 0649
- }
-
- [TestCompiler]
- public static int CheckSizeOfWithGenerics()
- {
- return UnsafeUtility.SizeOf<DataOutput2<int>>() + UnsafeUtility.SizeOf<DataOutput2<DataOutput2<GenericStruct<int, float>>>>() * 10;
- }
-
- [TestCompiler]
- public static float TestOuterInnerGenerics()
- {
- var yoyo = new GenericStructOuter<MyValueData1, MyValueData2>.GenericStructInner
- {
- Field1 = { Value = 1.0f },
- Field2 = { Value = 11.0f }
- };
- Executor<GenericStructOuter<MyValueData1, MyValueData2>.GenericStructInner>.Execute(ref yoyo);
- return yoyo.Result;
- }
-
- [TestCompiler]
- public static float TestOuterInnerGenerics2()
- {
- #pragma warning disable 0649
- var yoyo = new GenericStructOuter2<MyValueData1, MyValueData2>.GenericStructInner<MyValueData2>
- {
- Field1 = { Value = 1.0f },
- Field2 = { Value = 11.0f },
- Field3 = { Value = 106.0f }
- };
- #pragma warning restore 0649
- Executor<GenericStructOuter2<MyValueData1, MyValueData2>.GenericStructInner<MyValueData2>>.Execute(ref yoyo);
- return yoyo.Result;
- }
-
- [TestCompiler]
- public static float TestActivator()
- {
- var yoyo = new MyActivator<MyValueData1>();
- var result = yoyo.Create(1.0f);
- return result.Value;
- }
-
- [TestCompiler]
- public static float TestActivatorIndirect()
- {
- var yoyo = new MyActivatorIndirect<MyValueData1>();
- var result = yoyo.Create(1.0f);
- return result.Value;
- }
-
- [TestCompiler]
- public static float TestStaticMethodGeneric()
- {
- var v1 = new MyValueData1() { Value = 10.0f };
- var v2 = new MyValueData2() { Value = 100.0f };
- var result = ComputeData<MyValueData2, MyValueData1, MyValueData2>(v1, v2);
- return result.Value;
- }
-
- public interface IMyActivator<T> where T : IMyData, new()
- {
- T Create(float value);
- }
-
- public struct MyActivator<T> : IMyActivator<T> where T : IMyData, new()
- {
- public T Create(float value)
- {
- var data = new T { Value = value + 2.0f };
- return data;
- }
- }
-
- public struct MyActivatorIndirect<T> : IMyActivator<T> where T : IMyData, new()
- {
- public T Create(float value)
- {
- return CreateActivator<T>(value);
- }
- }
-
- public interface IMyData
- {
- float Value { get; set; }
- }
-
- public struct MyValueData1 : IMyData
- {
- public float Value { get; set; }
- }
-
- public struct MyValueData2 : IMyData
- {
- public float Value { get; set; }
- }
-
- private struct GenericStructOuter<T1, T2> where T1 : IMyData where T2 : IMyData
- {
- public struct GenericStructInner : IJob
- {
- #pragma warning disable 0649
- public T1 Field1;
-
- public T2 Field2;
- #pragma warning restore 0649
- public float Result;
-
- public void Execute()
- {
- Result = Field1.Value + Field2.Value;
- }
- }
- }
-
- private struct GenericStructOuter2<T1, T2> where T1 : IMyData where T2 : IMyData
- {
- public struct GenericStructInner<T3> : IJob where T3 : IMyData
- {
- #pragma warning disable 0649
- public T1 Field1;
-
- public T2 Field2;
-
- public T3 Field3;
-
- public float Result;
- #pragma warning restore 0649
- public void Execute()
- {
- Result = Field1.Value + Field2.Value + Field3.Value;
- }
- }
- }
-
- private struct Executor<T> where T : IJob
- {
- public static void Execute(ref T job)
- {
- job.Execute();
- }
- }
-
- private struct GenericStruct<T1, T2>
- {
- #pragma warning disable 0649
- public GenericSubStruct<int, T2> FieldMixed1;
-
- public GenericSubStruct<T1, float> FieldMixed2;
- #pragma warning restore 0649
- }
-
- private struct GenericSubStruct<T3, T4>
- {
- #pragma warning disable 0649
- public T3 Field3;
-
- public T4 Field4;
- #pragma warning restore 0649
- }
-
- public interface IRotation
- {
- float Value { get; set; }
- }
-
- public struct SimpleRotation : IRotation
- {
- public float Value { get; set; }
- }
-
- public struct SimpleRotation2 : IRotation
- {
- public float Value { get; set; }
- }
-
- private static TNew CreateActivator<TNew>(float value) where TNew : IMyData, new()
- {
- var data = new TNew { Value = value + 5.0f };
- return data;
- }
-
- private static TResult ComputeData<TResult, TLeft, TRight>(TLeft left, TRight right) where TLeft : IMyData where TRight : IMyData where TResult : IMyData, new()
- {
- var result = new TResult();
- result.Value = 5.0f;
- result.Value += left.Value;
- result.Value += right.Value;
- return result;
- }
-
- [TestCompiler]
- public static void TestCrossConstraints()
- {
- var job = new ReproBurstError();
- job.Execute();
- }
-
- struct ReproBurstError : IJob
- {
- #pragma warning disable 0649
- public FirstLevel<SecondLevel<int>, int> first;
- public SecondLevel<int> second;
- #pragma warning restore 0649
-
- public void Execute()
- {
- first.First(second, 0);
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 1)]
- struct FirstLevel<T1, T2> where T1 : struct, ISecondLevel<T2>
- {
- public void First(T1 t1, T2 t2) { t1.Second(t2); }
- }
- interface ISecondLevel<T2> { void Second(T2 x); }
- [StructLayout(LayoutKind.Sequential, Size = 1)]
- struct SecondLevel<T> : ISecondLevel<T>
- {
- public void Second(T x) { }
- }
-
- [TestCompiler]
- public static float TestCrossAndGenericArgumentsInGenericInterface()
- {
- var value = new CaseMixedGenerics<SimpleRotation2>.Check<CaseMixedImplem, SimpleRotation>();
- return value.Execute();
- }
-
- public struct CaseMixedGenerics<T1> where T1 : IRotation
- {
- public interface MyInterface<T2> where T2 : IRotation
- {
- // Here we have a test with generics coming from interface but also coming from parameters
- // through an interface method call
- float MyMethod<T>(T2 t2, T value) where T : IRotation;
- }
-
- public struct Check<T3, T4> where T3 : MyInterface<T4> where T4 : IRotation
- {
- #pragma warning disable 0649
- private T3 t3Value;
-
- private T4 t4Value;
- #pragma warning restore 0649
-
- public float Execute()
- {
- return t3Value.MyMethod(t4Value, t4Value);
- }
-
- public static float Run(T1 t1, Check<T3, T4> t3t4)
- {
- return t1.Value + t3t4.Execute();
- }
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 1)]
- public struct CaseMixedImplem : CaseMixedGenerics<SimpleRotation2>.MyInterface<SimpleRotation>
- {
- public float MyMethod<T>(SimpleRotation t2, T value) where T : IRotation
- {
- return t2.Value + value.Value;
- }
- }
-
- [TestCompiler]
- public static int TestCase_1059355()
- {
- var job = new ReproBurstError2();
- job.Execute();
- return job.Result;
- }
-
- [TestCompiler]
- public static void ExplicitInterfaceImplementation()
- {
- ExplicitRunner.RunJob(new ExplicitInterfaceStruct());
- }
-
- struct ReproBurstError2 : IJob
- {
- #pragma warning disable 0649
- Simplified<BugRepro<Variant>.Foo> solver;
-
- public int Result;
- #pragma warning restore 0649
- public void Execute()
- {
- Result = solver.Run(default(BugRepro<Variant>.Foo));
- }
- }
-
- struct Variant { }
-
- struct BugRepro<TVariant>
- {
-
- public struct Foo : IFoo
- {
- public void Bug() { }
- }
- }
-
- interface IFoo
- {
- void Bug();
- }
-
- [StructLayout(LayoutKind.Sequential, Size = 1)]
- struct Simplified<T>
- where T : IFoo
- {
- public int Run(T foo)
- {
- foo.Bug();
- foo.Bug();
- return 1;
- }
- }
-
-
- struct ExplicitInterfaceStruct : IJob
- {
- void IJob.Execute()
- {
- }
- }
-
- struct ExplicitRunner
- {
- public static void RunJob<T>(T job) where T : IJob
- {
- job.Execute();
- }
- }
-
- // case devirtualizer not working for a Physics Job
- [TestCompiler]
- public static int ExecutePhysicsJob()
- {
- var job = new PhysicsJob();
- job.Execute(0);
- return job.result ? 1 : 0;
- }
-
- public interface IQueryResult
- {
- float Fraction { get; set; }
- }
-
- // The output of ray cast queries
- public struct RayCastResult : IQueryResult
- {
- public float Fraction { get; set; }
- public float3 SurfaceNormal;
- public int RigidBodyIndex;
- }
-
- public interface ICollector<T> where T : struct, IQueryResult
- {
- float MaxFraction { get; }
- bool HasHit { get; }
- int NumHits { get; }
- void AddHit(T hit);
- }
-
- public struct AnyHitCollector<T> : ICollector<T> where T : struct, IQueryResult
- {
- public float MaxFraction { get; private set; }
- public bool HasHit { get; private set; }
- public int NumHits { get { return HasHit ? 1 : 0; } }
- public void AddHit(T hit) { HasHit = true; }
- }
-
- public struct ClosestHitCollector<T> : ICollector<T> where T : struct, IQueryResult
- {
- public float MaxFraction { get { return ClosestHit.Fraction; } }
- public bool HasHit { get; private set; }
- public int NumHits { get { return HasHit ? 1 : 0; } }
- public T ClosestHit;
-
- public void AddHit(T hit)
- {
- ClosestHit = hit;
- HasHit = true;
- }
- }
-
- public interface IRaycastLeafProcessor
- {
- // Cast a ray against a leaf node of the bounding volume hierarchy.
- void RayLeaf<T>(int leafData, ref T collector) where T : struct, ICollector<RayCastResult>;
- }
-
- static void castRay<T>(int data, ref T collector) where T : struct, ICollector<RayCastResult>
- {
- RayCastResult result = new RayCastResult();
- result.Fraction = 0.5f;
- collector.AddHit(result);
- }
-
- private struct RayLeafProcessor : IRaycastLeafProcessor
- {
- public void RayLeaf<T>(int leafData, ref T collector) where T : struct, ICollector<RayCastResult>
- {
- castRay(leafData, ref collector);
- }
- }
-
- static void processLeaves<T, U>(ref T processor, ref U collector) where T : struct, IRaycastLeafProcessor where U : struct, ICollector<RayCastResult>
- {
- for (int i = 0; i < 10; i++)
- {
- if (collector.MaxFraction > 0.5f)
- {
- processor.RayLeaf(i, ref collector);
- }
- }
- }
-
- static void castRayMesh<T>(ref T collector) where T : struct, ICollector<RayCastResult>
- {
- RayLeafProcessor processor;
- processLeaves(ref processor, ref collector);
- }
-
- [BurstCompile]
- protected struct PhysicsJob : IJobParallelFor
- {
- public bool result;
- public unsafe void Execute(int index)
- {
- ClosestHitCollector<RayCastResult> collector = new ClosestHitCollector<RayCastResult>();
- castRayMesh(ref collector);
- result = collector.HasHit;
- }
- }
-
- [TestCompiler]
- public static float TestGenericIssueWithIJobProcessComponentData()
- {
- var jobProcess = new JobStruct_Process_DD<MyReadJob, GenericComponent<float>, Translation>();
- jobProcess.DataU0.Value = 5.0f;
- jobProcess.DataU1.Value = 22.0f;
- JobStruct_Process_DD<MyReadJob, GenericComponent<float>, Translation>.Execute(ref jobProcess);
- return jobProcess.DataU0.Value + jobProcess.DataU1.Value;
- }
-
- public interface IComponentData
- {
-
- }
-
- internal struct JobStruct_Process_DD<T, U0, U1>
- where T : struct, IJobProcessComponentData<U0, U1>
- where U0 : struct, IComponentData
- where U1 : struct, IComponentData
- {
- public T Data;
-
- public U0 DataU0;
- public U1 DataU1;
-
- public static unsafe void Execute(ref JobStruct_Process_DD<T, U0, U1> jobData)
- {
- jobData.Data.Execute(ref jobData.DataU0, ref jobData.DataU1);
- }
- }
-
-
- public interface IJobProcessComponentData<U0, U1>
- where U0 : struct, IComponentData
- where U1 : struct, IComponentData
- {
- void Execute(ref U0 c0, ref U1 c1);
- }
-
- public struct GenericComponent<T> : IComponentData
- {
- public T Value;
- }
-
- public struct Translation : IComponentData
- {
- public float Value;
- }
-
- struct MyReadJob : IJobProcessComponentData<GenericComponent<float>, Translation>
- {
- public void Execute(ref GenericComponent<float> c0, ref Translation c1)
- {
- c1.Value = c0.Value;
- }
- }
-
- public struct GenericTypeContainer<TType>
- where TType : struct
- {
- public TType Value;
- }
-
- [TestCompiler]
- public static int TestSizeOfWithGenericType()
- {
- return UnsafeUtility.SizeOf<GenericTypeContainer<int>>();
- }
-
- public class GenericContainerOuter<T>
- where T : struct
- {
- public struct GenericContainerInner<TType>
- where TType : struct
- {
- public TType Value;
- public T Value2;
- }
- }
-
- [TestCompiler]
- public static int TestSizeOfWithNestedGenericTypes()
- {
- return UnsafeUtility.SizeOf<GenericContainerOuter<long>.GenericContainerInner<int>>();
- }
-
- [TestCompiler]
- public static int CheckInterfaceCallsThroughGenericsOfGenerics()
- {
- var job = MyOuterStructWithGenerics<MyComponentData>.GetJob();
- job.Value1.Component.Value = 1;
- job.Value1.Component.Value = 2;
-
- job.Execute();
-
- return job.Result;
- }
-
- private interface IComponentDataOrdered
- {
- int Order { get; }
- }
-
-
- private struct EntityInChunkWithComponent<TComponent> where TComponent : struct, IComponentData
- {
- public TComponent Component;
-
- public EntityInChunkWithComponent(TComponent component)
- {
- Component = component;
- }
- }
-
- private struct EntityInChunkWithComponentComparer<TComponent> : IComparer<EntityInChunkWithComponent<TComponent>>
- where TComponent : unmanaged, IComponentData, IComparable<TComponent>
-
- {
- public int Compare(EntityInChunkWithComponent<TComponent> x, EntityInChunkWithComponent<TComponent> y)
- {
- return x.Component.CompareTo(y.Component);
- }
- }
-
- private struct MyOuterStructWithGenerics<TComponent>
- where TComponent : unmanaged, IComponentData, IComparable<TComponent>
- {
-
- public struct InnerWithComparer<T, TComparer> : IJob
- where T : struct
- where TComparer : struct, IComparer<T>
- {
- public T Value1;
- #pragma warning disable 0649
- public T Value2;
- #pragma warning restore 0649
-
- public int Result;
-
- public void Execute()
- {
- var comparer = new TComparer();
- Result = comparer.Compare(Value1, Value2);
- }
- }
-
- public static InnerWithComparer<EntityInChunkWithComponent<TComponent>, EntityInChunkWithComponentComparer<TComponent>> GetJob()
- {
- return new InnerWithComparer<EntityInChunkWithComponent<TComponent>, EntityInChunkWithComponentComparer<TComponent>>();
- }
- }
-
- private struct MyComponentData : IComponentData, IComparable<MyComponentData>
- {
- public int Value;
-
- public MyComponentData(int value)
- {
- Value = value;
- }
-
- public int CompareTo(MyComponentData other)
- {
- return Value.CompareTo(other.Value);
- }
- }
-
- [TestCompiler]
- public static long TestNestedGenericsWithStaticAndSameName()
- {
- return TypeIndexCache<float>.GetValue();
- }
-
- private class TypeIndexCache<T>
- {
- public static long GetValue()
- {
- return InnerIndex<int>.Create<TestGenerics, T>();
- }
- }
-
- private struct InnerIndex<T>
- {
- public static long Create<T1, T2>()
- {
- var value = BurstRuntime.GetHashCode64<T1>();
- value *= BurstRuntime.GetHashCode64<T2>();
- return value;
- }
- }
-
- // Set this to no-inlining so the compiler can't fold the branch away with anything other than type deduction.
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int GenericResolutionBranchTrick<T>()
- {
- if (default(T) is null)
- {
- return 42;
- }
- else
- {
- return 13;
- }
- }
-
- [TestCompiler]
- public static int TestGenericResolutionBranchTrickInt()
- {
- return GenericResolutionBranchTrick<int>();
- }
-
- private struct SomeStruct { }
-
- [TestCompiler]
- public static int TestGenericResolutionBranchTrickStruct()
- {
- return GenericResolutionBranchTrick<SomeStruct>();
- }
-
- private class SomeClass { }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionBoxNotSupported)]
- public static unsafe int TestGenericResolutionBranchTrickClass()
- {
- return GenericResolutionBranchTrick<SomeClass>();
- }
-
- // TODO: Burst does not yet resolve the correct method
- // [TestCompiler]
- public static int TestStructImplementingGenericInterfaceWithSourceOrderDependentResolution()
- {
- var value = new StructImplementingGenericInterfaceWithSourceOrderDependentResolution();
- return CallStructImplementingGenericInterfaceWithSourceOrderDependentResolutionHelper(value, 0);
- }
-
- private static int CallStructImplementingGenericInterfaceWithSourceOrderDependentResolutionHelper<T, U>(T value, U u)
- where T : IGenericInterfaceWithSourceOrderDependentResolution<U>
- {
- return value.Foo(u);
- }
-
- private interface IGenericInterfaceWithSourceOrderDependentResolution<T>
- {
- int Foo(int i);
- int Foo(T t);
- }
-
- private struct StructImplementingGenericInterfaceWithSourceOrderDependentResolution : IGenericInterfaceWithSourceOrderDependentResolution<int>
- {
- #pragma warning disable CS0473 // Explicit interface implementation matches more than one interface member
- int IGenericInterfaceWithSourceOrderDependentResolution<int>.Foo(int i) => 1;
- #pragma warning restore CS0473 // Explicit interface implementation matches more than one interface member
- public int Foo(int i) => 2;
- }
-
- [TestCompiler]
- public static int TestStructImplementingGenericInterfaceWithSourceOrderDependentResolution2()
- {
- var value = new StructImplementingGenericInterfaceWithSourceOrderDependentResolution2();
- return CallStructImplementingGenericInterfaceWithSourceOrderDependentResolution2Helper(value, 0);
- }
-
- private static int CallStructImplementingGenericInterfaceWithSourceOrderDependentResolution2Helper<T, U>(T value, U u)
- where T : IGenericInterfaceWithSourceOrderDependentResolution2<U>
- {
- return value.Foo(u);
- }
-
- private interface IGenericInterfaceWithSourceOrderDependentResolution2<T>
- {
- // Inverted order from IGenericInterfaceWithSourceOrderDependentResolution<T> above
- int Foo(T t);
- int Foo(int i);
- }
-
- private struct StructImplementingGenericInterfaceWithSourceOrderDependentResolution2 : IGenericInterfaceWithSourceOrderDependentResolution2<int>
- {
- #pragma warning disable CS0473 // Explicit interface implementation matches more than one interface member
- int IGenericInterfaceWithSourceOrderDependentResolution2<int>.Foo(int i) => 1;
- #pragma warning restore CS0473 // Explicit interface implementation matches more than one interface member
- public int Foo(int i) => 2;
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGenericStructImplementingGenericInterfaceWithOverloads()
- {
- var value = new GenericStructImplementingGenericInterfaceWithOverloads<int>();
- return CallGenericStructImplementingGenericInterfaceWithOverloadsHelper(value);
- }
-
- private static int CallGenericStructImplementingGenericInterfaceWithOverloadsHelper<T>(T value)
- where T : IGenericInterfaceWithOverloads<int>
- {
- return value.Foo(0u) + value.Foo(0);
- }
-
- private interface IGenericInterfaceWithOverloads<T>
- {
- T Foo(uint u);
- T Foo(int i);
- }
-
- private struct GenericStructImplementingGenericInterfaceWithOverloads<T> : IGenericInterfaceWithOverloads<T>
- {
- public T UIntValue;
- public T IntValue;
-
- public T Foo(uint u) => UIntValue;
-
- public T Foo(int i) => IntValue;
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGenericStructImplementingGenericInterfaceWithOverloads2()
- {
- var value = new GenericStructImplementingGenericInterfaceWithOverloads<int>
- {
- UIntValue = 42,
- IntValue = 43,
- };
- CallGenericStructImplementingGenericInterfaceWithOverloadsHelper2(value, out int result1, out int result2);
- return result1 + result2;
- }
-
- private static void CallGenericStructImplementingGenericInterfaceWithOverloadsHelper2<T, U>(T value, out U result1, out U result2)
- where T : IGenericInterfaceWithOverloads<U>
- {
- result1 = value.Foo(0u);
- result2 = value.Foo(0);
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGenericStructImplementingGenericInterfaceWithOverloadsWrapper()
- {
- var value = new GenericStructImplementingGenericInterfaceWithOverloadsWrapper<int>
- {
- UIntValue = new GenericStructImplementingGenericInterfaceWithOverloads<int>
- {
- UIntValue = 42,
- IntValue = 43,
- },
- IntValue = new GenericStructImplementingGenericInterfaceWithOverloads<int>
- {
- UIntValue = 44,
- IntValue = 45,
- },
- };
- return CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper(value);
- }
-
- private static int CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper<T>(T value)
- where T : IGenericInterfaceWithOverloadsWrapper<int>
- {
- return value.Bar(0u).Foo(0u)
- + value.Bar(0u).Foo(0)
- + value.Bar(0).Foo(0u)
- + value.Bar(0).Foo(0);
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGenericStructImplementingGenericInterfaceWithOverloadsWrapper2()
- {
- var value = new GenericStructImplementingGenericInterfaceWithOverloadsWrapper<int>();
- CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper2(
- value,
- out int result1,
- out int result2,
- out int result3,
- out int result4);
- return result1 + result2 + result3 + result4;
- }
-
- private static void CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper2<T, U>(
- T value,
- out U result1,
- out U result2,
- out U result3,
- out U result4)
- where T : IGenericInterfaceWithOverloadsWrapper<U>
- {
- result1 = value.Bar(0u).Foo(0u);
- result2 = value.Bar(0u).Foo(0);
- result3 = value.Bar(0).Foo(0u);
- result4 = value.Bar(0).Foo(0);
- }
-
- private interface IGenericInterfaceWithOverloadsWrapper<T>
- {
- GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(uint index);
- GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(int index);
- }
-
- private struct GenericStructImplementingGenericInterfaceWithOverloadsWrapper<T> : IGenericInterfaceWithOverloadsWrapper<T>
- {
- public GenericStructImplementingGenericInterfaceWithOverloads<T> UIntValue;
- public GenericStructImplementingGenericInterfaceWithOverloads<T> IntValue;
-
- public GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(uint index) => UIntValue;
-
- public GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(int index) => IntValue;
- }
-
- // TODO: Burst does not yet resolve the correct method
- // [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload()
- {
- var value = new StructImplementingGenericInterfaceWithMoreSpecificOverload<int>();
- return CallStructImplementingGenericInterfaceWithMoreSpecificOverloadHelper(value);
- }
-
- private static int CallStructImplementingGenericInterfaceWithMoreSpecificOverloadHelper<T>(T value)
- where T : IGenericInterfaceWithMoreSpecificOverload<int>
- {
- return value.Foo(0);
- }
-
- private interface IGenericInterfaceWithMoreSpecificOverload<T>
- {
- int Foo(T t);
- int Foo(int i);
- }
-
- private struct StructImplementingGenericInterfaceWithMoreSpecificOverload<T> : IGenericInterfaceWithMoreSpecificOverload<T>
- {
- public int Foo(T t) => 1;
-
- public int Foo(int i) => 2;
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload2()
- {
- var value = new StructImplementingGenericInterfaceWithMoreSpecificOverload2();
- return CallStructImplementingGenericInterfaceWithMoreSpecificOverload2Helper(value);
- }
-
- private static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload2Helper<T>(T value)
- where T : IGenericInterfaceWithMoreSpecificOverload<int>
- {
- return value.Foo(0);
- }
-
- private struct StructImplementingGenericInterfaceWithMoreSpecificOverload2 : IGenericInterfaceWithMoreSpecificOverload<int>
- {
- public int Foo(int i) => 1;
- }
-
- [TestCompiler]
- public static int CallGenericStructImplementingGenericInterfaceWithPrivateOverload()
- {
- var value = new GenericStructImplementingGenericInterfaceWithPrivateOverload<int>();
- return CallGenericStructImplementingGenericInterfaceWithPrivateOverloadHelper(value);
- }
-
- private interface IGenericInterface<T>
- {
- T Get(int idx);
- }
-
- private static int CallGenericStructImplementingGenericInterfaceWithPrivateOverloadHelper<T>(T value)
- where T : IGenericInterface<int>
- {
- return value.Get(0);
- }
-
- private struct GenericStructImplementingGenericInterfaceWithPrivateOverload<T> : IGenericInterface<T>
- {
- private int Get(T idx) => 42;
-
- public T Get(int idx) => default;
- }
-
- [TestCompiler]
- public static int CallGenericStructImplementingGenericInterfaceDerived()
- {
- var value = new GenericStructImplementingGenericInterfaceDerived<int>();
- return CallGenericStructImplementingGenericInterfaceDerivedHelper(value);
- }
-
- private static int CallGenericStructImplementingGenericInterfaceDerivedHelper<T>(T value)
- where T : IGenericInterfaceDerived<int, int>
- {
- return value.Foo(0);
- }
-
- private interface IGenericInterfaceBase<T>
- {
- int Foo(T t);
- int Foo(double d);
- }
-
- private interface IGenericInterfaceDerived<T, U> : IGenericInterfaceBase<T>
- {
- int Foo(U u);
- }
-
- private struct GenericStructImplementingGenericInterfaceDerived<T> : IGenericInterfaceDerived<T, T>
- {
- public int Foo(T u) => 1;
-
- public int Foo(double d) => (int)d;
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallBaseInterfaceMethodOnGenericStruct()
- {
- var value = new GenericStructImplementingGenericInterfaceDerived<int>();
- return CallBaseInterfaceMethodOnGenericStructHelper(value);
- }
-
- private static int CallBaseInterfaceMethodOnGenericStructHelper<T>(T value)
- where T : IGenericInterfaceBase<int>
- {
- return value.Foo(0);
- }
-
- // TODO: Burst does not yet resolve the correct method
- // [TestCompiler]
- public static int CallGenericStructImplementingGenericInterfaceDerived2()
- {
- var value = new GenericStructImplementingGenericInterfaceDerived2<int>();
- return CallGenericStructImplementingGenericInterfaceDerived2Helper<GenericStructImplementingGenericInterfaceDerived2<int>, int>(value);
- }
-
- private static int CallGenericStructImplementingGenericInterfaceDerived2Helper<T, U>(T value)
- where T : IGenericInterfaceDerived<U, U>
- {
- return value.Foo(default);
- }
-
- private struct GenericStructImplementingGenericInterfaceDerived2<T> : IGenericInterfaceDerived<T, T>
- {
- int IGenericInterfaceBase<T>.Foo(T t) => 2;
-
- int IGenericInterfaceBase<T>.Foo(double d) => (int)d;
-
- public int Foo(T u) => 1;
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGetHashCodeViaInterface()
- {
- return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct { Value = 42 });
- }
-
- public static int CallGetHashCodeViaInterfaceHelper<T>(T value)
- {
- return value.GetHashCode();
- }
-
- public struct CallGetHashCodeViaInterfaceStruct
- {
- public int Value;
-
- public override int GetHashCode() => Value.GetHashCode();
-
- public int GetHashCode(int x) => x;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_UnableToAccessManagedMethod)]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGetHashCodeViaInterface2()
- {
- return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct2 { Value = 42 });
- }
-
- public struct CallGetHashCodeViaInterfaceStruct2
- {
- public int Value;
-
- // This struct doesn't override GetHashCode, so a Burst compiler error is expected.
- // (but hashing should still succeed regardless).
-
- public int GetHashCode(int x) => x;
-
- public double GetHashCode(double d) => d;
- }
-
- [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_UnableToAccessManagedMethod)]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int CallGetHashCodeViaInterface3()
- {
- return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct3 { Value = 42 });
- }
-
- public struct CallGetHashCodeViaInterfaceStruct3
- {
- public int Value;
-
- // This struct doesn't override GetHashCode and has no other methods with that name.
- }
-
- #if NET7_0
- private interface IDefault
- {
- int A();
-
- int B() => 42;
- }
-
- private interface IDefaultSelfCall
- {
- int A();
- int B() => A() + 1;
- }
-
- private interface IDefaultGeneric<T>
- {
- public T A();
- public (U, T) B<U>() => (default, A());
- }
-
- private struct DefaultBasic : IDefault
- {
- public int A() => 43;
- }
-
- private struct DefaultImpl : IDefault
- {
- public int A() => 43;
- public int B() => 3;
- }
-
- private struct SelfCallDefault : IDefaultSelfCall
- {
- public int A() => 10;
- }
-
- private struct SelfCallImpl : IDefaultSelfCall
- {
- public int A() => 99;
- public int B() => A() * 3;
- }
-
- private struct DefaultGenericBasic: IDefaultGeneric<int>
- {
- public int A() => 10;
- }
-
- private struct DefaultGenericImpl: IDefaultGeneric<int>
- {
- public int A() => 10;
-
- (U, int) IDefaultGeneric<int>.B<U>() => (default, 3);
- }
-
- private struct DefaultVeryGenericBasic<T>: IDefaultGeneric<T>
- {
- public T A() => default;
- }
-
- private struct DefaultVeryGenericImpl<T>: IDefaultGeneric<T>
- {
- public T A() => default;
-
- (U, T) IDefaultGeneric<T>.B<U>() => (default, default);
- }
-
- private interface IBumper
- {
- void Bump();
- }
-
- private struct SelfMutator : IDefaultSelfCall, IBumper
- {
- public int X;
-
- public void Bump()
- {
- X = (X << 1) | 1;
- }
-
- public int A()
- {
- var x = X;
- Bump();
- return x;
- }
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int TestDefaultInterfaceMethod()
- {
- return UseDefaultInterfaceMethodsHelper(new DefaultBasic());
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int TestImplementedDefaultInterfaceMethod()
- {
- return UseDefaultInterfaceMethodsHelper(new DefaultImpl());
- }
-
- private static int UseDefaultInterfaceMethodsHelper<T>(T t)
- where T: IDefault
- {
- return t.B();
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int TestSelfCallingDefaultInterfaceMethod()
- {
- return UseSelfCallingDefaultInterfaceMethod(new SelfCallDefault(), new SelfCallImpl());
- }
-
- private static int UseSelfCallingDefaultInterfaceMethod<T, U>(T t, U u)
- where T : IDefaultSelfCall
- where U : IDefaultSelfCall
- {
- return t.B() + u.B();
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int TestGenericDefaultInterfaceMethod()
- {
- return UseGenericDefaultInterfaceMethod(new DefaultGenericBasic(), new DefaultGenericImpl());
- }
-
- private static int UseGenericDefaultInterfaceMethod<T, U>(T t, U u)
- where T : IDefaultGeneric<int>
- where U : IDefaultGeneric<int>
- {
- var (x, y) = t.B<int>();
- var (z, w) = u.B<int>();
- return (x + y) * (z + w);
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int TestVeryGenericDefaultInterfaceMethod()
- {
- var ((x, y), (z, w)) = UseVeryGenericDefaultInterfaceMethod<DefaultVeryGenericBasic<int>, DefaultVeryGenericImpl<int>, int, int, long>(new DefaultVeryGenericBasic<int>(), new DefaultVeryGenericImpl<int>());
- return (int)(x + y + z + w);
- }
-
- private static ((W, V), (X, V)) UseVeryGenericDefaultInterfaceMethod<T, U, V, W, X>(T t, U u)
- where T : IDefaultGeneric<V>
- where U : IDefaultGeneric<V>
- {
- return (t.B<W>(), u.B<X>());
- }
-
- private static int UseSelfMutator<T>(ref T x) where T : IDefaultSelfCall, IBumper
- {
- x.Bump();
- var r = x.B();
- x.Bump();
- return r;
- }
-
- [TestCompiler]
- #if BURST_TESTS_ONLY
- [TestHash]
- #endif
- public static int TestSelfMutator()
- {
- var x = new SelfMutator();
- x.Bump();
- var ret = UseSelfMutator(ref x);
- x.Bump();
- return (x.X << 16) | ret;
- }
-
- #endif
- }
- }
|