trfc405.nim 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. {.experimental: "flexibleOptionalParams".}
  2. # https://github.com/nim-lang/RFCs/issues/405
  3. template main =
  4. template fn1(a = 1, b = 2, body): auto = (a, b, astToStr(body))
  5. let a1 = fn1(10, 20):
  6. foo
  7. doAssert a1 == (10, 20, "\nfoo")
  8. template fn2(a = 1, b = 2, body): auto = (a, b, astToStr(body))
  9. let a2 = fn2(a = 10): foo
  10. doAssert a2 == (10, 2, "\nfoo")
  11. let a2b = fn2(b = 20): foo
  12. doAssert a2b == (1, 20, "\nfoo")
  13. template fn3(x: int, a = 1, b = 2, body): auto = (a, b, astToStr(body))
  14. let a3 = fn3(3, 10, 20): foo
  15. doAssert a3 == (10, 20, "\nfoo")
  16. let a3b = fn3(3, a = 10): foo
  17. doAssert a3b == (10, 2, "\nfoo")
  18. template fn4(x: int, y: int, body): auto = (x, y, astToStr(body))
  19. let a4 = fn4(1, 2): foo
  20. doAssert a4 == (1, 2, "\nfoo")
  21. template fn5(x = 1, y = 2, body: untyped = 3): auto = (x, y, astToStr(body))
  22. doAssert compiles(fn5(1, 2, foo))
  23. doAssert not compiles(fn5(1, foo))
  24. block:
  25. # with an overload
  26. var witness = 0
  27. template fn6() = discard
  28. template fn6(procname: string, body: untyped): untyped = witness.inc
  29. fn6("abc"): discard
  30. assert witness == 1
  31. block:
  32. # with overloads
  33. var witness = 0
  34. template fn6() = discard
  35. template fn6(a: int) = discard
  36. template fn6(procname: string, body: untyped): untyped = witness.inc
  37. fn6("abc"): discard
  38. assert witness == 1
  39. template fn6(b = 1.5, body: untyped): untyped = witness.inc
  40. fn6(1.3): discard
  41. assert witness == 2
  42. block:
  43. var witness = 0
  44. template fn6(a: int) = discard
  45. template fn6(a: string) = discard
  46. template fn6(ignore: string, b = 1.5, body: untyped): untyped = witness.inc
  47. fn6(""):
  48. foobar1
  49. foobar2
  50. doAssert witness == 1
  51. fn6(""): discard
  52. doAssert witness == 2
  53. block: # multi block args
  54. template fn8(a = 1, b = 2, body1: untyped, body2: untyped): auto = (a, b, astToStr(body1), astToStr(body2))
  55. let a1 = fn8():
  56. foobar1
  57. foobar2
  58. do:
  59. foobar3
  60. foobar4
  61. doAssert a1 == (1, 2, "\nfoobar1\nfoobar2", "\nfoobar3\nfoobar4")
  62. let a2 = fn8(b = 20):
  63. foobar1
  64. foobar2
  65. do:
  66. foobar3
  67. foobar4
  68. doAssert a2 == (1, 20, "\nfoobar1\nfoobar2", "\nfoobar3\nfoobar4")
  69. block: # issue #19015
  70. template hi(a: untyped, b: varargs[untyped]): untyped =
  71. a
  72. var worked = false
  73. hi:
  74. worked = true
  75. doAssert worked
  76. worked = false
  77. hi(doAssert(not worked)):
  78. doesntCompile
  79. hi(doAssert(not worked), doesntCompile, againDoesntCompile):
  80. definitelyDoesntCompile
  81. template hi2(a: bool, b: untyped, c: varargs[untyped]): untyped =
  82. b
  83. doAssert a
  84. hi2 worked:
  85. worked = true
  86. doAssert worked
  87. hi2 worked, doAssert(worked):
  88. doesntCompile
  89. hi2 worked, doAssert(worked), doesntCompile, againDoesntCompile:
  90. definitelyDoesntCompile
  91. hi2 worked, doAssert(worked), againDoesntCompile:
  92. definitelyDoesntCompile
  93. static: main()
  94. main()