tstatictypes.nim 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. '''
  13. """
  14. import macros
  15. template ok(x) = assert(x)
  16. template no(x) = assert(not x)
  17. template accept(x) =
  18. static: assert(compiles(x))
  19. template reject(x) =
  20. static: assert(not compiles(x))
  21. proc plus(a, b: int): int = a + b
  22. template isStatic(x: static): bool = true
  23. template isStatic(x: auto): bool = false
  24. var v = 1
  25. when true:
  26. # test that `isStatic` works as expected
  27. const C = 2
  28. static:
  29. ok C.isStatic
  30. ok isStatic(plus(1, 2))
  31. ok plus(C, 2).isStatic
  32. no isStatic(v)
  33. no plus(1, v).isStatic
  34. when true:
  35. # test that proc instantiation works as expected
  36. type
  37. StaticTypeAlias = static[int]
  38. proc staticAliasProc(a: StaticTypeAlias,
  39. b: static[int],
  40. c: static int) =
  41. static:
  42. assert a.isStatic and b.isStatic and c.isStatic
  43. assert isStatic(a + plus(b, c))
  44. echo "staticAlialProc instantiated with ", a, b, c
  45. when b mod a == 0:
  46. echo "b is ", b div a, " times a"
  47. echo a + b + c
  48. staticAliasProc 1+2, 5, 8
  49. staticAliasProc 3, 2+3, 9-1
  50. staticAliasProc 3, 3+3, 4+4
  51. when true:
  52. # test static coercions. normal cases that should work:
  53. accept:
  54. var s1 = static[int] plus(1, 2)
  55. var s2 = static(plus(1,2))
  56. var s3 = static plus(1,2)
  57. var s4 = static[SomeInteger](1 + 2)
  58. # the sub-script operator can be used only with types:
  59. reject:
  60. var just_static3 = static[plus(1,2)]
  61. # static coercion takes into account the type:
  62. reject:
  63. var x = static[string](plus(1, 2))
  64. reject:
  65. var x = static[string] plus(1, 2)
  66. reject:
  67. var x = static[SomeFloat] plus(3, 4)
  68. # you cannot coerce a run-time variable
  69. reject:
  70. var x = static(v)
  71. block: # issue #13730
  72. type Foo[T: static[float]] = object
  73. doAssert Foo[0.0] is Foo[-0.0]
  74. when true:
  75. type
  76. ArrayWrapper1[S: static int] = object
  77. data: array[S + 1, int]
  78. ArrayWrapper2[S: static[int]] = object
  79. data: array[S.plus(2), int]
  80. ArrayWrapper3[S: static[(int, string)]] = object
  81. data: array[S[0], int]
  82. var aw1: ArrayWrapper1[5]
  83. var aw2: ArrayWrapper2[5]
  84. var aw3: ArrayWrapper3[(10, "str")]
  85. static:
  86. assert aw1.data.high == 5
  87. assert aw2.data.high == 6
  88. assert aw3.data.high == 9
  89. # #6077
  90. block:
  91. type
  92. Backend = enum
  93. Cpu
  94. Tensor[B: static[Backend]; T] = object
  95. BackProp[B: static[Backend],T] = proc (gradient: Tensor[B,T]): Tensor[B,T]
  96. # https://github.com/nim-lang/Nim/issues/10073
  97. block:
  98. proc foo[N: static int](x: var int,
  99. y: int,
  100. z: static int,
  101. arr: array[N, int]): auto =
  102. var t1 = (a: x, b: y, c: z, d: N)
  103. var t2 = (x, y, z, N)
  104. doAssert t1 == t2
  105. result = t1
  106. var y = 20
  107. var x = foo(y, 10, 15, [1, 2, 3])
  108. doAssert x == (20, 10, 15, 3)
  109. # #7609
  110. block:
  111. type
  112. Coord[N: static[int]] = tuple[col, row: range[0'i8 .. (N.int8-1)]]
  113. Point[N: static[int]] = range[0'i16 .. N.int16 * N.int16 - 1]
  114. # https://github.com/nim-lang/Nim/issues/10339
  115. block:
  116. type
  117. MicroKernel = object
  118. a: float
  119. b: int
  120. macro extractA(ukernel: static MicroKernel): untyped =
  121. result = newLit ukernel.a
  122. proc tFunc[ukernel: static MicroKernel]() =
  123. const x = ukernel.extractA
  124. doAssert x == 5.5
  125. const uk = MicroKernel(a: 5.5, b: 1)
  126. tFunc[uk]()
  127. # bug #7258
  128. type
  129. StringValue*[LEN: static[Natural]] = array[LEN+Natural(2),char]
  130. StringValue16* = StringValue[2]
  131. var
  132. s: StringValue16
  133. echo s
  134. block: #13529
  135. block:
  136. type Foo[T: static type] = object
  137. var foo: Foo["test"]
  138. doAssert $foo == "()"
  139. doAssert foo.T is string
  140. static: doAssert foo.T == "test"
  141. doAssert not compiles(
  142. block:
  143. type Foo2[T: static type] = object
  144. x: T)
  145. block:
  146. type Foo[T: static[float]] = object
  147. var foo: Foo[1.2]
  148. doAssert $foo == "()"
  149. doAssert foo.T == 1.2
  150. block: # routines also work
  151. proc fun(a: static) = (const a2 = a)
  152. fun(1)
  153. fun(1.2)
  154. block: # routines also work
  155. proc fun(a: static type) = (const a2 = a)
  156. fun(1)
  157. fun(1.2)
  158. block: # this also works
  159. proc fun[T](a: static[T]) = (const a2 = a)
  160. fun(1)
  161. fun(1.2)
  162. block: # #12713
  163. block:
  164. type Cell = object
  165. c: int
  166. proc test(c: static string) = discard #Remove this and it compiles
  167. proc test(c: Cell) = discard
  168. test Cell(c: 0)
  169. block:
  170. type Cell = object
  171. c: int
  172. proc test(c: static string) = discard #Remove this and it compiles
  173. proc test(c: Cell) = discard
  174. test Cell()
  175. block: # issue #14802
  176. template fn(s: typed): untyped =
  177. proc bar() = discard
  178. 12
  179. const myConst = static(fn(1))
  180. doAssert myConst == 12