tgenerics_issues.nim 14 KB

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