tstatictypes.nim 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. discard """
  2. nimoutFull: true
  3. nimout: '''
  4. staticAlialProc instantiated with 358
  5. staticAlialProc instantiated with 368
  6. 0: Foo
  7. 1: Bar
  8. 0: Foo
  9. 1: Bar
  10. 0: Foo
  11. 1: Bar
  12. 0: Foo
  13. 1: Bar
  14. '''
  15. output: '''
  16. 16
  17. 16
  18. b is 2 times a
  19. 17
  20. ['\x00', '\x00', '\x00', '\x00']
  21. heyho
  22. Val1
  23. Val1
  24. '''
  25. matrix: "--hints:off --mm:orc; --hints:off --mm:refc"
  26. """
  27. import macros
  28. template ok(x) = doAssert(x)
  29. template no(x) = doAssert(not x)
  30. template accept(x) =
  31. static: doAssert(compiles(x))
  32. template reject(x) =
  33. static: doAssert(not compiles(x))
  34. proc plus(a, b: int): int = a + b
  35. template isStatic(x: static): bool = true
  36. template isStatic(x: auto): bool = false
  37. var v = 1
  38. when true:
  39. # test that `isStatic` works as expected
  40. const C = 2
  41. static:
  42. ok C.isStatic
  43. ok isStatic(plus(1, 2))
  44. ok plus(C, 2).isStatic
  45. no isStatic(v)
  46. no plus(1, v).isStatic
  47. when true:
  48. # test that proc instantiation works as expected
  49. type
  50. StaticTypeAlias = static[int]
  51. proc staticAliasProc(a: StaticTypeAlias,
  52. b: static[int],
  53. c: static int) =
  54. static:
  55. doAssert a.isStatic and b.isStatic and c.isStatic
  56. doAssert isStatic(a + plus(b, c))
  57. echo "staticAlialProc instantiated with ", a, b, c
  58. when b mod a == 0:
  59. echo "b is ", b div a, " times a"
  60. echo a + b + c
  61. staticAliasProc 1+2, 5, 8
  62. staticAliasProc 3, 2+3, 9-1
  63. staticAliasProc 3, 3+3, 4+4
  64. when true:
  65. # test static coercions. normal cases that should work:
  66. accept:
  67. var s1 = static[int] plus(1, 2)
  68. var s2 = static(plus(1,2))
  69. var s3 = static plus(1,2)
  70. var s4 = static[SomeInteger](1 + 2)
  71. # the sub-script operator can be used only with types:
  72. reject:
  73. var just_static3 = static[plus(1,2)]
  74. # static coercion takes into account the type:
  75. reject:
  76. var x = static[string](plus(1, 2))
  77. reject:
  78. var x = static[string] plus(1, 2)
  79. reject:
  80. var x = static[SomeFloat] plus(3, 4)
  81. # you cannot coerce a run-time variable
  82. reject:
  83. var x = static(v)
  84. block: # issue #13730
  85. type Foo[T: static[float]] = object
  86. doAssert Foo[0.0] is Foo[-0.0]
  87. when true:
  88. type
  89. ArrayWrapper1[S: static int] = object
  90. data: array[S + 1, int]
  91. ArrayWrapper2[S: static[int]] = object
  92. data: array[S.plus(2), int]
  93. ArrayWrapper3[S: static[(int, string)]] = object
  94. data: array[S[0], int]
  95. var aw1: ArrayWrapper1[5]
  96. var aw2: ArrayWrapper2[5]
  97. var aw3: ArrayWrapper3[(10, "str")]
  98. static:
  99. doAssert aw1.data.high == 5
  100. doAssert aw2.data.high == 6
  101. doAssert aw3.data.high == 9
  102. # #6077
  103. block:
  104. type
  105. Backend = enum
  106. Cpu
  107. Tensor[B: static[Backend]; T] = object
  108. BackProp[B: static[Backend],T] = proc (gradient: Tensor[B,T]): Tensor[B,T]
  109. # https://github.com/nim-lang/Nim/issues/10073
  110. block:
  111. proc foo[N: static int](x: var int,
  112. y: int,
  113. z: static int,
  114. arr: array[N, int]): auto =
  115. var t1 = (a: x, b: y, c: z, d: N)
  116. var t2 = (x, y, z, N)
  117. doAssert t1 == t2
  118. result = t1
  119. var y = 20
  120. var x = foo(y, 10, 15, [1, 2, 3])
  121. doAssert x == (20, 10, 15, 3)
  122. # #7609
  123. block:
  124. type
  125. Coord[N: static[int]] = tuple[col, row: range[0'i8 .. (N.int8-1)]]
  126. Point[N: static[int]] = range[0'i16 .. N.int16 * N.int16 - 1]
  127. # https://github.com/nim-lang/Nim/issues/10339
  128. block:
  129. type
  130. MicroKernel = object
  131. a: float
  132. b: int
  133. macro extractA(ukernel: static MicroKernel): untyped =
  134. result = newLit ukernel.a
  135. proc tFunc[ukernel: static MicroKernel]() =
  136. const x = ukernel.extractA
  137. doAssert x == 5.5
  138. const uk = MicroKernel(a: 5.5, b: 1)
  139. tFunc[uk]()
  140. # bug #7258
  141. type
  142. StringValue*[LEN: static[Natural]] = array[LEN+Natural(2),char]
  143. StringValue16* = StringValue[2]
  144. var
  145. s: StringValue16
  146. echo s
  147. block: #13529
  148. block:
  149. type Foo[T: static type] = object
  150. var foo: Foo["test"]
  151. doAssert $foo == "()"
  152. doAssert foo.T is string
  153. static: doAssert foo.T == "test"
  154. doAssert not compiles(
  155. block:
  156. type Foo2[T: static type] = object
  157. x: T)
  158. block:
  159. type Foo[T: static[float]] = object
  160. var foo: Foo[1.2]
  161. doAssert $foo == "()"
  162. doAssert foo.T == 1.2
  163. block: # routines also work
  164. proc fun(a: static) = (const a2 = a)
  165. fun(1)
  166. fun(1.2)
  167. block: # routines also work
  168. proc fun(a: static type) = (const a2 = a)
  169. fun(1)
  170. fun(1.2)
  171. block: # this also works
  172. proc fun[T](a: static[T]) = (const a2 = a)
  173. fun(1)
  174. fun(1.2)
  175. block: # #12713
  176. block:
  177. type Cell = object
  178. c: int
  179. proc test(c: static string) = discard #Remove this and it compiles
  180. proc test(c: Cell) = discard
  181. test Cell(c: 0)
  182. block:
  183. type Cell = object
  184. c: int
  185. proc test(c: static string) = discard #Remove this and it compiles
  186. proc test(c: Cell) = discard
  187. test Cell()
  188. block: # issue #14802
  189. template fn(s: typed): untyped =
  190. proc bar() = discard
  191. 12
  192. const myConst = static(fn(1))
  193. doAssert myConst == 12
  194. # bug #12571
  195. type
  196. T[K: static bool] = object of RootObj
  197. when K == true:
  198. foo: string
  199. else:
  200. bar: string
  201. U[K: static bool] = object of T[K]
  202. let t = T[true](foo: "hey")
  203. let u = U[false](bar: "ho")
  204. echo t.foo, u.bar
  205. #------------------------------------------------------------------------------
  206. # issue #9679
  207. type
  208. Foo*[T] = object
  209. bar*: int
  210. dummy: T
  211. proc initFoo(T: type, bar: int): Foo[T] =
  212. result.bar = 1
  213. proc fails[T](x: static Foo[T]) = # Change to non-static and it compiles
  214. doAssert($x == "(bar: 1, dummy: 0)")
  215. block:
  216. const foo = initFoo(int, 2)
  217. fails(foo)
  218. import tables
  219. var foo{.compileTime.} = [
  220. "Foo",
  221. "Bar"
  222. ]
  223. var bar{.compileTime.} = {
  224. 0: "Foo",
  225. 1: "Bar"
  226. }.toTable()
  227. macro fooM(): untyped =
  228. for i, val in foo:
  229. echo i, ": ", val
  230. macro barM(): untyped =
  231. for i, val in bar:
  232. echo i, ": ", val
  233. macro fooParam(x: static array[2, string]): untyped =
  234. for i, val in x:
  235. echo i, ": ", val
  236. macro barParam(x: static Table[int, string]): untyped =
  237. let barParamInsides = proc(i: int, val: string): NimNode =
  238. echo i, ": ", val
  239. for i, val in x:
  240. discard barParamInsides(i, val)
  241. fooM()
  242. barM()
  243. fooParam(foo)
  244. barParam(bar)
  245. #-----------------------------------------------------------------------------------------
  246. # issue #7546
  247. type
  248. rangeB[N: static[int16]] = range[0'i16 .. N]
  249. setB[N: static[int16]] = set[rangeB[N]]
  250. block:
  251. var s : setB[14'i16]
  252. #-----------------------------------------------------------------------------------------
  253. # issue #9520
  254. type
  255. MyEnum = enum
  256. Val1, Val2
  257. proc myproc(a: static[MyEnum], b: int) =
  258. if b < 0:
  259. myproc(a, -b)
  260. echo $a
  261. myproc(Val1, -10)
  262. #------------------------------------------------------------------------------------------
  263. # issue #6177
  264. type
  265. G[N,M:static[int], T] = object
  266. o: T
  267. proc newG[N,M:static[int],T](x:var G[N,M,T], y:T) =
  268. x.o = y+10*N+100*M
  269. proc newG[N,M:static[int],T](x:T):G[N,M,T] = result.newG(x)
  270. var x:G[2,3,int]
  271. x.newG(4)
  272. var y = newG[2,3,int](4)
  273. #------------------------------------------------------------------------------------------
  274. # issue #12897
  275. type
  276. TileCT[n: static int] = object
  277. a: array[n, int]
  278. Tile = TileCT #Commenting this out to make it work
  279. #------------------------------------------------------------------------------------------
  280. # issue #15858
  281. proc fn(N1: static int, N2: static int, T: typedesc): array[N1 * N2, T] =
  282. doAssert(len(result) == N1 * N2)
  283. let yy = fn(5, 10, float)
  284. block:
  285. block:
  286. type Foo[N: static int] = array[cint(0) .. cint(N), float]
  287. type T = Foo[3]
  288. block:
  289. type Foo[N: static int] = array[int32(0) .. int32(N), float]
  290. type T = Foo[3]
  291. #------------------------------------------------------------------------------------------
  292. # static proc/lambda param
  293. func isSorted2[T](a: openArray[T], cmp: static proc(x, y: T): bool {.inline.}): bool =
  294. result = true
  295. for i in 0..<len(a)-1:
  296. if not cmp(a[i], a[i+1]):
  297. return false
  298. proc compare(a, b: int): bool {.inline.} = a < b
  299. var sorted = newSeq[int](1000)
  300. for i in 0..<sorted.len: sorted[i] = i*2
  301. doAssert isSorted2(sorted, compare)
  302. doAssert isSorted2(sorted, proc (a, b: int): bool {.inline.} = a < b)
  303. block: # Ensure static descriminated objects compile
  304. type
  305. ObjKind = enum
  306. KindA, KindB, KindC
  307. MyObject[kind: static[ObjKind]] = object of RootObj
  308. myNumber: int
  309. when kind != KindA:
  310. driverType: int
  311. otherField: int
  312. elif kind == KindC:
  313. driverType: uint
  314. otherField: int
  315. var instance: MyObject[KindA]
  316. discard instance
  317. discard MyObject[KindC]()
  318. block: # more cases of above, issue #8446
  319. type
  320. Color = enum
  321. red, green, blue
  322. Blah[color: static[Color]] = object
  323. when color == red:
  324. a: string
  325. else:
  326. b: int
  327. proc foo(blah: Blah) = discard
  328. foo(Blah[red](a: "abc"))
  329. type
  330. Mytype[K: static[int]] = object
  331. when K < 16:
  332. data: uint8
  333. else:
  334. data: uint64
  335. proc usingMyt(k: Mytype) = discard # triggers Error: cannot generate code for: K
  336. block: # bug #22600
  337. proc f(n: static int): int = n * 2 # same for template
  338. type
  339. a[N: static int] = object
  340. field : array[N, uint8]
  341. b[N: static int] = object
  342. field : a[N]
  343. c[N: static int] = object
  344. f0 : a[N ] # works
  345. f1 : a[N + 1 ] # asserts
  346. f2 : a[f(N) ] # asserts
  347. f3 : b[N ] # works
  348. f4 : b[N + 1 ] # asserts
  349. f5 : b[f(N) ] # asserts
  350. proc init[N: static int](x : var a[N]) = discard
  351. proc init[N: static int](x : var b[N]) = discard
  352. proc init[N: static int](x : var c[N]) = x.f1.init() # this is needed
  353. var x: c[2]
  354. x.init()