mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-17 18:44:53 +00:00
…ult is never destroyed fixes #26094 Conceptually, the new lowering for `destination = raisingCall()` is: ```nim var tmp: T try: tmp = raisingCall() let value = tmp wasMoved(tmp) destination = value finally: destroy(tmp) ``` So whether `raisingCall` Succeeds or not, `tmp` is destroyed --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
68 lines
1.3 KiB
Nim
68 lines
1.3 KiB
Nim
discard """
|
|
valgrind: true
|
|
cmd: "nim c -d:useMalloc $file"
|
|
matrix: "--mm:arc; --mm:orc"
|
|
disabled: "freebsd"
|
|
disabled: "osx"
|
|
disabled: "openbsd"
|
|
disabled: "windows"
|
|
disabled: "32bit"
|
|
"""
|
|
|
|
import std/options
|
|
|
|
type Foo = object
|
|
id: string
|
|
items: seq[string]
|
|
|
|
proc build(x: int): Foo =
|
|
result = Foo(id: "padding-padding", items: @["a", "b", "c"])
|
|
if x < 0:
|
|
raise newException(ValueError, "boom")
|
|
|
|
proc parseResult(x: int): Foo =
|
|
try:
|
|
result = build(x)
|
|
except CatchableError:
|
|
result = default(Foo)
|
|
|
|
proc parseVar(x: int; dst: var Foo): bool =
|
|
dst = build(x)
|
|
result = true
|
|
|
|
proc parseOption(x: int): Option[Foo] =
|
|
result = some(build(x))
|
|
|
|
const iterations = 10_000
|
|
|
|
doAssert parseResult(1).items == @["a", "b", "c"]
|
|
|
|
var successfulDst: Foo
|
|
doAssert parseVar(1, successfulDst)
|
|
doAssert successfulDst.id == "padding-padding"
|
|
|
|
doAssert parseOption(1).get.items == @["a", "b", "c"]
|
|
|
|
var unchangedDst = Foo(id: "old", items: @["old"])
|
|
try:
|
|
discard parseVar(-1, unchangedDst)
|
|
except CatchableError:
|
|
discard
|
|
doAssert unchangedDst == Foo(id: "old", items: @["old"])
|
|
|
|
for _ in 0 ..< iterations:
|
|
discard parseResult(-1)
|
|
|
|
for _ in 0 ..< iterations:
|
|
var dst: Foo
|
|
try:
|
|
discard parseVar(-1, dst)
|
|
except CatchableError:
|
|
discard
|
|
|
|
for _ in 0 ..< iterations:
|
|
try:
|
|
discard parseOption(-1)
|
|
except CatchableError:
|
|
discard
|