123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- {.experimental: "templateOpenSym".}
- block: # issue #24002
- type Result[T, E] = object
- func value[T, E](self: Result[T, E]): T {.inline.} =
- discard
- func value[T: not void, E](self: var Result[T, E]): var T {.inline.} =
- discard
- template unrecognizedFieldWarning =
- doAssert value == 123
- let x = value
- doAssert value == x
- proc readValue(value: var int) =
- unrecognizedFieldWarning()
- var foo: int = 123
- readValue(foo)
- block: # issue #22605 for templates, normal call syntax
- const error = "bad"
- template valueOr(self: int, def: untyped): untyped =
- case false
- of true: ""
- of false:
- template error: untyped {.used, inject.} = "good"
- def
- template g(T: type): string =
- var res = "ok"
- let x = valueOr 123:
- res = $error
- "dummy"
- res
- doAssert g(int) == "good"
- template g2(T: type): string =
- bind error # use the bad version on purpose
- var res = "ok"
- let x = valueOr 123:
- res = $error
- "dummy"
- res
- doAssert g2(int) == "bad"
- block: # issue #22605 for templates, method call syntax
- const error = "bad"
- template valueOr(self: int, def: untyped): untyped =
- case false
- of true: ""
- of false:
- template error: untyped {.used, inject.} = "good"
- def
- template g(T: type): string =
- var res = "ok"
- let x = 123.valueOr:
- res = $error
- "dummy"
- res
- doAssert g(int) == "good"
- template g2(T: type): string =
- bind error # use the bad version on purpose
- var res = "ok"
- let x = 123.valueOr:
- res = $error
- "dummy"
- res
- doAssert g2(int) == "bad"
- block: # issue #22605 for templates, original complex example
- type Xxx = enum
- error
- value
- type
- Result[T, E] = object
- when T is void:
- when E is void:
- oResultPrivate*: bool
- else:
- case oResultPrivate*: bool
- of false:
- eResultPrivate*: E
- of true:
- discard
- else:
- when E is void:
- case oResultPrivate*: bool
- of false:
- discard
- of true:
- vResultPrivate*: T
- else:
- case oResultPrivate*: bool
- of false:
- eResultPrivate*: E
- of true:
- vResultPrivate*: T
- template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped =
- let s = (self) # TODO avoid copy
- case s.oResultPrivate
- of true:
- s.vResultPrivate
- of false:
- when E isnot void:
- template error: untyped {.used, inject.} = s.eResultPrivate
- def
- proc f(): Result[int, cstring] =
- Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
- template g(T: type): string =
- var res = "ok"
- let x = f().valueOr:
- res = $error
- 123
- res
- doAssert g(int) == "f"
- template g2(T: type): string =
- bind error # use the bad version on purpose
- var res = "ok"
- let x = f().valueOr:
- res = $error
- 123
- res
- doAssert g2(int) == "error"
- block: # issue #23865 for templates
- type Xxx = enum
- error
- value
- type
- Result[T, E] = object
- when T is void:
- when E is void:
- oResultPrivate: bool
- else:
- case oResultPrivate: bool
- of false:
- eResultPrivate: E
- of true:
- discard
- else:
- when E is void:
- case oResultPrivate: bool
- of false:
- discard
- of true:
- vResultPrivate: T
- else:
- case oResultPrivate: bool
- of false:
- eResultPrivate: E
- of true:
- vResultPrivate: T
- func error[T, E](self: Result[T, E]): E =
- ## Fetch error of result if set, or raise Defect
- case self.oResultPrivate
- of true:
- when T isnot void:
- raiseResultDefect("Trying to access error when value is set", self.vResultPrivate)
- else:
- raiseResultDefect("Trying to access error when value is set")
- of false:
- when E isnot void:
- self.eResultPrivate
- template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped =
- let s = (self) # TODO avoid copy
- case s.oResultPrivate
- of true:
- s.vResultPrivate
- of false:
- when E isnot void:
- template error: untyped {.used, inject.} = s.eResultPrivate
- def
- proc f(): Result[int, cstring] =
- Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
- template g(T: type): string =
- var res = "ok"
- let x = f().valueOr:
- res = $error
- 123
- res
- doAssert g(int) == "f"
- import std/sequtils
- block: # issue #15314
- var it: string
- var nums = @[1,2,3]
- template doubleNums() =
- nums.applyIt(it * 2)
- doubleNums()
- doAssert nums == @[2, 4, 6]
|