tgenerics_issues.nim 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. discard """
  2. output: '''
  3. 4
  4. 3
  5. (weight: 17.0, color: 100)
  6. perm: 22 det: 22
  7. TMatrix[3, 3, system.int]
  8. 3
  9. @[0.9, 0.1]
  10. U[3]
  11. U[(f: 3)]
  12. U[[3]]
  13. b()
  14. @[1, 2]
  15. @[3, 4]
  16. 1
  17. concrete 88
  18. 123
  19. 1
  20. 2
  21. 3
  22. !!Hi!!
  23. G:0,1:0.1
  24. G:0,1:0.1
  25. H:1:0.1
  26. '''
  27. joinable: false
  28. """
  29. import macros, sequtils, sets, sugar, tables, typetraits
  30. block t88:
  31. type
  32. BaseClass[V] = object of RootObj
  33. b: V
  34. proc new[V](t: typedesc[BaseClass], v: V): BaseClass[V] =
  35. BaseClass[V](b: v)
  36. proc baseMethod[V](v: BaseClass[V]): V = v.b
  37. proc overriddenMethod[V](v: BaseClass[V]): V = v.baseMethod
  38. type
  39. ChildClass[V] = object of BaseClass[V]
  40. c: V
  41. proc new[V](t: typedesc[ChildClass], v1, v2: V): ChildClass[V] =
  42. ChildClass[V](b: v1, c: v2)
  43. proc overriddenMethod[V](v: ChildClass[V]): V = v.c
  44. let c = ChildClass[string].new("Base", "Child")
  45. assert c.baseMethod == "Base"
  46. assert c.overriddenMethod == "Child"
  47. block t4528:
  48. type GenericBase[T] = ref object of RootObj
  49. type GenericSubclass[T] = ref object of GenericBase[T]
  50. proc foo[T](g: GenericBase[T]) = discard
  51. var bar: GenericSubclass[int]
  52. foo(bar)
  53. block t1050_5597:
  54. type ArrayType[T] = distinct T
  55. proc arrayItem(a: ArrayType): auto =
  56. static: echo(name(type(a).T))
  57. result = (type(a).T)(4)
  58. var arr: ArrayType[int]
  59. echo arrayItem(arr)
  60. # bug #5597
  61. template fail() = "what"
  62. proc g[T](x: var T) =
  63. x.fail = 3
  64. type
  65. Obj = object
  66. fail: int
  67. var y: Obj
  68. g y
  69. block t1789:
  70. type
  71. Foo[N: static[int]] = object
  72. proc bindStaticN[N](foo: Foo[N]) =
  73. var ar0: array[3, int]
  74. var ar1: array[N, int]
  75. var ar2: array[1..N, int]
  76. var ar3: array[0..(N+10), float]
  77. echo N
  78. var f: Foo[3]
  79. f.bindStaticN
  80. # case 2
  81. type
  82. ObjectWithStatic[X, Y: static[int], T] = object
  83. bar: array[X * Y, T] # this one works
  84. AliasWithStatic[X, Y: static[int], T] = array[X * Y, T]
  85. var
  86. x: ObjectWithStatic[1, 2, int]
  87. y: AliasWithStatic[2, 3, int]
  88. # case 3
  89. type
  90. Bar[N: static[int], T] = object
  91. bar: array[N, T]
  92. proc `[]`[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T =
  93. assert high(n) == N-1
  94. result = f.bar[n]
  95. var b: Bar[3, int]
  96. doAssert b[2] == 0
  97. block t3977:
  98. type Foo[N: static[int]] = object
  99. proc foo[N](x: Foo[N]) =
  100. let n = N
  101. doAssert N == n
  102. var f1: Foo[42]
  103. f1.foo
  104. block t5570:
  105. type
  106. BaseFruit[T] = object of RootObj
  107. color: T
  108. Banana[T] = object of BaseFruit[uint32]
  109. weight: T
  110. macro printTypeName(typ: typed): untyped =
  111. echo "type ", getType(typ).repr
  112. proc setColor[K](self: var BaseFruit[K], c: int) =
  113. printTypeName(self.color)
  114. self.color = uint32(c)
  115. var x: Banana[float64]
  116. x.weight = 17
  117. printTypeName(x.color)
  118. x.setColor(100)
  119. echo x
  120. block t5643:
  121. type
  122. Matrix[M, N: static[int], T: SomeFloat] = object
  123. data: ref array[N * M, T]
  124. Matrix64[M, N: static[int]] = Matrix[M, N, float64]
  125. proc zeros64(M,N: static[int]): Matrix64[M,N] =
  126. new result.data
  127. for i in 0 ..< (M * N):
  128. result.data[i] = 0'f64
  129. proc bar[M,N: static[int], T](a: Matrix[M,N,T], b: Matrix[M,N,T]) =
  130. discard
  131. let a = zeros64(2,2)
  132. bar(a,a)
  133. # https://github.com/nim-lang/Nim/issues/5643
  134. #
  135. # The test case was failing here, because the compiler failed to
  136. # detect the two matrix instantiations as the same type.
  137. #
  138. # The root cause was that the `T` type variable is a different
  139. # type after the first Matrix type has been matched.
  140. #
  141. # Sigmatch was failing to match the second version of `T`, but
  142. # due to some complex interplay between tyOr, tyTypeDesc and
  143. # tyGenericParam this was allowed to went through. The generic
  144. # instantiation of the second matrix was incomplete and the
  145. # generic cache lookup failed, producing two separate types.
  146. block t5683:
  147. type Matrix[M,N: static[int]] = array[M, array[N, float]]
  148. proc det[M,N](a: Matrix[M,N]): int = N*10 + M
  149. proc perm[M,N](a: Matrix[M,N]): int = M*10 + N
  150. const
  151. a = [ [1.0, 2.0]
  152. , [3.0, 4.0]
  153. ]
  154. echo "perm: ", a.perm, " det: ", a.det
  155. # This tests multiple instantiations of a generic
  156. # proc involving static params:
  157. type
  158. Vector64[N: static[int]] = ref array[N, float64]
  159. Array64[N: static[int]] = array[N, float64]
  160. proc vector[N: static[int]](xs: Array64[N]): Vector64[N] =
  161. new result
  162. for i in 0 ..< N:
  163. result[i] = xs[i]
  164. let v1 = vector([1.0, 2.0, 3.0, 4.0, 5.0])
  165. let v2 = vector([1.0, 2.0, 3.0, 4.0, 5.0])
  166. let v3 = vector([1.0, 2.0, 3.0, 4.0])
  167. block t7794:
  168. type
  169. Data[T:SomeNumber, U:SomeFloat] = ref object
  170. x: T
  171. value*: U
  172. var d = Data[int, float64](x:10.int, value:2'f64)
  173. doAssert d.x == 10
  174. doAssert d.value == 2.0
  175. block t8403:
  176. proc sum[T](s: seq[T], R: typedesc): R =
  177. var sum: R = 0
  178. for x in s:
  179. sum += R(x)
  180. return sum
  181. doAssert @[1, 2, 3].sum(float) == 6.0
  182. block t8439:
  183. type
  184. Cardinal = enum
  185. north, east, south, west
  186. proc foo[cardinal: static[Cardinal]](): int = 1
  187. doAssert foo[north]() == 1
  188. block t8694:
  189. when true:
  190. # Error: undeclared identifier: '|'
  191. proc bar[T](t:T): bool =
  192. runnableExamples:
  193. type Foo = int | float
  194. true
  195. doAssert bar(0)
  196. when true:
  197. # ok
  198. proc bar(t:int): bool =
  199. runnableExamples:
  200. type Foo = int | float
  201. true
  202. doAssert bar(0)
  203. when true:
  204. # Error: undeclared identifier: '|'
  205. proc bar(t:typedesc): bool =
  206. runnableExamples:
  207. type Foo = int | float
  208. true
  209. doAssert bar(int)
  210. block t9130:
  211. when true:
  212. # stack overflow
  213. template baz1(iter: untyped): untyped =
  214. runnableExamples:
  215. import sugar
  216. proc fun(a: proc(x:int): int) = discard
  217. baz1(fun(x:int => x))
  218. discard
  219. proc foo1[A](ts: A) =
  220. baz1(ts)
  221. when true:
  222. # ok
  223. template baz2(iter: untyped): untyped =
  224. runnableExamples:
  225. import sugar
  226. proc fun(a: proc(x:int): int) = discard
  227. baz2(fun(x:int => x))
  228. discard
  229. proc foo2(ts: int) =
  230. baz2(ts)
  231. when true:
  232. # stack overflow
  233. template baz3(iter: untyped): untyped =
  234. runnableExamples:
  235. baz3(fun(x:int => x))
  236. discard
  237. proc foo3[A](ts: A) =
  238. baz3(ts)
  239. block t1056:
  240. type
  241. TMatrix[N,M: static[int], T] = object
  242. data: array[0..N*M-1, T]
  243. TMat2[T] = TMatrix[2,2,T]
  244. proc echoMatrix(a: TMatrix) =
  245. echo a.type.name
  246. echo TMatrix.N
  247. proc echoMat2(a: TMat2) =
  248. echo TMat2.M
  249. var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
  250. echoMatrix m
  251. block t4884:
  252. type
  253. Vec[N: static[int], T] = object
  254. arr*: array[N, T]
  255. Mat[N,M: static[int], T] = object
  256. arr: array[N, Vec[M,T]]
  257. var m : Mat[3,3,float]
  258. var strMat : Mat[m.N, m.M, string]
  259. var lenMat : Mat[m.N, m.M, int]
  260. block t2221:
  261. var tblo: TableRef[string, int]
  262. doAssert tblo == nil
  263. block t2304:
  264. type TV2[T:SomeNumber] = array[0..1, T]
  265. proc newV2T[T](x, y: T=0): TV2[T] = [x, y]
  266. let x = newV2T[float](0.9, 0.1)
  267. echo(@x)
  268. block t2752:
  269. proc myFilter[T](it: (iterator(): T), f: (proc(anything: T):bool)): (iterator(): T) =
  270. iterator aNameWhichWillConflict(): T {.closure.}=
  271. for x in it():
  272. if f(x):
  273. yield x
  274. result = aNameWhichWillConflict
  275. iterator testIt():int {.closure.}=
  276. yield -1
  277. yield 2
  278. #let unusedVariable = myFilter(testIt, (x: int) => x > 0)
  279. proc onlyPos(it: (iterator(): int)): (iterator(): int)=
  280. iterator aNameWhichWillConflict(): int {.closure.}=
  281. var filtered = onlyPos(myFilter(it, (x:int) => x > 0))
  282. for x in filtered():
  283. yield x
  284. result = aNameWhichWillConflict
  285. let x = onlyPos(testIt)
  286. block t5106:
  287. block:
  288. type T = distinct int
  289. proc `+`(a, b: T): T =
  290. T(int(a) + int(b))
  291. type U[F: static[T]] = distinct int
  292. proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] =
  293. U[P1 + P2](int(a) + int(b))
  294. var a = U[T(1)](1)
  295. var b = U[T(2)](2)
  296. var c = a + b
  297. echo c.type.name
  298. block:
  299. type T = object
  300. f: int
  301. proc `+`(a, b: T): T =
  302. T(f: a.f + b.f)
  303. type U[F: static[T]] = distinct int
  304. proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] =
  305. U[P1 + P2](int(a) + int(b))
  306. var a = U[T(f: 1)](1)
  307. var b = U[T(f: 2)](2)
  308. var c = a + b
  309. echo c.type.name
  310. block:
  311. type T = distinct array[0..0, int]
  312. proc `+`(a, b: T): T =
  313. T([array[0..0, int](a)[0] + array[0..0, int](b)[0]])
  314. type U[F: static[T]] = distinct int
  315. proc `+`[P1, P2: static[T]](a: U[P1], b: U[P2]): U[P1 + P2] =
  316. U[P1 + P2](int(a) + int(b))
  317. var a = U[T([1])](1)
  318. var b = U[T([2])](2)
  319. var c = a + b
  320. echo c.type.name
  321. block t3055:
  322. proc b(t: int | string)
  323. proc a(t: int) = b(t)
  324. proc b(t: int | string) = echo "b()"
  325. a(1)
  326. # test recursive generics still work:
  327. proc fac[T](x: T): T =
  328. if x == 0: return 1
  329. else: return fac(x-1)*x
  330. doAssert fac(6) == 720
  331. doAssert fac(5.0) == 120.0
  332. # test recursive generic with forwarding:
  333. proc fac2[T](x: T): T
  334. doAssert fac2(6) == 720
  335. doAssert fac2(5.0) == 120.0
  336. proc fac2[T](x: T): T =
  337. if x == 0: return 1
  338. else: return fac2(x-1)*x
  339. block t1187:
  340. type
  341. TEventArgs = object
  342. skip: bool
  343. TEventHandler[T] = proc (e: var TEventArgs, data: T) {.closure.}
  344. TEvent[T] = object
  345. #handlers: seq[TEventHandler[T]] # Does not work
  346. handlers: seq[proc (e: var TEventArgs, d: T) {.closure.}] # works
  347. TData = object
  348. x: int
  349. TSomething = object
  350. s: TEvent[TData]
  351. proc init[T](e: var TEvent[T]) =
  352. e.handlers.newSeq(0)
  353. #proc add*[T](e: var TEvent[T], h: proc (e: var TEventArgs, data: T) {.closure.}) =
  354. # this line works
  355. proc add[T](e: var TEvent[T], h: TEventHandler[T]) =
  356. # this line does not work
  357. e.handlers.add(h)
  358. proc main () =
  359. var something: TSomething
  360. something.s.init()
  361. var fromOutside = 4711
  362. something.s.add() do (e: var TEventArgs, data: TData):
  363. var x = data.x
  364. x = fromOutside
  365. main()
  366. block t1919:
  367. type
  368. Base[M] = object of RootObj
  369. a : M
  370. Sub1[M] = object of Base[M]
  371. b : int
  372. Sub2[M] = object of Sub1[M]
  373. c : int
  374. var x: Sub2[float]
  375. doAssert x.a == 0.0
  376. block t5756:
  377. type
  378. Vec[N : static[int]] = object
  379. x: int
  380. arr: array[N, int32]
  381. Mat[M,N: static[int]] = object
  382. x: int
  383. arr: array[M, Vec[N]]
  384. proc vec2(x,y:int32) : Vec[2] =
  385. result.arr = [x,y]
  386. result.x = 10
  387. proc mat2(a,b: Vec[2]): Mat[2,2] =
  388. result.arr = [a,b]
  389. result.x = 20
  390. const M = mat2(vec2(1, 2), vec2(3, 4))
  391. let m1 = M
  392. echo @(m1.arr[0].arr)
  393. echo @(m1.arr[1].arr)
  394. proc foo =
  395. let m2 = M
  396. echo m1.arr[0].arr[0]
  397. foo()
  398. block t7854:
  399. type
  400. Stream = ref StreamObj
  401. StreamObj = object of RootObj
  402. InhStream = ref InhStreamObj
  403. InhStreamObj = object of Stream
  404. f: string
  405. proc newInhStream(f: string): InhStream =
  406. new(result)
  407. result.f = f
  408. var val: int
  409. let str = newInhStream("input_file.json")
  410. block:
  411. # works:
  412. proc load[T](data: var T, s: Stream) =
  413. discard
  414. load(val, str)
  415. block:
  416. # works
  417. proc load[T](s: Stream, data: T) =
  418. discard
  419. load(str, val)
  420. block:
  421. # broken
  422. proc load[T](s: Stream, data: var T) =
  423. discard
  424. load(str, val)
  425. block t5864:
  426. proc defaultStatic(s: openarray, N: static[int] = 1): int = N
  427. proc defaultGeneric[T](a: T = 2): int = a
  428. let a = [1, 2, 3, 4].defaultStatic()
  429. let b = defaultGeneric()
  430. doAssert a == 1
  431. doAssert b == 2
  432. block t3498:
  433. template defaultOf[T](t: T): untyped = (var d: T; d)
  434. doAssert defaultOf(1) == 0
  435. # assignment using template
  436. template tassign[T](x: var seq[T]) =
  437. x = @[1, 2, 3]
  438. var y: seq[int]
  439. tassign(y) #<- x is expected = @[1, 2, 3]
  440. tassign(y)
  441. doAssert y[0] == 1
  442. doAssert y[1] == 2
  443. doAssert y[2] == 3
  444. block t3499:
  445. proc foo[T](x: proc(): T) =
  446. echo "generic ", x()
  447. proc foo(x: proc(): int) =
  448. echo "concrete ", x()
  449. # note the following 'proc' is not .closure!
  450. foo(proc (): auto {.nimcall.} = 88)
  451. # bug #3499 last snippet fixed
  452. # bug 705 last snippet fixed
  453. block t797:
  454. proc foo[T](s:T):string = $s
  455. type IntStringProc = proc(x: int): string
  456. var f1 = IntStringProc(foo)
  457. var f2: proc(x: int): string = foo
  458. var f3: IntStringProc = foo
  459. echo f1(1), f2(2), f3(3)
  460. for x in map([1,2,3], foo): echo x
  461. block t4658:
  462. var x = 123
  463. proc twice[T](f: T -> T): T -> T = (x: T) => f(f(x))
  464. proc quote(s: string): string = "!" & s & "!"
  465. echo twice(quote)("Hi")
  466. block t4589:
  467. type SimpleTable[TKey, TVal] = TableRef[TKey, TVal]
  468. template newSimpleTable(TKey, TVal: typedesc): SimpleTable[TKey, TVal] = newTable[TKey, TVal]()
  469. var fontCache : SimpleTable[string, SimpleTable[int32, int]]
  470. fontCache = newSimpleTable(string, SimpleTable[int32, int])
  471. block t4600:
  472. template foo(x: untyped): untyped = echo 1
  473. template foo(x,y: untyped): untyped = echo 2
  474. proc bar1[T](x: T) = foo(x)
  475. proc bar2(x: float) = foo(x,x)
  476. proc bar3[T](x: T) = foo(x,x)
  477. block t4672:
  478. type
  479. EnumContainer[T: enum] = object
  480. v: T
  481. SomeEnum {.pure.} = enum
  482. A,B,C
  483. proc value[T: enum](this: EnumContainer[T]): T =
  484. this.v
  485. var enumContainer: EnumContainer[SomeEnum]
  486. discard enumContainer.value()
  487. block t4863:
  488. type
  489. G[i,j: static[int]] = object
  490. v:float
  491. H[j: static[int]] = G[0,j]
  492. proc p[i,j: static[int]](x:G[i,j]) = echo "G:", i, ",", j, ":", x.v
  493. proc q[j: static[int]](x:H[j]) = echo "H:", j, ":", x.v
  494. var
  495. g0 = G[0,1](v: 0.1)
  496. h0:H[1] = g0
  497. p(g0)
  498. p(h0)
  499. q(h0)
  500. block t1684:
  501. type
  502. BaseType {.inheritable pure.} = object
  503. idx: int
  504. DerivedType {.final pure.} = object of BaseType
  505. proc index[Toohoo: BaseType](h: Toohoo): int {.inline.} = h.idx
  506. proc newDerived(idx: int): DerivedType {.inline.} = DerivedType(idx: idx)
  507. let d = newDerived(2)
  508. assert(d.index == 2)
  509. block t5632:
  510. type Option[T] = object
  511. proc point[A](v: A, t: typedesc[Option[A]]): Option[A] =
  512. discard
  513. discard point(1, Option)
  514. block t7247:
  515. type n8 = range[0'i8..127'i8]
  516. var tab = initSet[n8]()
  517. doAssert tab.contains(8) == false
  518. block t3717:
  519. type
  520. Foo[T] = object
  521. a: T
  522. Foo1[T] = Foo[T] | int
  523. proc foo[T](s: Foo1[Foo[T]]): T =
  524. 5
  525. var f: Foo[Foo[int]]
  526. discard foo(f)
  527. block t5707:
  528. proc foo[T]: seq[int] =
  529. return lc[x | (x <- 1..10, x mod 2 == 0), int]
  530. doAssert foo[float32]() == @[2, 4, 6, 8, 10]