Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

051-TestGenerics.cs 39KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. using Unity.Burst;
  6. using Unity.Collections.LowLevel.Unsafe;
  7. using Unity.Jobs;
  8. using Unity.Mathematics;
  9. namespace Burst.Compiler.IL.Tests
  10. {
  11. // TODO: We should add a lot more tests for generics
  12. // - instance methods with generics
  13. // - instance methods with generics and outer generics from declaring type
  14. // - check generic name collisions
  15. // - ...etc.
  16. internal partial class TestGenerics
  17. {
  18. [TestCompiler]
  19. public static int StructNestedGenerics()
  20. {
  21. var value = new GenericStruct<float, GenericStruct<int, int>>();
  22. return value.FieldMixed1.Field4.FieldMixed1.Field4;
  23. }
  24. private unsafe struct DataOutput2<TType>
  25. where TType : struct
  26. {
  27. #pragma warning disable 0649
  28. internal TType m_Value;
  29. #pragma warning restore 0649
  30. }
  31. [TestCompiler]
  32. public static int CheckSizeOfWithGenerics()
  33. {
  34. return UnsafeUtility.SizeOf<DataOutput2<int>>() + UnsafeUtility.SizeOf<DataOutput2<DataOutput2<GenericStruct<int, float>>>>() * 10;
  35. }
  36. [TestCompiler]
  37. public static float TestOuterInnerGenerics()
  38. {
  39. var yoyo = new GenericStructOuter<MyValueData1, MyValueData2>.GenericStructInner
  40. {
  41. Field1 = { Value = 1.0f },
  42. Field2 = { Value = 11.0f }
  43. };
  44. Executor<GenericStructOuter<MyValueData1, MyValueData2>.GenericStructInner>.Execute(ref yoyo);
  45. return yoyo.Result;
  46. }
  47. [TestCompiler]
  48. public static float TestOuterInnerGenerics2()
  49. {
  50. #pragma warning disable 0649
  51. var yoyo = new GenericStructOuter2<MyValueData1, MyValueData2>.GenericStructInner<MyValueData2>
  52. {
  53. Field1 = { Value = 1.0f },
  54. Field2 = { Value = 11.0f },
  55. Field3 = { Value = 106.0f }
  56. };
  57. #pragma warning restore 0649
  58. Executor<GenericStructOuter2<MyValueData1, MyValueData2>.GenericStructInner<MyValueData2>>.Execute(ref yoyo);
  59. return yoyo.Result;
  60. }
  61. [TestCompiler]
  62. public static float TestActivator()
  63. {
  64. var yoyo = new MyActivator<MyValueData1>();
  65. var result = yoyo.Create(1.0f);
  66. return result.Value;
  67. }
  68. [TestCompiler]
  69. public static float TestActivatorIndirect()
  70. {
  71. var yoyo = new MyActivatorIndirect<MyValueData1>();
  72. var result = yoyo.Create(1.0f);
  73. return result.Value;
  74. }
  75. [TestCompiler]
  76. public static float TestStaticMethodGeneric()
  77. {
  78. var v1 = new MyValueData1() { Value = 10.0f };
  79. var v2 = new MyValueData2() { Value = 100.0f };
  80. var result = ComputeData<MyValueData2, MyValueData1, MyValueData2>(v1, v2);
  81. return result.Value;
  82. }
  83. public interface IMyActivator<T> where T : IMyData, new()
  84. {
  85. T Create(float value);
  86. }
  87. public struct MyActivator<T> : IMyActivator<T> where T : IMyData, new()
  88. {
  89. public T Create(float value)
  90. {
  91. var data = new T { Value = value + 2.0f };
  92. return data;
  93. }
  94. }
  95. public struct MyActivatorIndirect<T> : IMyActivator<T> where T : IMyData, new()
  96. {
  97. public T Create(float value)
  98. {
  99. return CreateActivator<T>(value);
  100. }
  101. }
  102. public interface IMyData
  103. {
  104. float Value { get; set; }
  105. }
  106. public struct MyValueData1 : IMyData
  107. {
  108. public float Value { get; set; }
  109. }
  110. public struct MyValueData2 : IMyData
  111. {
  112. public float Value { get; set; }
  113. }
  114. private struct GenericStructOuter<T1, T2> where T1 : IMyData where T2 : IMyData
  115. {
  116. public struct GenericStructInner : IJob
  117. {
  118. #pragma warning disable 0649
  119. public T1 Field1;
  120. public T2 Field2;
  121. #pragma warning restore 0649
  122. public float Result;
  123. public void Execute()
  124. {
  125. Result = Field1.Value + Field2.Value;
  126. }
  127. }
  128. }
  129. private struct GenericStructOuter2<T1, T2> where T1 : IMyData where T2 : IMyData
  130. {
  131. public struct GenericStructInner<T3> : IJob where T3 : IMyData
  132. {
  133. #pragma warning disable 0649
  134. public T1 Field1;
  135. public T2 Field2;
  136. public T3 Field3;
  137. public float Result;
  138. #pragma warning restore 0649
  139. public void Execute()
  140. {
  141. Result = Field1.Value + Field2.Value + Field3.Value;
  142. }
  143. }
  144. }
  145. private struct Executor<T> where T : IJob
  146. {
  147. public static void Execute(ref T job)
  148. {
  149. job.Execute();
  150. }
  151. }
  152. private struct GenericStruct<T1, T2>
  153. {
  154. #pragma warning disable 0649
  155. public GenericSubStruct<int, T2> FieldMixed1;
  156. public GenericSubStruct<T1, float> FieldMixed2;
  157. #pragma warning restore 0649
  158. }
  159. private struct GenericSubStruct<T3, T4>
  160. {
  161. #pragma warning disable 0649
  162. public T3 Field3;
  163. public T4 Field4;
  164. #pragma warning restore 0649
  165. }
  166. public interface IRotation
  167. {
  168. float Value { get; set; }
  169. }
  170. public struct SimpleRotation : IRotation
  171. {
  172. public float Value { get; set; }
  173. }
  174. public struct SimpleRotation2 : IRotation
  175. {
  176. public float Value { get; set; }
  177. }
  178. private static TNew CreateActivator<TNew>(float value) where TNew : IMyData, new()
  179. {
  180. var data = new TNew { Value = value + 5.0f };
  181. return data;
  182. }
  183. private static TResult ComputeData<TResult, TLeft, TRight>(TLeft left, TRight right) where TLeft : IMyData where TRight : IMyData where TResult : IMyData, new()
  184. {
  185. var result = new TResult();
  186. result.Value = 5.0f;
  187. result.Value += left.Value;
  188. result.Value += right.Value;
  189. return result;
  190. }
  191. [TestCompiler]
  192. public static void TestCrossConstraints()
  193. {
  194. var job = new ReproBurstError();
  195. job.Execute();
  196. }
  197. struct ReproBurstError : IJob
  198. {
  199. #pragma warning disable 0649
  200. public FirstLevel<SecondLevel<int>, int> first;
  201. public SecondLevel<int> second;
  202. #pragma warning restore 0649
  203. public void Execute()
  204. {
  205. first.First(second, 0);
  206. }
  207. }
  208. [StructLayout(LayoutKind.Sequential, Size = 1)]
  209. struct FirstLevel<T1, T2> where T1 : struct, ISecondLevel<T2>
  210. {
  211. public void First(T1 t1, T2 t2) { t1.Second(t2); }
  212. }
  213. interface ISecondLevel<T2> { void Second(T2 x); }
  214. [StructLayout(LayoutKind.Sequential, Size = 1)]
  215. struct SecondLevel<T> : ISecondLevel<T>
  216. {
  217. public void Second(T x) { }
  218. }
  219. [TestCompiler]
  220. public static float TestCrossAndGenericArgumentsInGenericInterface()
  221. {
  222. var value = new CaseMixedGenerics<SimpleRotation2>.Check<CaseMixedImplem, SimpleRotation>();
  223. return value.Execute();
  224. }
  225. public struct CaseMixedGenerics<T1> where T1 : IRotation
  226. {
  227. public interface MyInterface<T2> where T2 : IRotation
  228. {
  229. // Here we have a test with generics coming from interface but also coming from parameters
  230. // through an interface method call
  231. float MyMethod<T>(T2 t2, T value) where T : IRotation;
  232. }
  233. public struct Check<T3, T4> where T3 : MyInterface<T4> where T4 : IRotation
  234. {
  235. #pragma warning disable 0649
  236. private T3 t3Value;
  237. private T4 t4Value;
  238. #pragma warning restore 0649
  239. public float Execute()
  240. {
  241. return t3Value.MyMethod(t4Value, t4Value);
  242. }
  243. public static float Run(T1 t1, Check<T3, T4> t3t4)
  244. {
  245. return t1.Value + t3t4.Execute();
  246. }
  247. }
  248. }
  249. [StructLayout(LayoutKind.Sequential, Size = 1)]
  250. public struct CaseMixedImplem : CaseMixedGenerics<SimpleRotation2>.MyInterface<SimpleRotation>
  251. {
  252. public float MyMethod<T>(SimpleRotation t2, T value) where T : IRotation
  253. {
  254. return t2.Value + value.Value;
  255. }
  256. }
  257. [TestCompiler]
  258. public static int TestCase_1059355()
  259. {
  260. var job = new ReproBurstError2();
  261. job.Execute();
  262. return job.Result;
  263. }
  264. [TestCompiler]
  265. public static void ExplicitInterfaceImplementation()
  266. {
  267. ExplicitRunner.RunJob(new ExplicitInterfaceStruct());
  268. }
  269. struct ReproBurstError2 : IJob
  270. {
  271. #pragma warning disable 0649
  272. Simplified<BugRepro<Variant>.Foo> solver;
  273. public int Result;
  274. #pragma warning restore 0649
  275. public void Execute()
  276. {
  277. Result = solver.Run(default(BugRepro<Variant>.Foo));
  278. }
  279. }
  280. struct Variant { }
  281. struct BugRepro<TVariant>
  282. {
  283. public struct Foo : IFoo
  284. {
  285. public void Bug() { }
  286. }
  287. }
  288. interface IFoo
  289. {
  290. void Bug();
  291. }
  292. [StructLayout(LayoutKind.Sequential, Size = 1)]
  293. struct Simplified<T>
  294. where T : IFoo
  295. {
  296. public int Run(T foo)
  297. {
  298. foo.Bug();
  299. foo.Bug();
  300. return 1;
  301. }
  302. }
  303. struct ExplicitInterfaceStruct : IJob
  304. {
  305. void IJob.Execute()
  306. {
  307. }
  308. }
  309. struct ExplicitRunner
  310. {
  311. public static void RunJob<T>(T job) where T : IJob
  312. {
  313. job.Execute();
  314. }
  315. }
  316. // case devirtualizer not working for a Physics Job
  317. [TestCompiler]
  318. public static int ExecutePhysicsJob()
  319. {
  320. var job = new PhysicsJob();
  321. job.Execute(0);
  322. return job.result ? 1 : 0;
  323. }
  324. public interface IQueryResult
  325. {
  326. float Fraction { get; set; }
  327. }
  328. // The output of ray cast queries
  329. public struct RayCastResult : IQueryResult
  330. {
  331. public float Fraction { get; set; }
  332. public float3 SurfaceNormal;
  333. public int RigidBodyIndex;
  334. }
  335. public interface ICollector<T> where T : struct, IQueryResult
  336. {
  337. float MaxFraction { get; }
  338. bool HasHit { get; }
  339. int NumHits { get; }
  340. void AddHit(T hit);
  341. }
  342. public struct AnyHitCollector<T> : ICollector<T> where T : struct, IQueryResult
  343. {
  344. public float MaxFraction { get; private set; }
  345. public bool HasHit { get; private set; }
  346. public int NumHits { get { return HasHit ? 1 : 0; } }
  347. public void AddHit(T hit) { HasHit = true; }
  348. }
  349. public struct ClosestHitCollector<T> : ICollector<T> where T : struct, IQueryResult
  350. {
  351. public float MaxFraction { get { return ClosestHit.Fraction; } }
  352. public bool HasHit { get; private set; }
  353. public int NumHits { get { return HasHit ? 1 : 0; } }
  354. public T ClosestHit;
  355. public void AddHit(T hit)
  356. {
  357. ClosestHit = hit;
  358. HasHit = true;
  359. }
  360. }
  361. public interface IRaycastLeafProcessor
  362. {
  363. // Cast a ray against a leaf node of the bounding volume hierarchy.
  364. void RayLeaf<T>(int leafData, ref T collector) where T : struct, ICollector<RayCastResult>;
  365. }
  366. static void castRay<T>(int data, ref T collector) where T : struct, ICollector<RayCastResult>
  367. {
  368. RayCastResult result = new RayCastResult();
  369. result.Fraction = 0.5f;
  370. collector.AddHit(result);
  371. }
  372. private struct RayLeafProcessor : IRaycastLeafProcessor
  373. {
  374. public void RayLeaf<T>(int leafData, ref T collector) where T : struct, ICollector<RayCastResult>
  375. {
  376. castRay(leafData, ref collector);
  377. }
  378. }
  379. static void processLeaves<T, U>(ref T processor, ref U collector) where T : struct, IRaycastLeafProcessor where U : struct, ICollector<RayCastResult>
  380. {
  381. for (int i = 0; i < 10; i++)
  382. {
  383. if (collector.MaxFraction > 0.5f)
  384. {
  385. processor.RayLeaf(i, ref collector);
  386. }
  387. }
  388. }
  389. static void castRayMesh<T>(ref T collector) where T : struct, ICollector<RayCastResult>
  390. {
  391. RayLeafProcessor processor;
  392. processLeaves(ref processor, ref collector);
  393. }
  394. [BurstCompile]
  395. protected struct PhysicsJob : IJobParallelFor
  396. {
  397. public bool result;
  398. public unsafe void Execute(int index)
  399. {
  400. ClosestHitCollector<RayCastResult> collector = new ClosestHitCollector<RayCastResult>();
  401. castRayMesh(ref collector);
  402. result = collector.HasHit;
  403. }
  404. }
  405. [TestCompiler]
  406. public static float TestGenericIssueWithIJobProcessComponentData()
  407. {
  408. var jobProcess = new JobStruct_Process_DD<MyReadJob, GenericComponent<float>, Translation>();
  409. jobProcess.DataU0.Value = 5.0f;
  410. jobProcess.DataU1.Value = 22.0f;
  411. JobStruct_Process_DD<MyReadJob, GenericComponent<float>, Translation>.Execute(ref jobProcess);
  412. return jobProcess.DataU0.Value + jobProcess.DataU1.Value;
  413. }
  414. public interface IComponentData
  415. {
  416. }
  417. internal struct JobStruct_Process_DD<T, U0, U1>
  418. where T : struct, IJobProcessComponentData<U0, U1>
  419. where U0 : struct, IComponentData
  420. where U1 : struct, IComponentData
  421. {
  422. public T Data;
  423. public U0 DataU0;
  424. public U1 DataU1;
  425. public static unsafe void Execute(ref JobStruct_Process_DD<T, U0, U1> jobData)
  426. {
  427. jobData.Data.Execute(ref jobData.DataU0, ref jobData.DataU1);
  428. }
  429. }
  430. public interface IJobProcessComponentData<U0, U1>
  431. where U0 : struct, IComponentData
  432. where U1 : struct, IComponentData
  433. {
  434. void Execute(ref U0 c0, ref U1 c1);
  435. }
  436. public struct GenericComponent<T> : IComponentData
  437. {
  438. public T Value;
  439. }
  440. public struct Translation : IComponentData
  441. {
  442. public float Value;
  443. }
  444. struct MyReadJob : IJobProcessComponentData<GenericComponent<float>, Translation>
  445. {
  446. public void Execute(ref GenericComponent<float> c0, ref Translation c1)
  447. {
  448. c1.Value = c0.Value;
  449. }
  450. }
  451. public struct GenericTypeContainer<TType>
  452. where TType : struct
  453. {
  454. public TType Value;
  455. }
  456. [TestCompiler]
  457. public static int TestSizeOfWithGenericType()
  458. {
  459. return UnsafeUtility.SizeOf<GenericTypeContainer<int>>();
  460. }
  461. public class GenericContainerOuter<T>
  462. where T : struct
  463. {
  464. public struct GenericContainerInner<TType>
  465. where TType : struct
  466. {
  467. public TType Value;
  468. public T Value2;
  469. }
  470. }
  471. [TestCompiler]
  472. public static int TestSizeOfWithNestedGenericTypes()
  473. {
  474. return UnsafeUtility.SizeOf<GenericContainerOuter<long>.GenericContainerInner<int>>();
  475. }
  476. [TestCompiler]
  477. public static int CheckInterfaceCallsThroughGenericsOfGenerics()
  478. {
  479. var job = MyOuterStructWithGenerics<MyComponentData>.GetJob();
  480. job.Value1.Component.Value = 1;
  481. job.Value1.Component.Value = 2;
  482. job.Execute();
  483. return job.Result;
  484. }
  485. private interface IComponentDataOrdered
  486. {
  487. int Order { get; }
  488. }
  489. private struct EntityInChunkWithComponent<TComponent> where TComponent : struct, IComponentData
  490. {
  491. public TComponent Component;
  492. public EntityInChunkWithComponent(TComponent component)
  493. {
  494. Component = component;
  495. }
  496. }
  497. private struct EntityInChunkWithComponentComparer<TComponent> : IComparer<EntityInChunkWithComponent<TComponent>>
  498. where TComponent : unmanaged, IComponentData, IComparable<TComponent>
  499. {
  500. public int Compare(EntityInChunkWithComponent<TComponent> x, EntityInChunkWithComponent<TComponent> y)
  501. {
  502. return x.Component.CompareTo(y.Component);
  503. }
  504. }
  505. private struct MyOuterStructWithGenerics<TComponent>
  506. where TComponent : unmanaged, IComponentData, IComparable<TComponent>
  507. {
  508. public struct InnerWithComparer<T, TComparer> : IJob
  509. where T : struct
  510. where TComparer : struct, IComparer<T>
  511. {
  512. public T Value1;
  513. #pragma warning disable 0649
  514. public T Value2;
  515. #pragma warning restore 0649
  516. public int Result;
  517. public void Execute()
  518. {
  519. var comparer = new TComparer();
  520. Result = comparer.Compare(Value1, Value2);
  521. }
  522. }
  523. public static InnerWithComparer<EntityInChunkWithComponent<TComponent>, EntityInChunkWithComponentComparer<TComponent>> GetJob()
  524. {
  525. return new InnerWithComparer<EntityInChunkWithComponent<TComponent>, EntityInChunkWithComponentComparer<TComponent>>();
  526. }
  527. }
  528. private struct MyComponentData : IComponentData, IComparable<MyComponentData>
  529. {
  530. public int Value;
  531. public MyComponentData(int value)
  532. {
  533. Value = value;
  534. }
  535. public int CompareTo(MyComponentData other)
  536. {
  537. return Value.CompareTo(other.Value);
  538. }
  539. }
  540. [TestCompiler]
  541. public static long TestNestedGenericsWithStaticAndSameName()
  542. {
  543. return TypeIndexCache<float>.GetValue();
  544. }
  545. private class TypeIndexCache<T>
  546. {
  547. public static long GetValue()
  548. {
  549. return InnerIndex<int>.Create<TestGenerics, T>();
  550. }
  551. }
  552. private struct InnerIndex<T>
  553. {
  554. public static long Create<T1, T2>()
  555. {
  556. var value = BurstRuntime.GetHashCode64<T1>();
  557. value *= BurstRuntime.GetHashCode64<T2>();
  558. return value;
  559. }
  560. }
  561. // Set this to no-inlining so the compiler can't fold the branch away with anything other than type deduction.
  562. [MethodImpl(MethodImplOptions.NoInlining)]
  563. private static int GenericResolutionBranchTrick<T>()
  564. {
  565. if (default(T) is null)
  566. {
  567. return 42;
  568. }
  569. else
  570. {
  571. return 13;
  572. }
  573. }
  574. [TestCompiler]
  575. public static int TestGenericResolutionBranchTrickInt()
  576. {
  577. return GenericResolutionBranchTrick<int>();
  578. }
  579. private struct SomeStruct { }
  580. [TestCompiler]
  581. public static int TestGenericResolutionBranchTrickStruct()
  582. {
  583. return GenericResolutionBranchTrick<SomeStruct>();
  584. }
  585. private class SomeClass { }
  586. [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionBoxNotSupported)]
  587. public static unsafe int TestGenericResolutionBranchTrickClass()
  588. {
  589. return GenericResolutionBranchTrick<SomeClass>();
  590. }
  591. // TODO: Burst does not yet resolve the correct method
  592. // [TestCompiler]
  593. public static int TestStructImplementingGenericInterfaceWithSourceOrderDependentResolution()
  594. {
  595. var value = new StructImplementingGenericInterfaceWithSourceOrderDependentResolution();
  596. return CallStructImplementingGenericInterfaceWithSourceOrderDependentResolutionHelper(value, 0);
  597. }
  598. private static int CallStructImplementingGenericInterfaceWithSourceOrderDependentResolutionHelper<T, U>(T value, U u)
  599. where T : IGenericInterfaceWithSourceOrderDependentResolution<U>
  600. {
  601. return value.Foo(u);
  602. }
  603. private interface IGenericInterfaceWithSourceOrderDependentResolution<T>
  604. {
  605. int Foo(int i);
  606. int Foo(T t);
  607. }
  608. private struct StructImplementingGenericInterfaceWithSourceOrderDependentResolution : IGenericInterfaceWithSourceOrderDependentResolution<int>
  609. {
  610. #pragma warning disable CS0473 // Explicit interface implementation matches more than one interface member
  611. int IGenericInterfaceWithSourceOrderDependentResolution<int>.Foo(int i) => 1;
  612. #pragma warning restore CS0473 // Explicit interface implementation matches more than one interface member
  613. public int Foo(int i) => 2;
  614. }
  615. [TestCompiler]
  616. public static int TestStructImplementingGenericInterfaceWithSourceOrderDependentResolution2()
  617. {
  618. var value = new StructImplementingGenericInterfaceWithSourceOrderDependentResolution2();
  619. return CallStructImplementingGenericInterfaceWithSourceOrderDependentResolution2Helper(value, 0);
  620. }
  621. private static int CallStructImplementingGenericInterfaceWithSourceOrderDependentResolution2Helper<T, U>(T value, U u)
  622. where T : IGenericInterfaceWithSourceOrderDependentResolution2<U>
  623. {
  624. return value.Foo(u);
  625. }
  626. private interface IGenericInterfaceWithSourceOrderDependentResolution2<T>
  627. {
  628. // Inverted order from IGenericInterfaceWithSourceOrderDependentResolution<T> above
  629. int Foo(T t);
  630. int Foo(int i);
  631. }
  632. private struct StructImplementingGenericInterfaceWithSourceOrderDependentResolution2 : IGenericInterfaceWithSourceOrderDependentResolution2<int>
  633. {
  634. #pragma warning disable CS0473 // Explicit interface implementation matches more than one interface member
  635. int IGenericInterfaceWithSourceOrderDependentResolution2<int>.Foo(int i) => 1;
  636. #pragma warning restore CS0473 // Explicit interface implementation matches more than one interface member
  637. public int Foo(int i) => 2;
  638. }
  639. [TestCompiler]
  640. #if BURST_TESTS_ONLY
  641. [TestHash]
  642. #endif
  643. public static int CallGenericStructImplementingGenericInterfaceWithOverloads()
  644. {
  645. var value = new GenericStructImplementingGenericInterfaceWithOverloads<int>();
  646. return CallGenericStructImplementingGenericInterfaceWithOverloadsHelper(value);
  647. }
  648. private static int CallGenericStructImplementingGenericInterfaceWithOverloadsHelper<T>(T value)
  649. where T : IGenericInterfaceWithOverloads<int>
  650. {
  651. return value.Foo(0u) + value.Foo(0);
  652. }
  653. private interface IGenericInterfaceWithOverloads<T>
  654. {
  655. T Foo(uint u);
  656. T Foo(int i);
  657. }
  658. private struct GenericStructImplementingGenericInterfaceWithOverloads<T> : IGenericInterfaceWithOverloads<T>
  659. {
  660. public T UIntValue;
  661. public T IntValue;
  662. public T Foo(uint u) => UIntValue;
  663. public T Foo(int i) => IntValue;
  664. }
  665. [TestCompiler]
  666. #if BURST_TESTS_ONLY
  667. [TestHash]
  668. #endif
  669. public static int CallGenericStructImplementingGenericInterfaceWithOverloads2()
  670. {
  671. var value = new GenericStructImplementingGenericInterfaceWithOverloads<int>
  672. {
  673. UIntValue = 42,
  674. IntValue = 43,
  675. };
  676. CallGenericStructImplementingGenericInterfaceWithOverloadsHelper2(value, out int result1, out int result2);
  677. return result1 + result2;
  678. }
  679. private static void CallGenericStructImplementingGenericInterfaceWithOverloadsHelper2<T, U>(T value, out U result1, out U result2)
  680. where T : IGenericInterfaceWithOverloads<U>
  681. {
  682. result1 = value.Foo(0u);
  683. result2 = value.Foo(0);
  684. }
  685. [TestCompiler]
  686. #if BURST_TESTS_ONLY
  687. [TestHash]
  688. #endif
  689. public static int CallGenericStructImplementingGenericInterfaceWithOverloadsWrapper()
  690. {
  691. var value = new GenericStructImplementingGenericInterfaceWithOverloadsWrapper<int>
  692. {
  693. UIntValue = new GenericStructImplementingGenericInterfaceWithOverloads<int>
  694. {
  695. UIntValue = 42,
  696. IntValue = 43,
  697. },
  698. IntValue = new GenericStructImplementingGenericInterfaceWithOverloads<int>
  699. {
  700. UIntValue = 44,
  701. IntValue = 45,
  702. },
  703. };
  704. return CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper(value);
  705. }
  706. private static int CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper<T>(T value)
  707. where T : IGenericInterfaceWithOverloadsWrapper<int>
  708. {
  709. return value.Bar(0u).Foo(0u)
  710. + value.Bar(0u).Foo(0)
  711. + value.Bar(0).Foo(0u)
  712. + value.Bar(0).Foo(0);
  713. }
  714. [TestCompiler]
  715. #if BURST_TESTS_ONLY
  716. [TestHash]
  717. #endif
  718. public static int CallGenericStructImplementingGenericInterfaceWithOverloadsWrapper2()
  719. {
  720. var value = new GenericStructImplementingGenericInterfaceWithOverloadsWrapper<int>();
  721. CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper2(
  722. value,
  723. out int result1,
  724. out int result2,
  725. out int result3,
  726. out int result4);
  727. return result1 + result2 + result3 + result4;
  728. }
  729. private static void CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper2<T, U>(
  730. T value,
  731. out U result1,
  732. out U result2,
  733. out U result3,
  734. out U result4)
  735. where T : IGenericInterfaceWithOverloadsWrapper<U>
  736. {
  737. result1 = value.Bar(0u).Foo(0u);
  738. result2 = value.Bar(0u).Foo(0);
  739. result3 = value.Bar(0).Foo(0u);
  740. result4 = value.Bar(0).Foo(0);
  741. }
  742. private interface IGenericInterfaceWithOverloadsWrapper<T>
  743. {
  744. GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(uint index);
  745. GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(int index);
  746. }
  747. private struct GenericStructImplementingGenericInterfaceWithOverloadsWrapper<T> : IGenericInterfaceWithOverloadsWrapper<T>
  748. {
  749. public GenericStructImplementingGenericInterfaceWithOverloads<T> UIntValue;
  750. public GenericStructImplementingGenericInterfaceWithOverloads<T> IntValue;
  751. public GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(uint index) => UIntValue;
  752. public GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(int index) => IntValue;
  753. }
  754. // TODO: Burst does not yet resolve the correct method
  755. // [TestCompiler]
  756. #if BURST_TESTS_ONLY
  757. [TestHash]
  758. #endif
  759. public static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload()
  760. {
  761. var value = new StructImplementingGenericInterfaceWithMoreSpecificOverload<int>();
  762. return CallStructImplementingGenericInterfaceWithMoreSpecificOverloadHelper(value);
  763. }
  764. private static int CallStructImplementingGenericInterfaceWithMoreSpecificOverloadHelper<T>(T value)
  765. where T : IGenericInterfaceWithMoreSpecificOverload<int>
  766. {
  767. return value.Foo(0);
  768. }
  769. private interface IGenericInterfaceWithMoreSpecificOverload<T>
  770. {
  771. int Foo(T t);
  772. int Foo(int i);
  773. }
  774. private struct StructImplementingGenericInterfaceWithMoreSpecificOverload<T> : IGenericInterfaceWithMoreSpecificOverload<T>
  775. {
  776. public int Foo(T t) => 1;
  777. public int Foo(int i) => 2;
  778. }
  779. [TestCompiler]
  780. #if BURST_TESTS_ONLY
  781. [TestHash]
  782. #endif
  783. public static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload2()
  784. {
  785. var value = new StructImplementingGenericInterfaceWithMoreSpecificOverload2();
  786. return CallStructImplementingGenericInterfaceWithMoreSpecificOverload2Helper(value);
  787. }
  788. private static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload2Helper<T>(T value)
  789. where T : IGenericInterfaceWithMoreSpecificOverload<int>
  790. {
  791. return value.Foo(0);
  792. }
  793. private struct StructImplementingGenericInterfaceWithMoreSpecificOverload2 : IGenericInterfaceWithMoreSpecificOverload<int>
  794. {
  795. public int Foo(int i) => 1;
  796. }
  797. [TestCompiler]
  798. public static int CallGenericStructImplementingGenericInterfaceWithPrivateOverload()
  799. {
  800. var value = new GenericStructImplementingGenericInterfaceWithPrivateOverload<int>();
  801. return CallGenericStructImplementingGenericInterfaceWithPrivateOverloadHelper(value);
  802. }
  803. private interface IGenericInterface<T>
  804. {
  805. T Get(int idx);
  806. }
  807. private static int CallGenericStructImplementingGenericInterfaceWithPrivateOverloadHelper<T>(T value)
  808. where T : IGenericInterface<int>
  809. {
  810. return value.Get(0);
  811. }
  812. private struct GenericStructImplementingGenericInterfaceWithPrivateOverload<T> : IGenericInterface<T>
  813. {
  814. private int Get(T idx) => 42;
  815. public T Get(int idx) => default;
  816. }
  817. [TestCompiler]
  818. public static int CallGenericStructImplementingGenericInterfaceDerived()
  819. {
  820. var value = new GenericStructImplementingGenericInterfaceDerived<int>();
  821. return CallGenericStructImplementingGenericInterfaceDerivedHelper(value);
  822. }
  823. private static int CallGenericStructImplementingGenericInterfaceDerivedHelper<T>(T value)
  824. where T : IGenericInterfaceDerived<int, int>
  825. {
  826. return value.Foo(0);
  827. }
  828. private interface IGenericInterfaceBase<T>
  829. {
  830. int Foo(T t);
  831. int Foo(double d);
  832. }
  833. private interface IGenericInterfaceDerived<T, U> : IGenericInterfaceBase<T>
  834. {
  835. int Foo(U u);
  836. }
  837. private struct GenericStructImplementingGenericInterfaceDerived<T> : IGenericInterfaceDerived<T, T>
  838. {
  839. public int Foo(T u) => 1;
  840. public int Foo(double d) => (int)d;
  841. }
  842. [TestCompiler]
  843. #if BURST_TESTS_ONLY
  844. [TestHash]
  845. #endif
  846. public static int CallBaseInterfaceMethodOnGenericStruct()
  847. {
  848. var value = new GenericStructImplementingGenericInterfaceDerived<int>();
  849. return CallBaseInterfaceMethodOnGenericStructHelper(value);
  850. }
  851. private static int CallBaseInterfaceMethodOnGenericStructHelper<T>(T value)
  852. where T : IGenericInterfaceBase<int>
  853. {
  854. return value.Foo(0);
  855. }
  856. // TODO: Burst does not yet resolve the correct method
  857. // [TestCompiler]
  858. public static int CallGenericStructImplementingGenericInterfaceDerived2()
  859. {
  860. var value = new GenericStructImplementingGenericInterfaceDerived2<int>();
  861. return CallGenericStructImplementingGenericInterfaceDerived2Helper<GenericStructImplementingGenericInterfaceDerived2<int>, int>(value);
  862. }
  863. private static int CallGenericStructImplementingGenericInterfaceDerived2Helper<T, U>(T value)
  864. where T : IGenericInterfaceDerived<U, U>
  865. {
  866. return value.Foo(default);
  867. }
  868. private struct GenericStructImplementingGenericInterfaceDerived2<T> : IGenericInterfaceDerived<T, T>
  869. {
  870. int IGenericInterfaceBase<T>.Foo(T t) => 2;
  871. int IGenericInterfaceBase<T>.Foo(double d) => (int)d;
  872. public int Foo(T u) => 1;
  873. }
  874. [TestCompiler]
  875. #if BURST_TESTS_ONLY
  876. [TestHash]
  877. #endif
  878. public static int CallGetHashCodeViaInterface()
  879. {
  880. return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct { Value = 42 });
  881. }
  882. public static int CallGetHashCodeViaInterfaceHelper<T>(T value)
  883. {
  884. return value.GetHashCode();
  885. }
  886. public struct CallGetHashCodeViaInterfaceStruct
  887. {
  888. public int Value;
  889. public override int GetHashCode() => Value.GetHashCode();
  890. public int GetHashCode(int x) => x;
  891. }
  892. [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_UnableToAccessManagedMethod)]
  893. #if BURST_TESTS_ONLY
  894. [TestHash]
  895. #endif
  896. public static int CallGetHashCodeViaInterface2()
  897. {
  898. return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct2 { Value = 42 });
  899. }
  900. public struct CallGetHashCodeViaInterfaceStruct2
  901. {
  902. public int Value;
  903. // This struct doesn't override GetHashCode, so a Burst compiler error is expected.
  904. // (but hashing should still succeed regardless).
  905. public int GetHashCode(int x) => x;
  906. public double GetHashCode(double d) => d;
  907. }
  908. [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_UnableToAccessManagedMethod)]
  909. #if BURST_TESTS_ONLY
  910. [TestHash]
  911. #endif
  912. public static int CallGetHashCodeViaInterface3()
  913. {
  914. return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct3 { Value = 42 });
  915. }
  916. public struct CallGetHashCodeViaInterfaceStruct3
  917. {
  918. public int Value;
  919. // This struct doesn't override GetHashCode and has no other methods with that name.
  920. }
  921. #if NET7_0
  922. private interface IDefault
  923. {
  924. int A();
  925. int B() => 42;
  926. }
  927. private interface IDefaultSelfCall
  928. {
  929. int A();
  930. int B() => A() + 1;
  931. }
  932. private interface IDefaultGeneric<T>
  933. {
  934. public T A();
  935. public (U, T) B<U>() => (default, A());
  936. }
  937. private struct DefaultBasic : IDefault
  938. {
  939. public int A() => 43;
  940. }
  941. private struct DefaultImpl : IDefault
  942. {
  943. public int A() => 43;
  944. public int B() => 3;
  945. }
  946. private struct SelfCallDefault : IDefaultSelfCall
  947. {
  948. public int A() => 10;
  949. }
  950. private struct SelfCallImpl : IDefaultSelfCall
  951. {
  952. public int A() => 99;
  953. public int B() => A() * 3;
  954. }
  955. private struct DefaultGenericBasic: IDefaultGeneric<int>
  956. {
  957. public int A() => 10;
  958. }
  959. private struct DefaultGenericImpl: IDefaultGeneric<int>
  960. {
  961. public int A() => 10;
  962. (U, int) IDefaultGeneric<int>.B<U>() => (default, 3);
  963. }
  964. private struct DefaultVeryGenericBasic<T>: IDefaultGeneric<T>
  965. {
  966. public T A() => default;
  967. }
  968. private struct DefaultVeryGenericImpl<T>: IDefaultGeneric<T>
  969. {
  970. public T A() => default;
  971. (U, T) IDefaultGeneric<T>.B<U>() => (default, default);
  972. }
  973. private interface IBumper
  974. {
  975. void Bump();
  976. }
  977. private struct SelfMutator : IDefaultSelfCall, IBumper
  978. {
  979. public int X;
  980. public void Bump()
  981. {
  982. X = (X << 1) | 1;
  983. }
  984. public int A()
  985. {
  986. var x = X;
  987. Bump();
  988. return x;
  989. }
  990. }
  991. [TestCompiler]
  992. #if BURST_TESTS_ONLY
  993. [TestHash]
  994. #endif
  995. public static int TestDefaultInterfaceMethod()
  996. {
  997. return UseDefaultInterfaceMethodsHelper(new DefaultBasic());
  998. }
  999. [TestCompiler]
  1000. #if BURST_TESTS_ONLY
  1001. [TestHash]
  1002. #endif
  1003. public static int TestImplementedDefaultInterfaceMethod()
  1004. {
  1005. return UseDefaultInterfaceMethodsHelper(new DefaultImpl());
  1006. }
  1007. private static int UseDefaultInterfaceMethodsHelper<T>(T t)
  1008. where T: IDefault
  1009. {
  1010. return t.B();
  1011. }
  1012. [TestCompiler]
  1013. #if BURST_TESTS_ONLY
  1014. [TestHash]
  1015. #endif
  1016. public static int TestSelfCallingDefaultInterfaceMethod()
  1017. {
  1018. return UseSelfCallingDefaultInterfaceMethod(new SelfCallDefault(), new SelfCallImpl());
  1019. }
  1020. private static int UseSelfCallingDefaultInterfaceMethod<T, U>(T t, U u)
  1021. where T : IDefaultSelfCall
  1022. where U : IDefaultSelfCall
  1023. {
  1024. return t.B() + u.B();
  1025. }
  1026. [TestCompiler]
  1027. #if BURST_TESTS_ONLY
  1028. [TestHash]
  1029. #endif
  1030. public static int TestGenericDefaultInterfaceMethod()
  1031. {
  1032. return UseGenericDefaultInterfaceMethod(new DefaultGenericBasic(), new DefaultGenericImpl());
  1033. }
  1034. private static int UseGenericDefaultInterfaceMethod<T, U>(T t, U u)
  1035. where T : IDefaultGeneric<int>
  1036. where U : IDefaultGeneric<int>
  1037. {
  1038. var (x, y) = t.B<int>();
  1039. var (z, w) = u.B<int>();
  1040. return (x + y) * (z + w);
  1041. }
  1042. [TestCompiler]
  1043. #if BURST_TESTS_ONLY
  1044. [TestHash]
  1045. #endif
  1046. public static int TestVeryGenericDefaultInterfaceMethod()
  1047. {
  1048. var ((x, y), (z, w)) = UseVeryGenericDefaultInterfaceMethod<DefaultVeryGenericBasic<int>, DefaultVeryGenericImpl<int>, int, int, long>(new DefaultVeryGenericBasic<int>(), new DefaultVeryGenericImpl<int>());
  1049. return (int)(x + y + z + w);
  1050. }
  1051. private static ((W, V), (X, V)) UseVeryGenericDefaultInterfaceMethod<T, U, V, W, X>(T t, U u)
  1052. where T : IDefaultGeneric<V>
  1053. where U : IDefaultGeneric<V>
  1054. {
  1055. return (t.B<W>(), u.B<X>());
  1056. }
  1057. private static int UseSelfMutator<T>(ref T x) where T : IDefaultSelfCall, IBumper
  1058. {
  1059. x.Bump();
  1060. var r = x.B();
  1061. x.Bump();
  1062. return r;
  1063. }
  1064. [TestCompiler]
  1065. #if BURST_TESTS_ONLY
  1066. [TestHash]
  1067. #endif
  1068. public static int TestSelfMutator()
  1069. {
  1070. var x = new SelfMutator();
  1071. x.Bump();
  1072. var ret = UseSelfMutator(ref x);
  1073. x.Bump();
  1074. return (x.X << 16) | ret;
  1075. }
  1076. #endif
  1077. }
  1078. }