tmacroinjectedsym.nim 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. {.experimental: "genericsOpenSym".}
  2. block: # issue #22605, normal call syntax
  3. const error = "bad"
  4. template valueOr(self: int, def: untyped): untyped =
  5. case false
  6. of true: ""
  7. of false:
  8. template error: untyped {.used, inject.} = "good"
  9. def
  10. proc g(T: type): string =
  11. let x = valueOr 123:
  12. return $error
  13. "ok"
  14. doAssert g(int) == "good"
  15. proc g2(T: type): string =
  16. bind error # use the bad version on purpose
  17. let x = valueOr 123:
  18. return $error
  19. "ok"
  20. doAssert g2(int) == "bad"
  21. block: # issue #22605, method call syntax
  22. const error = "bad"
  23. template valueOr(self: int, def: untyped): untyped =
  24. case false
  25. of true: ""
  26. of false:
  27. template error: untyped {.used, inject.} = "good"
  28. def
  29. proc g(T: type): string =
  30. let x = 123.valueOr:
  31. return $error
  32. "ok"
  33. doAssert g(int) == "good"
  34. proc g2(T: type): string =
  35. bind error # use the bad version on purpose
  36. let x = 123.valueOr:
  37. return $error
  38. "ok"
  39. doAssert g2(int) == "bad"
  40. block: # issue #22605, original complex example
  41. type Xxx = enum
  42. error
  43. value
  44. type
  45. Result[T, E] = object
  46. when T is void:
  47. when E is void:
  48. oResultPrivate*: bool
  49. else:
  50. case oResultPrivate*: bool
  51. of false:
  52. eResultPrivate*: E
  53. of true:
  54. discard
  55. else:
  56. when E is void:
  57. case oResultPrivate*: bool
  58. of false:
  59. discard
  60. of true:
  61. vResultPrivate*: T
  62. else:
  63. case oResultPrivate*: bool
  64. of false:
  65. eResultPrivate*: E
  66. of true:
  67. vResultPrivate*: T
  68. template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped =
  69. let s = (self) # TODO avoid copy
  70. case s.oResultPrivate
  71. of true:
  72. s.vResultPrivate
  73. of false:
  74. when E isnot void:
  75. template error: untyped {.used, inject.} = s.eResultPrivate
  76. def
  77. proc f(): Result[int, cstring] =
  78. Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
  79. proc g(T: type): string =
  80. let x = f().valueOr:
  81. return $error
  82. "ok"
  83. doAssert g(int) == "f"
  84. proc g2(T: type): string =
  85. bind error # use the bad version on purpose
  86. let x = f().valueOr:
  87. return $error
  88. "ok"
  89. doAssert g2(int) == "error"
  90. block: # issue #23865
  91. type Xxx = enum
  92. error
  93. value
  94. type
  95. Result[T, E] = object
  96. when T is void:
  97. when E is void:
  98. oResultPrivate: bool
  99. else:
  100. case oResultPrivate: bool
  101. of false:
  102. eResultPrivate: E
  103. of true:
  104. discard
  105. else:
  106. when E is void:
  107. case oResultPrivate: bool
  108. of false:
  109. discard
  110. of true:
  111. vResultPrivate: T
  112. else:
  113. case oResultPrivate: bool
  114. of false:
  115. eResultPrivate: E
  116. of true:
  117. vResultPrivate: T
  118. func error[T, E](self: Result[T, E]): E =
  119. ## Fetch error of result if set, or raise Defect
  120. case self.oResultPrivate
  121. of true:
  122. when T isnot void:
  123. raiseResultDefect("Trying to access error when value is set", self.vResultPrivate)
  124. else:
  125. raiseResultDefect("Trying to access error when value is set")
  126. of false:
  127. when E isnot void:
  128. self.eResultPrivate
  129. template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped =
  130. let s = (self) # TODO avoid copy
  131. case s.oResultPrivate
  132. of true:
  133. s.vResultPrivate
  134. of false:
  135. when E isnot void:
  136. template error: untyped {.used, inject.} = s.eResultPrivate
  137. def
  138. proc f(): Result[int, cstring] =
  139. Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
  140. proc g(T: type): string =
  141. let x = f().valueOr:
  142. return $error
  143. "ok"
  144. doAssert g(int) == "f"
  145. import sequtils
  146. block: # issue #12283
  147. var b = 5
  148. type Foo[T] = object
  149. h, w: int
  150. proc bar[T](foos: seq[Foo[T]]): T =
  151. let w = foldl(foos, a + b.w, 0)
  152. w
  153. let foos = @[Foo[int](h: 3, w: 5), Foo[int](h: 4, w: 6)]
  154. doAssert bar(foos) == 11