暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

051-TestGenerics.cs 35KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  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. // These tests require 2020.2 because that enabled C# 8.0.
  562. #if BURST_INTERNAL || UNITY_2020_2_OR_NEWER
  563. // Set this to no-inlining so the compiler can't fold the branch away with anything other than type deduction.
  564. [MethodImpl(MethodImplOptions.NoInlining)]
  565. private static int GenericResolutionBranchTrick<T>()
  566. {
  567. if (default(T) is null)
  568. {
  569. return 42;
  570. }
  571. else
  572. {
  573. return 13;
  574. }
  575. }
  576. [TestCompiler]
  577. public static int TestGenericResolutionBranchTrickInt()
  578. {
  579. return GenericResolutionBranchTrick<int>();
  580. }
  581. private struct SomeStruct { }
  582. [TestCompiler]
  583. public static int TestGenericResolutionBranchTrickStruct()
  584. {
  585. return GenericResolutionBranchTrick<SomeStruct>();
  586. }
  587. private class SomeClass { }
  588. [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionBoxNotSupported)]
  589. public static unsafe int TestGenericResolutionBranchTrickClass()
  590. {
  591. return GenericResolutionBranchTrick<SomeClass>();
  592. }
  593. #endif
  594. // TODO: Burst does not yet resolve the correct method
  595. // [TestCompiler]
  596. #if BURST_TESTS_ONLY
  597. [TestHash]
  598. #endif
  599. public static int TestStructImplementingGenericInterfaceWithSourceOrderDependentResolution()
  600. {
  601. var value = new StructImplementingGenericInterfaceWithSourceOrderDependentResolution();
  602. return CallStructImplementingGenericInterfaceWithSourceOrderDependentResolutionHelper(value, 0);
  603. }
  604. private static int CallStructImplementingGenericInterfaceWithSourceOrderDependentResolutionHelper<T, U>(T value, U u)
  605. where T : IGenericInterfaceWithSourceOrderDependentResolution<U>
  606. {
  607. return value.Foo(u);
  608. }
  609. private interface IGenericInterfaceWithSourceOrderDependentResolution<T>
  610. {
  611. int Foo(int i);
  612. int Foo(T t);
  613. }
  614. private struct StructImplementingGenericInterfaceWithSourceOrderDependentResolution : IGenericInterfaceWithSourceOrderDependentResolution<int>
  615. {
  616. #pragma warning disable CS0473 // Explicit interface implementation matches more than one interface member
  617. int IGenericInterfaceWithSourceOrderDependentResolution<int>.Foo(int i) => 1;
  618. #pragma warning restore CS0473 // Explicit interface implementation matches more than one interface member
  619. public int Foo(int i) => 2;
  620. }
  621. [TestCompiler]
  622. #if BURST_TESTS_ONLY
  623. [TestHash]
  624. #endif
  625. public static int TestStructImplementingGenericInterfaceWithSourceOrderDependentResolution2()
  626. {
  627. var value = new StructImplementingGenericInterfaceWithSourceOrderDependentResolution2();
  628. return CallStructImplementingGenericInterfaceWithSourceOrderDependentResolution2Helper(value, 0);
  629. }
  630. private static int CallStructImplementingGenericInterfaceWithSourceOrderDependentResolution2Helper<T, U>(T value, U u)
  631. where T : IGenericInterfaceWithSourceOrderDependentResolution2<U>
  632. {
  633. return value.Foo(u);
  634. }
  635. private interface IGenericInterfaceWithSourceOrderDependentResolution2<T>
  636. {
  637. // Inverted order from IGenericInterfaceWithSourceOrderDependentResolution<T> above
  638. int Foo(T t);
  639. int Foo(int i);
  640. }
  641. private struct StructImplementingGenericInterfaceWithSourceOrderDependentResolution2 : IGenericInterfaceWithSourceOrderDependentResolution2<int>
  642. {
  643. #pragma warning disable CS0473 // Explicit interface implementation matches more than one interface member
  644. int IGenericInterfaceWithSourceOrderDependentResolution2<int>.Foo(int i) => 1;
  645. #pragma warning restore CS0473 // Explicit interface implementation matches more than one interface member
  646. public int Foo(int i) => 2;
  647. }
  648. [TestCompiler]
  649. #if BURST_TESTS_ONLY
  650. [TestHash]
  651. #endif
  652. public static int CallGenericStructImplementingGenericInterfaceWithOverloads()
  653. {
  654. var value = new GenericStructImplementingGenericInterfaceWithOverloads<int>();
  655. return CallGenericStructImplementingGenericInterfaceWithOverloadsHelper(value);
  656. }
  657. private static int CallGenericStructImplementingGenericInterfaceWithOverloadsHelper<T>(T value)
  658. where T : IGenericInterfaceWithOverloads<int>
  659. {
  660. return value.Foo(0u) + value.Foo(0);
  661. }
  662. private interface IGenericInterfaceWithOverloads<T>
  663. {
  664. T Foo(uint u);
  665. T Foo(int i);
  666. }
  667. private struct GenericStructImplementingGenericInterfaceWithOverloads<T> : IGenericInterfaceWithOverloads<T>
  668. {
  669. public T UIntValue;
  670. public T IntValue;
  671. public T Foo(uint u) => UIntValue;
  672. public T Foo(int i) => IntValue;
  673. }
  674. [TestCompiler]
  675. #if BURST_TESTS_ONLY
  676. [TestHash]
  677. #endif
  678. public static int CallGenericStructImplementingGenericInterfaceWithOverloads2()
  679. {
  680. var value = new GenericStructImplementingGenericInterfaceWithOverloads<int>
  681. {
  682. UIntValue = 42,
  683. IntValue = 43,
  684. };
  685. CallGenericStructImplementingGenericInterfaceWithOverloadsHelper2(value, out int result1, out int result2);
  686. return result1 + result2;
  687. }
  688. private static void CallGenericStructImplementingGenericInterfaceWithOverloadsHelper2<T, U>(T value, out U result1, out U result2)
  689. where T : IGenericInterfaceWithOverloads<U>
  690. {
  691. result1 = value.Foo(0u);
  692. result2 = value.Foo(0);
  693. }
  694. [TestCompiler]
  695. #if BURST_TESTS_ONLY
  696. [TestHash]
  697. #endif
  698. public static int CallGenericStructImplementingGenericInterfaceWithOverloadsWrapper()
  699. {
  700. var value = new GenericStructImplementingGenericInterfaceWithOverloadsWrapper<int>
  701. {
  702. UIntValue = new GenericStructImplementingGenericInterfaceWithOverloads<int>
  703. {
  704. UIntValue = 42,
  705. IntValue = 43,
  706. },
  707. IntValue = new GenericStructImplementingGenericInterfaceWithOverloads<int>
  708. {
  709. UIntValue = 44,
  710. IntValue = 45,
  711. },
  712. };
  713. return CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper(value);
  714. }
  715. private static int CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper<T>(T value)
  716. where T : IGenericInterfaceWithOverloadsWrapper<int>
  717. {
  718. return value.Bar(0u).Foo(0u)
  719. + value.Bar(0u).Foo(0)
  720. + value.Bar(0).Foo(0u)
  721. + value.Bar(0).Foo(0);
  722. }
  723. [TestCompiler]
  724. #if BURST_TESTS_ONLY
  725. [TestHash]
  726. #endif
  727. public static int CallGenericStructImplementingGenericInterfaceWithOverloadsWrapper2()
  728. {
  729. var value = new GenericStructImplementingGenericInterfaceWithOverloadsWrapper<int>();
  730. CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper2(
  731. value,
  732. out int result1,
  733. out int result2,
  734. out int result3,
  735. out int result4);
  736. return result1 + result2 + result3 + result4;
  737. }
  738. private static void CallGenericStructImplementingGenericInterfaceWithOverloadsHelperWrapper2<T, U>(
  739. T value,
  740. out U result1,
  741. out U result2,
  742. out U result3,
  743. out U result4)
  744. where T : IGenericInterfaceWithOverloadsWrapper<U>
  745. {
  746. result1 = value.Bar(0u).Foo(0u);
  747. result2 = value.Bar(0u).Foo(0);
  748. result3 = value.Bar(0).Foo(0u);
  749. result4 = value.Bar(0).Foo(0);
  750. }
  751. private interface IGenericInterfaceWithOverloadsWrapper<T>
  752. {
  753. GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(uint index);
  754. GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(int index);
  755. }
  756. private struct GenericStructImplementingGenericInterfaceWithOverloadsWrapper<T> : IGenericInterfaceWithOverloadsWrapper<T>
  757. {
  758. public GenericStructImplementingGenericInterfaceWithOverloads<T> UIntValue;
  759. public GenericStructImplementingGenericInterfaceWithOverloads<T> IntValue;
  760. public GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(uint index) => UIntValue;
  761. public GenericStructImplementingGenericInterfaceWithOverloads<T> Bar(int index) => IntValue;
  762. }
  763. // TODO: Burst does not yet resolve the correct method
  764. // [TestCompiler]
  765. #if BURST_TESTS_ONLY
  766. [TestHash]
  767. #endif
  768. public static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload()
  769. {
  770. var value = new StructImplementingGenericInterfaceWithMoreSpecificOverload<int>();
  771. return CallStructImplementingGenericInterfaceWithMoreSpecificOverloadHelper(value);
  772. }
  773. private static int CallStructImplementingGenericInterfaceWithMoreSpecificOverloadHelper<T>(T value)
  774. where T : IGenericInterfaceWithMoreSpecificOverload<int>
  775. {
  776. return value.Foo(0);
  777. }
  778. private interface IGenericInterfaceWithMoreSpecificOverload<T>
  779. {
  780. int Foo(T t);
  781. int Foo(int i);
  782. }
  783. private struct StructImplementingGenericInterfaceWithMoreSpecificOverload<T> : IGenericInterfaceWithMoreSpecificOverload<T>
  784. {
  785. public int Foo(T t) => 1;
  786. public int Foo(int i) => 2;
  787. }
  788. [TestCompiler]
  789. #if BURST_TESTS_ONLY
  790. [TestHash]
  791. #endif
  792. public static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload2()
  793. {
  794. var value = new StructImplementingGenericInterfaceWithMoreSpecificOverload2();
  795. return CallStructImplementingGenericInterfaceWithMoreSpecificOverload2Helper(value);
  796. }
  797. private static int CallStructImplementingGenericInterfaceWithMoreSpecificOverload2Helper<T>(T value)
  798. where T : IGenericInterfaceWithMoreSpecificOverload<int>
  799. {
  800. return value.Foo(0);
  801. }
  802. private struct StructImplementingGenericInterfaceWithMoreSpecificOverload2 : IGenericInterfaceWithMoreSpecificOverload<int>
  803. {
  804. public int Foo(int i) => 1;
  805. }
  806. [TestCompiler]
  807. #if BURST_TESTS_ONLY
  808. [TestHash]
  809. #endif
  810. public static int CallGenericStructImplementingGenericInterfaceWithPrivateOverload()
  811. {
  812. var value = new GenericStructImplementingGenericInterfaceWithPrivateOverload<int>();
  813. return CallGenericStructImplementingGenericInterfaceWithPrivateOverloadHelper(value);
  814. }
  815. private interface IGenericInterface<T>
  816. {
  817. T Get(int idx);
  818. }
  819. private static int CallGenericStructImplementingGenericInterfaceWithPrivateOverloadHelper<T>(T value)
  820. where T : IGenericInterface<int>
  821. {
  822. return value.Get(0);
  823. }
  824. private struct GenericStructImplementingGenericInterfaceWithPrivateOverload<T> : IGenericInterface<T>
  825. {
  826. private int Get(T idx) => 42;
  827. public T Get(int idx) => default;
  828. }
  829. [TestCompiler]
  830. #if BURST_TESTS_ONLY
  831. [TestHash]
  832. #endif
  833. public static int CallGenericStructImplementingGenericInterfaceDerived()
  834. {
  835. var value = new GenericStructImplementingGenericInterfaceDerived<int>();
  836. return CallGenericStructImplementingGenericInterfaceDerivedHelper(value);
  837. }
  838. private static int CallGenericStructImplementingGenericInterfaceDerivedHelper<T>(T value)
  839. where T : IGenericInterfaceDerived<int, int>
  840. {
  841. return value.Foo(0);
  842. }
  843. private interface IGenericInterfaceBase<T>
  844. {
  845. int Foo(T t);
  846. int Foo(double d);
  847. }
  848. private interface IGenericInterfaceDerived<T, U> : IGenericInterfaceBase<T>
  849. {
  850. int Foo(U u);
  851. }
  852. private struct GenericStructImplementingGenericInterfaceDerived<T> : IGenericInterfaceDerived<T, T>
  853. {
  854. public int Foo(T u) => 1;
  855. public int Foo(double d) => (int)d;
  856. }
  857. [TestCompiler]
  858. #if BURST_TESTS_ONLY
  859. [TestHash]
  860. #endif
  861. public static int CallBaseInterfaceMethodOnGenericStruct()
  862. {
  863. var value = new GenericStructImplementingGenericInterfaceDerived<int>();
  864. return CallBaseInterfaceMethodOnGenericStructHelper(value);
  865. }
  866. private static int CallBaseInterfaceMethodOnGenericStructHelper<T>(T value)
  867. where T : IGenericInterfaceBase<int>
  868. {
  869. return value.Foo(0);
  870. }
  871. // TODO: Burst does not yet resolve the correct method
  872. // [TestCompiler]
  873. #if BURST_TESTS_ONLY
  874. [TestHash]
  875. #endif
  876. public static int CallGenericStructImplementingGenericInterfaceDerived2()
  877. {
  878. var value = new GenericStructImplementingGenericInterfaceDerived2<int>();
  879. return CallGenericStructImplementingGenericInterfaceDerived2Helper<GenericStructImplementingGenericInterfaceDerived2<int>, int>(value);
  880. }
  881. private static int CallGenericStructImplementingGenericInterfaceDerived2Helper<T, U>(T value)
  882. where T : IGenericInterfaceDerived<U, U>
  883. {
  884. return value.Foo(default);
  885. }
  886. private struct GenericStructImplementingGenericInterfaceDerived2<T> : IGenericInterfaceDerived<T, T>
  887. {
  888. int IGenericInterfaceBase<T>.Foo(T t) => 2;
  889. int IGenericInterfaceBase<T>.Foo(double d) => (int)d;
  890. public int Foo(T u) => 1;
  891. }
  892. [TestCompiler]
  893. #if BURST_TESTS_ONLY
  894. [TestHash]
  895. #endif
  896. public static int CallGetHashCodeViaInterface()
  897. {
  898. return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct { Value = 42 });
  899. }
  900. public static int CallGetHashCodeViaInterfaceHelper<T>(T value)
  901. {
  902. return value.GetHashCode();
  903. }
  904. public struct CallGetHashCodeViaInterfaceStruct
  905. {
  906. public int Value;
  907. public override int GetHashCode() => Value.GetHashCode();
  908. public int GetHashCode(int x) => x;
  909. }
  910. [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_UnableToAccessManagedMethod)]
  911. #if BURST_TESTS_ONLY
  912. [TestHash]
  913. #endif
  914. public static int CallGetHashCodeViaInterface2()
  915. {
  916. return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct2 { Value = 42 });
  917. }
  918. public struct CallGetHashCodeViaInterfaceStruct2
  919. {
  920. public int Value;
  921. // This struct doesn't override GetHashCode, so a Burst compiler error is expected.
  922. // (but hashing should still succeed regardless).
  923. public int GetHashCode(int x) => x;
  924. public double GetHashCode(double d) => d;
  925. }
  926. [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_UnableToAccessManagedMethod)]
  927. #if BURST_TESTS_ONLY
  928. [TestHash]
  929. #endif
  930. public static int CallGetHashCodeViaInterface3()
  931. {
  932. return CallGetHashCodeViaInterfaceHelper(new CallGetHashCodeViaInterfaceStruct3 { Value = 42 });
  933. }
  934. public struct CallGetHashCodeViaInterfaceStruct3
  935. {
  936. public int Value;
  937. // This struct doesn't override GetHashCode and has no other methods with that name.
  938. }
  939. }
  940. }