tstatictypes.nim 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. discard """
  2. nimout: '''
  3. staticAlialProc instantiated with 358
  4. staticAlialProc instantiated with 368
  5. '''
  6. output: '''
  7. 16
  8. 16
  9. b is 2 times a
  10. 17
  11. ['\x00', '\x00', '\x00', '\x00']
  12. heyho
  13. Val1
  14. Val1
  15. '''
  16. """
  17. import macros
  18. template ok(x) = assert(x)
  19. template no(x) = assert(not x)
  20. template accept(x) =
  21. static: assert(compiles(x))
  22. template reject(x) =
  23. static: assert(not compiles(x))
  24. proc plus(a, b: int): int = a + b
  25. template isStatic(x: static): bool = true
  26. template isStatic(x: auto): bool = false
  27. var v = 1
  28. when true:
  29. # test that `isStatic` works as expected
  30. const C = 2
  31. static:
  32. ok C.isStatic
  33. ok isStatic(plus(1, 2))
  34. ok plus(C, 2).isStatic
  35. no isStatic(v)
  36. no plus(1, v).isStatic
  37. when true:
  38. # test that proc instantiation works as expected
  39. type
  40. StaticTypeAlias = static[int]
  41. proc staticAliasProc(a: StaticTypeAlias,
  42. b: static[int],
  43. c: static int) =
  44. static:
  45. assert a.isStatic and b.isStatic and c.isStatic
  46. assert isStatic(a + plus(b, c))
  47. echo "staticAlialProc instantiated with ", a, b, c
  48. when b mod a == 0:
  49. echo "b is ", b div a, " times a"
  50. echo a + b + c
  51. staticAliasProc 1+2, 5, 8
  52. staticAliasProc 3, 2+3, 9-1
  53. staticAliasProc 3, 3+3, 4+4
  54. when true:
  55. # test static coercions. normal cases that should work:
  56. accept:
  57. var s1 = static[int] plus(1, 2)
  58. var s2 = static(plus(1,2))
  59. var s3 = static plus(1,2)
  60. var s4 = static[SomeInteger](1 + 2)
  61. # the sub-script operator can be used only with types:
  62. reject:
  63. var just_static3 = static[plus(1,2)]
  64. # static coercion takes into account the type:
  65. reject:
  66. var x = static[string](plus(1, 2))
  67. reject:
  68. var x = static[string] plus(1, 2)
  69. reject:
  70. var x = static[SomeFloat] plus(3, 4)
  71. # you cannot coerce a run-time variable
  72. reject:
  73. var x = static(v)
  74. block: # issue #13730
  75. type Foo[T: static[float]] = object
  76. doAssert Foo[0.0] is Foo[-0.0]
  77. when true:
  78. type
  79. ArrayWrapper1[S: static int] = object
  80. data: array[S + 1, int]
  81. ArrayWrapper2[S: static[int]] = object
  82. data: array[S.plus(2), int]
  83. ArrayWrapper3[S: static[(int, string)]] = object
  84. data: array[S[0], int]
  85. var aw1: ArrayWrapper1[5]
  86. var aw2: ArrayWrapper2[5]
  87. var aw3: ArrayWrapper3[(10, "str")]
  88. static:
  89. assert aw1.data.high == 5
  90. assert aw2.data.high == 6
  91. assert aw3.data.high == 9
  92. # #6077
  93. block:
  94. type
  95. Backend = enum
  96. Cpu
  97. Tensor[B: static[Backend]; T] = object
  98. BackProp[B: static[Backend],T] = proc (gradient: Tensor[B,T]): Tensor[B,T]
  99. # https://github.com/nim-lang/Nim/issues/10073
  100. block:
  101. proc foo[N: static int](x: var int,
  102. y: int,
  103. z: static int,
  104. arr: array[N, int]): auto =
  105. var t1 = (a: x, b: y, c: z, d: N)
  106. var t2 = (x, y, z, N)
  107. doAssert t1 == t2
  108. result = t1
  109. var y = 20
  110. var x = foo(y, 10, 15, [1, 2, 3])
  111. doAssert x == (20, 10, 15, 3)
  112. # #7609
  113. block:
  114. type
  115. Coord[N: static[int]] = tuple[col, row: range[0'i8 .. (N.int8-1)]]
  116. Point[N: static[int]] = range[0'i16 .. N.int16 * N.int16 - 1]
  117. # https://github.com/nim-lang/Nim/issues/10339
  118. block:
  119. type
  120. MicroKernel = object
  121. a: float
  122. b: int
  123. macro extractA(ukernel: static MicroKernel): untyped =
  124. result = newLit ukernel.a
  125. proc tFunc[ukernel: static MicroKernel]() =
  126. const x = ukernel.extractA
  127. doAssert x == 5.5
  128. const uk = MicroKernel(a: 5.5, b: 1)
  129. tFunc[uk]()
  130. # bug #7258
  131. type
  132. StringValue*[LEN: static[Natural]] = array[LEN+Natural(2),char]
  133. StringValue16* = StringValue[2]
  134. var
  135. s: StringValue16
  136. echo s
  137. block: #13529
  138. block:
  139. type Foo[T: static type] = object
  140. var foo: Foo["test"]
  141. doAssert $foo == "()"
  142. doAssert foo.T is string
  143. static: doAssert foo.T == "test"
  144. doAssert not compiles(
  145. block:
  146. type Foo2[T: static type] = object
  147. x: T)
  148. block:
  149. type Foo[T: static[float]] = object
  150. var foo: Foo[1.2]
  151. doAssert $foo == "()"
  152. doAssert foo.T == 1.2
  153. block: # routines also work
  154. proc fun(a: static) = (const a2 = a)
  155. fun(1)
  156. fun(1.2)
  157. block: # routines also work
  158. proc fun(a: static type) = (const a2 = a)
  159. fun(1)
  160. fun(1.2)
  161. block: # this also works
  162. proc fun[T](a: static[T]) = (const a2 = a)
  163. fun(1)
  164. fun(1.2)
  165. block: # #12713
  166. block:
  167. type Cell = object
  168. c: int
  169. proc test(c: static string) = discard #Remove this and it compiles
  170. proc test(c: Cell) = discard
  171. test Cell(c: 0)
  172. block:
  173. type Cell = object
  174. c: int
  175. proc test(c: static string) = discard #Remove this and it compiles
  176. proc test(c: Cell) = discard
  177. test Cell()
  178. block: # issue #14802
  179. template fn(s: typed): untyped =
  180. proc bar() = discard
  181. 12
  182. const myConst = static(fn(1))
  183. doAssert myConst == 12
  184. # bug #12571
  185. type
  186. T[K: static bool] = object of RootObj
  187. when K == true:
  188. foo: string
  189. else:
  190. bar: string
  191. U[K: static bool] = object of T[K]
  192. let t = T[true](foo: "hey")
  193. let u = U[false](bar: "ho")
  194. echo t.foo, u.bar
  195. #------------------------------------------------------------------------------
  196. # issue #9679
  197. discard """
  198. output: ''''''
  199. """
  200. type
  201. Foo*[T] = object
  202. bar*: int
  203. dummy: T
  204. proc initFoo(T: type, bar: int): Foo[T] =
  205. result.bar = 1
  206. proc fails[T](x: static Foo[T]) = # Change to non-static and it compiles
  207. doAssert($x == "(bar: 1, dummy: 0)")
  208. block:
  209. const foo = initFoo(int, 2)
  210. fails(foo)
  211. import macros, tables
  212. var foo{.compileTime.} = [
  213. "Foo",
  214. "Bar"
  215. ]
  216. var bar{.compileTime.} = {
  217. 0: "Foo",
  218. 1: "Bar"
  219. }.toTable()
  220. macro fooM(): untyped =
  221. for i, val in foo:
  222. echo i, ": ", val
  223. macro barM(): untyped =
  224. for i, val in bar:
  225. echo i, ": ", val
  226. macro fooParam(x: static array[2, string]): untyped =
  227. for i, val in x:
  228. echo i, ": ", val
  229. macro barParam(x: static Table[int, string]): untyped =
  230. for i, val in x:
  231. echo i, ": ", val
  232. fooM()
  233. barM()
  234. fooParam(foo)
  235. barParam(bar)
  236. #-----------------------------------------------------------------------------------------
  237. # issue #7546
  238. type
  239. rangeB[N: static[int16]] = range[0'i16 .. N]
  240. setB[N: static[int16]] = set[rangeB[N]]
  241. block:
  242. var s : setB[14'i16]
  243. #-----------------------------------------------------------------------------------------
  244. # issue #9520
  245. type
  246. MyEnum = enum
  247. Val1, Val2
  248. proc myproc(a: static[MyEnum], b: int) =
  249. if b < 0:
  250. myproc(a, -b)
  251. echo $a
  252. myproc(Val1, -10)
  253. #------------------------------------------------------------------------------------------
  254. # issue #6177
  255. type
  256. G[N,M:static[int], T] = object
  257. o: T
  258. proc newG[N,M:static[int],T](x:var G[N,M,T], y:T) =
  259. x.o = y+10*N+100*M
  260. proc newG[N,M:static[int],T](x:T):G[N,M,T] = result.newG(x)
  261. var x:G[2,3,int]
  262. x.newG(4)
  263. var y = newG[2,3,int](4)
  264. #------------------------------------------------------------------------------------------
  265. # issue #12897
  266. type
  267. TileCT[n: static int] = object
  268. a: array[n, int]
  269. Tile = TileCT #Commenting this out to make it work
  270. #------------------------------------------------------------------------------------------
  271. # issue #15858
  272. proc fn(N1: static int, N2: static int, T: typedesc): array[N1 * N2, T] =
  273. doAssert(len(result) == N1 * N2)
  274. let yy = fn(5, 10, float)
  275. block:
  276. block:
  277. type Foo[N: static int] = array[cint(0) .. cint(N), float]
  278. type T = Foo[3]
  279. block:
  280. type Foo[N: static int] = array[int32(0) .. int32(N), float]
  281. type T = Foo[3]