tstaticsignature.nim 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 #20027
  110. block:
  111. type Test[T] = object
  112. proc run(self: Test): self.T = discard
  113. discard run(Test[int]())
  114. block:
  115. type Test[T] = object
  116. proc run[T](self: Test[T]): self.T = discard
  117. discard run(Test[int]())
  118. block:
  119. type Test[T] = object
  120. proc run(self: Test[auto]): self.T = discard
  121. discard run(Test[int]())
  122. block: # issue #11112
  123. proc foo[A, B]: type(A.default + B.default) =
  124. discard
  125. doAssert foo[int, int]() is int
  126. block: # tyStatic and tyFromExpr instantiation mid-match
  127. proc bar(x: int): int = x * 3
  128. proc bar2(x: static int): int = x * 4
  129. type Foo[T: static int] = distinct array[T, int]
  130. proc foo[T: static int](x: Foo[T], y: Foo[bar(T)]) = discard
  131. proc foo2[T: static int](x: Foo[T], y: Foo[bar2(T)]) = discard
  132. foo(Foo[1]([1]), Foo[3]([1, 2, 3]))
  133. foo2(Foo[1]([1]), Foo[4]([1, 2, 3, 4]))
  134. block: # issue #4990
  135. type Foo[I: static[int], A: static[array[I, int]]] = object
  136. curIndex: int
  137. proc next[I: static[int], A: static[array[I, int]]](f: Foo[I, A]): string =
  138. discard
  139. const arr = [1, 2, 3]
  140. var f: Foo[arr.len, arr]
  141. discard next(f)
  142. block: # issue #4990 comment
  143. type
  144. Foo[A: static[int], B: static[int], TokenType: enum, EofToken: static[TokenType]] = object
  145. curIndex: int
  146. MyEnum = enum
  147. meA, meB
  148. Bar = Foo[2, 3, MyEnum, meA]
  149. proc next[A: static[int], B: static[int], TokenType: enum,
  150. EofToken: static[TokenType]](f: Foo[A, B, TokenType, EofToken],
  151. a: static[(array[A, int], array[B, int])]): TokenType =
  152. TokenType(a[0][f.curIndex])
  153. const
  154. a = [1, 2]
  155. b = [3, 4, 5]
  156. template next(bar: Bar): MyEnum =
  157. next(Foo[2, 3, MyEnum, meA](bar), (a, b))
  158. let bar = Bar(curIndex: 0)
  159. doAssert bar.next() == meB
  160. block: # issue #14053
  161. template returnType(value: static[int]): typedesc =
  162. when value == 1:
  163. int
  164. else:
  165. float
  166. proc fun(value: static[int]): returnType(value) = discard
  167. doAssert fun(1) is int
  168. template returnType2(value: static[int]): typedesc =
  169. int
  170. proc fun2(value: static[int]): returnType2(value) = discard
  171. doAssert fun2(1) is int
  172. block: # issue #7547
  173. macro foo(N: static[int]): untyped =
  174. result = getType(int)
  175. type
  176. Foo[N: static[int]] = foo(N)
  177. ContainsFoo[N: static[int]] = object
  178. Ffoo: Foo[N]
  179. proc initFoo(N: static[int]): Foo[N] = discard
  180. proc initContainsFoo(size: static[int]): ContainsFoo[size] = discard
  181. var a: Foo[10] # Works
  182. doAssert a is int
  183. let b = initFoo(10) # Works
  184. doAssert b is int
  185. let c = ContainsFoo[5]() # Works
  186. doAssert c.Ffoo is int
  187. let z = initContainsFoo(5) # Error: undeclared identifier: 'N'
  188. doAssert z.Ffoo is int
  189. block: # issue #22607, needs nkWhenStmt to be handled like nkRecWhen
  190. proc test[x: static bool](
  191. t: (
  192. when x:
  193. int
  194. else:
  195. float
  196. )
  197. ) = discard
  198. test[true](1.int)
  199. test[false](1.0)
  200. doAssert not compiles(test[])
  201. block: # `when` in static signature
  202. template ctAnd(a, b): bool =
  203. when a:
  204. when b: true
  205. else: false
  206. else: false
  207. template test(): untyped =
  208. when ctAnd(declared(SharedTable), typeof(result) is SharedTable):
  209. result = SharedTable()
  210. else:
  211. result = 123
  212. proc foo[T](): T = test()
  213. proc bar[T](x = foo[T]()): T = x
  214. doAssert bar[int]() == 123
  215. block: # issue #22276
  216. type Foo = enum A, B
  217. macro test(y: static[Foo]): untyped =
  218. if y == A:
  219. result = parseExpr("proc (x: int)")
  220. else:
  221. result = parseExpr("proc (x: float)")
  222. proc foo(y: static[Foo], x: test(y)) = # We want to make the type of `x` depend on what `y` is
  223. x(9)
  224. foo(A, proc (x: int) = doAssert x == 9)
  225. var a: int
  226. foo(A, proc (x: int) =
  227. a = x * 2)
  228. doAssert a == 18
  229. foo(B, proc (x: float) = doAssert x == 9)