nim-works / cps

Continuation-Passing Style for Nim 🔗

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 into except 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.