tstaticsignature.nim 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. block: # issue #4228
  2. template seqType(t: typedesc): typedesc =
  3. when t is int:
  4. seq[int]
  5. else:
  6. seq[string]
  7. proc mkSeq[T: int|string](v: T): seqType(T) =
  8. result = newSeq[T](1)
  9. result[0] = v
  10. doAssert mkSeq("a") == @["a"]
  11. doAssert mkSeq(1) == @[1]
  12. block: # expanded version of t8545
  13. template bar(a: static[bool]): untyped =
  14. when a:
  15. int
  16. else:
  17. float
  18. proc main() =
  19. proc foo1(a: static[bool]): auto = 1
  20. doAssert foo1(true) == 1
  21. proc foo2(a: static[bool]): bar(a) = 1
  22. doAssert foo2(true) == 1
  23. doAssert foo2(true) is int
  24. doAssert foo2(false) == 1.0
  25. doAssert foo2(false) is float
  26. proc foo3(a: static[bool]): bar(cast[bool](a)) = 1
  27. doAssert foo3(true) == 1
  28. doAssert foo3(true) is int
  29. doAssert foo3(false) == 1.0
  30. doAssert foo3(false) is float
  31. proc foo4(a: static[bool]): bar(static(a)) = 1
  32. doAssert foo4(true) == 1
  33. doAssert foo4(true) is int
  34. doAssert foo4(false) == 1.0
  35. doAssert foo4(false) is float
  36. static: main()
  37. main()
  38. block: # issue #8406
  39. macro f(x: static[int]): untyped = discard
  40. proc g[X: static[int]](v: f(X)) = discard
  41. import macros
  42. block: # issue #8551
  43. macro distinctBase2(T: typedesc): untyped =
  44. let typeNode = getTypeImpl(T)
  45. expectKind(typeNode, nnkBracketExpr)
  46. if typeNode[0].typeKind != ntyTypeDesc:
  47. error "expected typeDesc, got " & $typeNode[0]
  48. var typeSym = typeNode[1]
  49. typeSym = getTypeImpl(typeSym)
  50. if typeSym.typeKind != ntyDistinct:
  51. error "type is not distinct: " & $typeSym.typeKind
  52. typeSym = typeSym[0]
  53. typeSym
  54. func distinctBase[T](a: T): distinctBase2(T) = distinctBase2(T)(a)
  55. type T = distinct int
  56. doAssert distinctBase(T(0)) is int
  57. block:
  58. type Foo[T] = object
  59. x: T
  60. proc foo(x: Foo): Foo[x.T] =
  61. doAssert typeof(result) is typeof(x)
  62. var a: Foo[int]
  63. let b: Foo[int] = foo(a)
  64. doAssert b.x is int
  65. block:
  66. type Foo[T: static int] = object
  67. x: array[T, int]
  68. proc double(x: int): int = x * 2
  69. proc foo[T: static int](x: Foo[T]): Foo[T.double] =
  70. doAssert typeof(result).T == double(typeof(x).T)
  71. var a: Foo[3]
  72. let b: Foo[6] = foo(a)
  73. doAssert $typeof(foo(a)) == "Foo[6]"
  74. block:
  75. type Foo[T: static int] = object
  76. x: array[T, int]
  77. proc foo(x: Foo): Foo[x.T] =
  78. doAssert typeof(result).T == typeof(x).T
  79. doAssert typeof(result) is typeof(x)
  80. var a: Foo[3]
  81. let b: Foo[3] = foo(a)
  82. doAssert $typeof(foo(a)) == "Foo[3]"
  83. block: # issue #7006
  84. type
  85. Node[T] = object
  86. val: T
  87. next: ref Node[T]
  88. HHSet[T, Key] = object
  89. data: seq[Node[T]]
  90. proc rawGet(hhs:HHSet; key: hhs.Key): ptr Node[hhs.T] =
  91. return nil # body doesn't matter
  92. var hhs: HHSet[string, cstring]
  93. discard hhs.rawGet("hello".cstring)
  94. block: # issue #7008
  95. type Node[T] = object
  96. val: T
  97. # Compiles fine
  98. proc concreteProc(s: Node[cstring]; key: s.T) = discard
  99. # Also fine
  100. proc implicitGenericProc1(s: Node; key: s.T) = discard
  101. # still fine
  102. proc explicitGenericProc1[T](s: Node[T]; key: T) = discard
  103. # Internal Compiler Error!
  104. proc explicitGenericProc2[T](s: Node[T]; key: s.T) = discard
  105. let n = Node[int](val: 5)
  106. implicitGenericProc1(n, 5) # works
  107. explicitGenericProc1(n, 5) # works
  108. explicitGenericProc2(n, 5) # doesn't
  109. block: # issue #7009
  110. type Node[T] = object
  111. val: T
  112. proc genericProc(s: Node; key: s.T) =
  113. discard # body doesn't matter
  114. proc explicitGenericProc[T](s: Node[T]; key: T) =
  115. discard # body doesn't matter
  116. proc concreteProc(s: Node[cstring]; key: s.T) =
  117. discard # body doesn't matter
  118. var strs: Node[cstring]
  119. concreteProc(strs, "string") # string converts to cstring
  120. explicitGenericProc(strs, "string") # still converts
  121. genericProc(strs, "string") # doesn't convert: COMPILE ERROR
  122. block: # issue #20027
  123. block:
  124. type Test[T] = object
  125. proc run(self: Test): self.T = discard
  126. discard run(Test[int]())
  127. block:
  128. type Test[T] = object
  129. proc run[T](self: Test[T]): self.T = discard
  130. discard run(Test[int]())
  131. block:
  132. type Test[T] = object
  133. proc run(self: Test[auto]): self.T = discard
  134. discard run(Test[int]())
  135. block: # issue #11112
  136. proc foo[A, B]: type(A.default + B.default) =
  137. discard
  138. doAssert foo[int, int]() is int
  139. block: # tyStatic and tyFromExpr instantiation mid-match
  140. proc bar(x: int): int = x * 3
  141. proc bar2(x: static int): int = x * 4
  142. type Foo[T: static int] = distinct array[T, int]
  143. proc foo[T: static int](x: Foo[T], y: Foo[bar(T)]) = discard
  144. proc foo2[T: static int](x: Foo[T], y: Foo[bar2(T)]) = discard
  145. foo(Foo[1]([1]), Foo[3]([1, 2, 3]))
  146. foo2(Foo[1]([1]), Foo[4]([1, 2, 3, 4]))
  147. block: # issue #4990
  148. type Foo[I: static[int], A: static[array[I, int]]] = object
  149. curIndex: int
  150. proc next[I: static[int], A: static[array[I, int]]](f: Foo[I, A]): string =
  151. discard
  152. const arr = [1, 2, 3]
  153. var f: Foo[arr.len, arr]
  154. discard next(f)
  155. block: # issue #4990 comment
  156. type
  157. Foo[A: static[int], B: static[int], TokenType: enum, EofToken: static[TokenType]] = object
  158. curIndex: int
  159. MyEnum = enum
  160. meA, meB
  161. Bar = Foo[2, 3, MyEnum, meA]
  162. proc next[A: static[int], B: static[int], TokenType: enum,
  163. EofToken: static[TokenType]](f: Foo[A, B, TokenType, EofToken],
  164. a: static[(array[A, int], array[B, int])]): TokenType =
  165. TokenType(a[0][f.curIndex])
  166. const
  167. a = [1, 2]
  168. b = [3, 4, 5]
  169. template next(bar: Bar): MyEnum =
  170. next(Foo[2, 3, MyEnum, meA](bar), (a, b))
  171. let bar = Bar(curIndex: 0)
  172. doAssert bar.next() == meB
  173. block: # issue #14053
  174. template returnType(value: static[int]): typedesc =
  175. when value == 1:
  176. int
  177. else:
  178. float
  179. proc fun(value: static[int]): returnType(value) = discard
  180. doAssert fun(1) is int
  181. template returnType2(value: static[int]): typedesc =
  182. int
  183. proc fun2(value: static[int]): returnType2(value) = discard
  184. doAssert fun2(1) is int
  185. block: # issue #7547
  186. macro foo(N: static[int]): untyped =
  187. result = getType(int)
  188. type
  189. Foo[N: static[int]] = foo(N)
  190. ContainsFoo[N: static[int]] = object
  191. Ffoo: Foo[N]
  192. proc initFoo(N: static[int]): Foo[N] = discard
  193. proc initContainsFoo(size: static[int]): ContainsFoo[size] = discard
  194. var a: Foo[10] # Works
  195. doAssert a is int
  196. let b = initFoo(10) # Works
  197. doAssert b is int
  198. let c = ContainsFoo[5]() # Works
  199. doAssert c.Ffoo is int
  200. let z = initContainsFoo(5) # Error: undeclared identifier: 'N'
  201. doAssert z.Ffoo is int
  202. block: # issue #22607, needs nkWhenStmt to be handled like nkRecWhen
  203. proc test[x: static bool](
  204. t: (
  205. when x:
  206. int
  207. else:
  208. float
  209. )
  210. ) = discard
  211. test[true](1.int)
  212. test[false](1.0)
  213. doAssert not compiles(test[])
  214. block: # `when` in static signature
  215. template ctAnd(a, b): bool =
  216. when a:
  217. when b: true
  218. else: false
  219. else: false
  220. template test(): untyped =
  221. when ctAnd(declared(SharedTable), typeof(result) is SharedTable):
  222. result = SharedTable()
  223. else:
  224. result = 123
  225. proc foo[T](): T = test()
  226. proc bar[T](x = foo[T]()): T = x
  227. doAssert bar[int]() == 123
  228. block: # issue #22276
  229. type Foo = enum A, B
  230. macro test(y: static[Foo]): untyped =
  231. if y == A:
  232. result = parseExpr("proc (x: int)")
  233. else:
  234. result = parseExpr("proc (x: float)")
  235. proc foo(y: static[Foo], x: test(y)) = # We want to make the type of `x` depend on what `y` is
  236. x(9)
  237. foo(A, proc (x: int) = doAssert x == 9)
  238. var a: int
  239. foo(A, proc (x: int) =
  240. a = x * 2)
  241. doAssert a == 18
  242. foo(B, proc (x: float) = doAssert x == 9)
  243. block: # issue #9190
  244. func foo[T, U]: type(T.low + U.low) =
  245. T.low + U.low
  246. doAssert foo[uint8, uint8]() == uint8.low