Bug in try-except rewrite of `except T as e`
alaviss opened this issue · comments
import cps
proc noop(c: Continuation): Continuation {.cpsMagic.} = c
var r = 0
proc foo() {.cps: Continuation.} =
try:
noop()
inc r
raise newException(ValueError, "something")
except ValueError as e:
inc r
doAssert typeof(e) is ValueError
foo()
doAssert r == 2
/home/leorize/source/cps/test.nim(16) test
/home/leorize/source/cps/test.nim(7) foo
/home/leorize/source/cps/test.nim(14) Except
/usr/lib/nim/lib/system/assertions.nim(39) failedAssertImpl
/usr/lib/nim/lib/system/assertions.nim(29) raiseAssert
/usr/lib/nim/lib/system/fatal.nim(53) sysFatal
Error: unhandled exception: /home/leorize/source/cps/test.nim(14, 14) `typeof(e) is ValueError` [AssertionDefect]
We are rewriting e
into the continuation's exception, which is ex
and it has type ref Exception
...
I see two possible solutions:
- We de-sugar
except T as e
intoexcept T: let e = (ref T)(getCurrentException())
- We rewrite
e
into(ref T)(ex)
The second solution come with the cost of checked conversion on every access to this local, so maybe the first solution makes more sense.