toverload_various.nim 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. discard """
  2. output: '''
  3. true012innertrue
  4. m1
  5. tup1
  6. another number: 123
  7. yay
  8. helloa 1 b 2 x @[3, 4, 5] y 6 z 7
  9. yay
  10. 12
  11. ref ref T ptr S
  12. dynamic: let
  13. dynamic: var
  14. static: const
  15. static: literal
  16. static: constant folding
  17. static: static string
  18. foo1
  19. 1
  20. '''
  21. """
  22. import strutils, sequtils
  23. block overl2:
  24. # Test new overloading resolution rules
  25. proc toverl2(x: int): string = return $x
  26. proc toverl2(x: bool): string = return $x
  27. iterator toverl2(x: int): int =
  28. var res = 0
  29. while res < x:
  30. yield res
  31. inc(res)
  32. var
  33. pp: proc (x: bool): string {.nimcall.} = toverl2
  34. stdout.write(pp(true))
  35. for x in toverl2(3):
  36. stdout.write(toverl2(x))
  37. block:
  38. proc toverl2(x: int): string = return "inner"
  39. stdout.write(toverl2(5))
  40. stdout.write(true)
  41. stdout.write("\n")
  42. #OUT true012innertrue
  43. block overl3:
  44. # Tests more specific generic match:
  45. proc m[T](x: T) = echo "m2"
  46. proc m[T](x: var ref T) = echo "m1"
  47. proc tup[S, T](x: tuple[a: S, b: ref T]) = echo "tup1"
  48. proc tup[S, T](x: tuple[a: S, b: T]) = echo "tup2"
  49. var
  50. obj: ref int
  51. tu: tuple[a: int, b: ref bool]
  52. m(obj)
  53. tup(tu)
  54. block toverprc:
  55. # Test overloading of procs when used as function pointers
  56. proc parseInt(x: float): int {.noSideEffect.} = discard
  57. proc parseInt(x: bool): int {.noSideEffect.} = discard
  58. proc parseInt(x: float32): int {.noSideEffect.} = discard
  59. proc parseInt(x: int8): int {.noSideEffect.} = discard
  60. proc parseInt(x: File): int {.noSideEffect.} = discard
  61. proc parseInt(x: char): int {.noSideEffect.} = discard
  62. proc parseInt(x: int16): int {.noSideEffect.} = discard
  63. proc parseInt[T](x: T): int = echo x; 34
  64. type
  65. TParseInt = proc (x: string): int {.noSideEffect.}
  66. var
  67. q = TParseInt(parseInt)
  68. p: TParseInt = parseInt
  69. proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int =
  70. result = x("123")
  71. if false:
  72. echo "Give a list of numbers (separated by spaces): "
  73. var x = stdin.readline.split.map(parseInt).max
  74. echo x, " is the maximum!"
  75. echo "another number: ", takeParseInt(parseInt)
  76. type
  77. TFoo[a,b] = object
  78. lorem: a
  79. ipsum: b
  80. proc bar[a,b](f: TFoo[a,b], x: a) = echo(x, " ", f.lorem, f.ipsum)
  81. proc bar[a,b](f: TFoo[a,b], x: b) = echo(x, " ", f.lorem, f.ipsum)
  82. discard parseInt[string]("yay")
  83. block toverwr:
  84. # Test the overloading resolution in connection with a qualifier
  85. proc write(t: File, s: string) =
  86. discard # a nop
  87. system.write(stdout, "hello")
  88. #OUT hello
  89. block tparams_after_varargs:
  90. proc test(a, b: int, x: varargs[int]; y, z: int) =
  91. echo "a ", a, " b ", b, " x ", @x, " y ", y, " z ", z
  92. test 1, 2, 3, 4, 5, 6, 7
  93. # XXX maybe this should also work with ``varargs[untyped]``
  94. template takesBlockA(a, b: untyped; x: varargs[typed]; blck: untyped): untyped =
  95. blck
  96. echo a, b
  97. takesBlockA 1, 2, "some", 0.90, "random stuff":
  98. echo "yay"
  99. block tprefer_specialized_generic:
  100. proc foo[T](x: T) =
  101. echo "only T"
  102. proc foo[T](x: ref T) =
  103. echo "ref T"
  104. proc foo[T, S](x: ref ref T; y: ptr S) =
  105. echo "ref ref T ptr S"
  106. proc foo[T, S](x: ref T; y: ptr S) =
  107. echo "ref T ptr S"
  108. proc foo[T](x: ref T; default = 0) =
  109. echo "ref T; default"
  110. var x: ref ref int
  111. var y: ptr ptr int
  112. foo(x, y)
  113. block tstaticoverload:
  114. proc foo(s: string) =
  115. echo "dynamic: ", s
  116. proc foo(s: static[string]) =
  117. echo "static: ", s
  118. let l = "let"
  119. var v = "var"
  120. const c = "const"
  121. type staticString = static[string]
  122. foo(l)
  123. foo(v)
  124. foo(c)
  125. foo("literal")
  126. foo("constant" & " " & "folding")
  127. foo(staticString("static string"))
  128. # bug #8568 (2)
  129. proc goo(a: int): string = "int"
  130. proc goo(a: static[int]): string = "static int"
  131. proc goo(a: var int): string = "var int"
  132. proc goo[T: int](a: T): string = "T: int"
  133. #proc goo[T](a: T): string = "nur T"
  134. const tmp1 = 1
  135. let tmp2 = 1
  136. var tmp3 = 1
  137. doAssert goo(1) == "static int"
  138. doAssert goo(tmp1) == "static int"
  139. doAssert goo(tmp2) == "int"
  140. doAssert goo(tmp3) == "var int"
  141. doAssert goo[int](1) == "T: int"
  142. doAssert goo[int](tmp1) == "T: int"
  143. doAssert goo[int](tmp2) == "T: int"
  144. doAssert goo[int](tmp3) == "T: int"
  145. # bug #6076
  146. type A[T] = object
  147. proc regr(a: A[void]) = echo "foo1"
  148. proc regr[T](a: A[T]) = doAssert(false)
  149. regr(A[void]())
  150. type Foo[T] = object
  151. proc regr[T](p: Foo[T]): seq[T] =
  152. discard
  153. proc regr(p: Foo[void]): seq[int] =
  154. discard
  155. discard regr(Foo[int]())
  156. discard regr(Foo[void]())
  157. type
  158. Sha2Context*[bits: static[int],
  159. bsize: static[int],
  160. T: uint32|uint64] = object
  161. count: array[2, T]
  162. state: array[8, T]
  163. buffer: array[bsize, byte]
  164. sha224* = Sha2Context[224, 64, uint32]
  165. sha256* = Sha2Context[256, 64, uint32]
  166. sha384* = Sha2Context[384, 128, uint64]
  167. sha512* = Sha2Context[512, 128, uint64]
  168. sha512_224* = Sha2Context[224, 128, uint64]
  169. sha512_256* = Sha2Context[256, 128, uint64]
  170. type
  171. RipemdContext*[bits: static[int]] = object
  172. count: array[2, uint32]
  173. state: array[bits div 32, uint32]
  174. buffer: array[64, byte]
  175. ripemd128* = RipemdContext[128]
  176. ripemd160* = RipemdContext[160]
  177. ripemd256* = RipemdContext[256]
  178. ripemd320* = RipemdContext[320]
  179. const
  180. MaxHmacBlockSize = 256
  181. type
  182. HMAC*[HashType] = object
  183. mdctx: HashType
  184. opadctx: HashType
  185. template sizeBlock*(h: HMAC[Sha2Context]): uint = 1u
  186. template sizeBlock*(h: HMAC[RipemdContext]): uint = 0u
  187. proc init*[T](hmctx: HMAC[T], key: ptr byte, ulen: uint) =
  188. const sizeBlock = hmctx.sizeBlock
  189. echo sizeBlock
  190. proc hmac*[A, B](HashType: typedesc, key: openArray[A],
  191. data: openArray[B]) =
  192. var ctx: HMAC[HashType]
  193. ctx.init(nil, 0)
  194. sha256.hmac("", "")
  195. # nested generic types
  196. block:
  197. type
  198. Foo[T] = object
  199. f: T
  200. Bar[T] = object
  201. b: T
  202. Baz[T] = object
  203. z: T
  204. FooBar[T] = Foo[Bar[T]]
  205. FooBarBaz[T] = FooBar[Baz[T]]
  206. #Int = int
  207. Int = SomeInteger
  208. FooBarBazInt = FooBarBaz[Int]
  209. FooBarBazX = FooBarBaz[int]
  210. proc p00(x: Foo): auto = x.f
  211. proc p01[T](x: Foo[T]): auto = x.f
  212. proc p02[T:Foo](x: T): auto = x.f
  213. proc p10(x: FooBar): auto = x.f
  214. proc p11[T](x: FooBar[T]): auto = x.f
  215. proc p12[T:FooBar](x: T): auto = x.f
  216. proc p13(x: Foo[Bar]): auto = x.f
  217. proc p14[T](x: Foo[Bar[T]]): auto = x.f
  218. proc p15[T:Bar](x: Foo[T]): auto = x.f
  219. proc p16[T:Foo[Bar]](x: T): auto = x.f
  220. proc p20(x: FooBarBaz): auto = x.f
  221. proc p21[T](x: FooBarBaz[T]): auto = x.f
  222. proc p22[T:FooBarBaz](x: T): auto = x.f
  223. proc p23(x: FooBar[Baz]): auto = x.f
  224. proc p24[T](x: FooBar[Baz[T]]): auto = x.f
  225. proc p25[T:Baz](x: FooBar[T]): auto = x.f
  226. proc p26[T:FooBar[Baz]](x: T): auto = x.f
  227. proc p27(x: Foo[Bar[Baz]]): auto = x.f
  228. proc p28[T](x: Foo[Bar[Baz[T]]]): auto = x.f
  229. proc p29[T:Baz](x: Foo[Bar[T]]): auto = x.f
  230. proc p2A[T:Bar[Baz]](x: Foo[T]): auto = x.f
  231. proc p2B[T:Foo[Bar[Baz]]](x: T): auto = x.f
  232. proc p30(x: FooBarBazInt): auto = x.f
  233. proc p31[T:FooBarBazInt](x: T): auto = x.f
  234. proc p32(x: FooBarBaz[Int]): auto = x.f
  235. proc p33[T:Int](x: FooBarBaz[T]): auto = x.f
  236. proc p34[T:FooBarBaz[Int]](x: T): auto = x.f
  237. proc p35(x: FooBar[Baz[Int]]): auto = x.f
  238. proc p36[T:Int](x: FooBar[Baz[T]]): auto = x.f
  239. proc p37[T:Baz[Int]](x: FooBar[T]): auto = x.f
  240. proc p38[T:FooBar[Baz[Int]]](x: T): auto = x.f
  241. proc p39(x: Foo[Bar[Baz[Int]]]): auto = x.f
  242. proc p3A[T:Int](x: Foo[Bar[Baz[T]]]): auto = x.f
  243. proc p3B[T:Baz[Int]](x: Foo[Bar[T]]): auto = x.f
  244. proc p3C[T:Bar[Baz[Int]]](x: Foo[T]): auto = x.f
  245. proc p3D[T:Foo[Bar[Baz[Int]]]](x: T): auto = x.f
  246. template test(x: typed) =
  247. let t00 = p00(x)
  248. let t01 = p01(x)
  249. let t02 = p02(x)
  250. let t10 = p10(x)
  251. let t11 = p11(x)
  252. let t12 = p12(x)
  253. #let t13 = p13(x)
  254. let t14 = p14(x)
  255. #let t15 = p15(x)
  256. #let t16 = p16(x)
  257. let t20 = p20(x)
  258. let t21 = p21(x)
  259. let t22 = p22(x)
  260. #let t23 = p23(x)
  261. let t24 = p24(x)
  262. #let t25 = p25(x)
  263. #let t26 = p26(x)
  264. #let t27 = p27(x)
  265. let t28 = p28(x)
  266. #let t29 = p29(x)
  267. #let t2A = p2A(x)
  268. #let t2B = p2B(x)
  269. let t30 = p30(x)
  270. let t31 = p31(x)
  271. let t32 = p32(x)
  272. let t33 = p33(x)
  273. let t34 = p34(x)
  274. let t35 = p35(x)
  275. let t36 = p36(x)
  276. let t37 = p37(x)
  277. let t38 = p38(x)
  278. let t39 = p39(x)
  279. let t3A = p3A(x)
  280. let t3B = p3B(x)
  281. let t3C = p3C(x)
  282. let t3D = p3D(x)
  283. var a: Foo[Bar[Baz[int]]]
  284. test(a)
  285. var b: FooBar[Baz[int]]
  286. test(b)
  287. var c: FooBarBaz[int]
  288. test(c)
  289. var d: FooBarBazX
  290. test(d)
  291. # overloading on tuples with generic alias
  292. block:
  293. type
  294. Foo[F,T] = object
  295. exArgs: T
  296. FooUn[F,T] = Foo[F,tuple[a:T]]
  297. FooBi[F,T1,T2] = Foo[F,tuple[a:T1,b:T2]]
  298. proc foo1[F,T](x: Foo[F,tuple[a:T]]): int = 1
  299. proc foo1[F,T1,T2](x: Foo[F,tuple[a:T1,b:T2]]): int = 2
  300. proc foo2[F,T](x: FooUn[F,T]): int = 1
  301. proc foo2[F,T1,T2](x: FooBi[F,T1,T2]):int = 2
  302. template bar1[F,T](x: Foo[F,tuple[a:T]]): int = 1
  303. template bar1[F,T1,T2](x: Foo[F,tuple[a:T1,b:T2]]): int = 2
  304. template bar2[F,T](x: FooUn[F,T]): int = 1
  305. template bar2[F,T1,T2](x: FooBi[F,T1,T2]): int = 2
  306. proc test(x: auto, n: int) =
  307. doAssert(foo1(x) == n)
  308. doAssert(foo2(x) == n)
  309. doAssert(bar1(x) == n)
  310. doAssert(bar2(x) == n)
  311. var a: Foo[int, tuple[a:int]]
  312. test(a, 1)
  313. var b: FooUn[int, int]
  314. test(b, 1)
  315. var c: Foo[int, tuple[a:int,b:int]]
  316. test(c, 2)
  317. var d: FooBi[int, int, int]
  318. test(d, 2)
  319. # inheritance and generics
  320. block:
  321. type
  322. Foo[T] = object of RootObj
  323. x: T
  324. Bar[T] = object of Foo[T]
  325. y: T
  326. Baz[T] = object of Bar[T]
  327. z: T
  328. template t0(x: Foo[int]): int = 0
  329. template t0(x: Bar[int]): int = 1
  330. template t0(x: Foo[bool or int]): int = 10
  331. template t0(x: Bar[bool or int]): int = 11
  332. #template t0[T:bool or int](x: Bar[T]): int = 11
  333. template t0[T](x: Foo[T]): int = 20
  334. template t0[T](x: Bar[T]): int = 21
  335. proc p0(x: Foo[int]): int = 0
  336. proc p0(x: Bar[int]): int = 1
  337. #proc p0(x: Foo[bool or int]): int = 10
  338. #proc p0(x: Bar[bool or int]): int = 11
  339. proc p0[T](x: Foo[T]): int = 20
  340. proc p0[T](x: Bar[T]): int = 21
  341. var a: Foo[int]
  342. var b: Bar[int]
  343. var c: Baz[int]
  344. var d: Foo[bool]
  345. var e: Bar[bool]
  346. var f: Baz[bool]
  347. var g: Foo[float]
  348. var h: Bar[float]
  349. var i: Baz[float]
  350. doAssert(t0(a) == 0)
  351. doAssert(t0(b) == 1)
  352. doAssert(t0(c) == 1)
  353. doAssert(t0(d) == 10)
  354. doAssert(t0(e) == 11)
  355. doAssert(t0(f) == 11)
  356. doAssert(t0(g) == 20)
  357. doAssert(t0(h) == 21)
  358. #doAssert(t0(i) == 21)
  359. doAssert(p0(a) == 0)
  360. doAssert(p0(b) == 1)
  361. doAssert(p0(c) == 1)
  362. #doAssert(p0(d) == 10)
  363. #doAssert(p0(e) == 11)
  364. #doAssert(p0(f) == 11)
  365. doAssert(p0(g) == 20)
  366. doAssert(p0(h) == 21)
  367. doAssert(p0(i) == 21)
  368. #type
  369. # f0 = proc(x:Foo)
  370. block:
  371. type
  372. TilesetCT[n: static[int]] = distinct int
  373. TilesetRT = int
  374. Tileset = TilesetCT | TilesetRT
  375. func prepareTileset(tileset: var Tileset) = discard
  376. func prepareTileset(tileset: Tileset): Tileset =
  377. result = tileset
  378. result.prepareTileset
  379. var parsedTileset: TilesetRT
  380. prepareTileset(parsedTileset)
  381. block:
  382. proc p1[T,U: SomeInteger|SomeFloat](x: T, y: U): int|float =
  383. when T is SomeInteger and U is SomeInteger:
  384. result = int(x) + int(y)
  385. else:
  386. result = float(x) + float(y)
  387. doAssert(p1(1,2) == 3)
  388. doAssert(p1(1.0,2) == 3.0)
  389. doAssert(p1(1,2.0) == 3.0)
  390. doAssert(p1(1.0,2.0) == 3.0)
  391. type Foo[T,U] = U
  392. template F[T,U](t: typedesc[T], x: U): untyped = Foo[T,U](x)
  393. proc p2[T; U,V:Foo[T,SomeNumber]](x: U, y: V): T =
  394. T(x) + T(y)
  395. #proc p2[T; U:Foo[T,SomeNumber], V:Foo[not T,SomeNumber]](x: U, y: V): T =
  396. # T(x) + T(y)
  397. doAssert(p2(F(int,1),F(int,2)) == 3)
  398. doAssert(p2(F(float,1),F(float,2)) == 3.0)
  399. doAssert(p2(F(float,1),F(float,2.0)) == 3.0)
  400. doAssert(p2(F(float,1.0),F(float,2)) == 3.0)
  401. doAssert(p2(F(float,1.0),F(float,2.0)) == 3.0)
  402. #doAssert(p2(F(float,1),F(int,2.0)) == 3.0)
  403. block: # PR #23870
  404. type
  405. A {.inheritable.} = object
  406. B = object of A
  407. C = object of B
  408. proc p[T: A](x: T): int = 0
  409. proc p[T: B](x: T): int = 1
  410. proc d(x: A): int = 0
  411. proc d(x: B): int = 1
  412. proc g[T:A](x: typedesc[T]): int = 0
  413. proc g[T: B](x: typedesc[T]): int = 1
  414. proc f[T](x: typedesc[T]): int = 0
  415. proc f[T:B](x: typedesc[T]): int = 1
  416. assert p(C()) == 1
  417. assert d(C()) == 1
  418. assert g(C) == 1
  419. assert f(C) == 1
  420. block: # PR #23870
  421. type
  422. A = object of RootObj
  423. PT = proc(ev: A) {.closure.}
  424. sdt = seq[(PT, PT)]
  425. proc encap() =
  426. proc p(a: A) {.closure.} =
  427. discard
  428. var s: sdt
  429. s.add (p, nil)
  430. encap()
  431. block: # PR #23870
  432. type
  433. A = object of RootObj
  434. B = object of A
  435. C = object of B
  436. proc p(a: B | RootObj): int =
  437. 0
  438. proc p(a: A | A): int =
  439. 1
  440. assert p(C()) == 0
  441. proc d(a: RootObj | B): int =
  442. 0
  443. proc d(a: A | A): int =
  444. 1
  445. assert d(C()) == 0