nim-works / cps

Continuation-Passing Style for Nim 🔗

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cps calls with variant object member fails due to lack of types

alaviss opened this issue · comments

Sample code:

import cps

type
  O = object
    case switch: bool
    of true: x: int
    of false: discard

proc noop(c: Continuation): Continuation {.cpsMagic.} = c

proc doThings(x: int) {.cps: Continuation.} = discard

proc foo(o: O) {.cps: Continuation.} =
  noop()
  case o.switch
  of true: doThings(o.x)
  else: discard

discard trampoline whelp(foo(O(switch: true, x: 10)))

Error:

cps/test.nim(16, 20) Error: type mismatch
Expression: doThings(cps:foo() env_553650071(continuation).o_553650072.x)
  [1] cps:foo() env_553650071(continuation).o_553650072.x: void

Expected one of (first mismatch at [position]):
[1] proc doThings(x: int)

Transform output:

=== cpsTransform on foo(original) === /home/leorize/Documents/sources/cps/test.nim(13, 0)
 13  proc foo(o: O) =
 14    noop()
 15    case o.switch
 16    of true:
 17      doThings(o.x)
 18    else:
 19      discard
 20
=== cpsTransform on foo(transformed) === /home/leorize/Documents/sources/cps/test.nim(13, 0)
 13
 14  {.push, hint[ConvFromXtoItselfNotNeeded]: off.}
 15  type
 16    cps:foo() env_553650071 = ref object of Continuation
 17      o_553650072: O
 18      child_553650127: cps:doThings() env_553648355
 19
 20  cpsFloater(cpsResolver(cps:foo() env_553650071, Continuation, cpsManageException(
 21      "foo()", cpsHandleUnhandledException(Continuation, proc foo_553650073(
 22      continuation: sink Continuation): Continuation {.used, cpsCont.} =
 23    mixin tail
 24    mixin head
 25    mixin pass
 26    mixin dealloc
 27    mixin alloc
 28    mixin trace
 29    mixin coop
 30    trace(Trace, continuation, foo_553650073, fun = "foo_553650073", info = LineInfo(
 31        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
 32        column: 0), nil)
 33    cpsJump(continuation, Continuation, "foo()", noop()):
 34      case cps:foo() env_553650071(continuation).o_553650072.switch
 35      of true:
 36        cpsContinuationJump(continuation, Continuation, "foo()",
 37                            doThings(cps:foo() env_553650071(continuation).o_553650072.x),
 38                            cps:foo() env_553650071(continuation).child_553650127) do:
 39      else:
 40        discard
 41    {.cpsPending.}
 42
 43  ))))
 44  proc cps:foo() recover_553650128(continuation: var Continuation) {.used, nimcall.} =
 45    case continuation.state
 46    of State(1):
 47      raise Defect.newException do:
 48        "dismissed continuations have no result"
 49    of State(2):
 50      discard
 51    of State(0):
 52      var base`gensym45: Continuation = move continuation
 53      defer:
 54        continuation = cps:foo() env_553650071(move base`gensym45)
 55      base`gensym45 = trampoline(base`gensym45)
 56      cps:foo() recover_553650128(base`gensym45)
 57
 58  proc recover(continuation: var cps:foo() env_553650071) {.used, nimcall.} =
 59    var base`gensym45: Continuation = move continuation
 60    defer:
 61      continuation = cps:foo() env_553650071(move base`gensym45)
 62    cps:foo() recover_553650128(base`gensym45)
 63
 64  {.push, experimental: "callOperator".}
 65  proc callOperatorStar(c`gensym46: var cps:foo() env_553650071) {.used, nimcall.} =
 66    recover(c`gensym46)
 67
 68  {.pop.}
 69  proc cps:foo() whelp_553650074(o: O): cps:foo() env_553650071 {.used, nimcall,
 70      cpsEnvironment: cps:foo() env_553650071, cpsResult: cps:foo() recover_553650128,
 71      cpsReturnType: void.} =
 72    mixin stack
 73    mixin boot
 74    mixin alloc
 75    result = trace(Alloc, Continuation, cps:foo() env_553650071,
 76                   fun = "cps:foo() env", info = LineInfo(
 77        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
 78        column: 22), alloc(Continuation, cps:foo() env_553650071))
 79    cps:foo() env_553650071(result).o_553650072 = o
 80    cps:foo() env_553650071(result).fn = foo_553650073
 81    result = trace(Stack, TraceFrame(hook: Hook(9), info: LineInfo(
 82        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
 83        column: 0), fun: "foo"), cps:foo() env_553650071, fun = "cps:foo() env", info = LineInfo(
 84        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
 85        column: 0), stack(TraceFrame(hook: Hook(9), info: LineInfo(
 86        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
 87        column: 0), fun: "foo"), cps:foo() env_553650071(trace(Boot, nil,
 88        Continuation, fun = "Continuation", info = LineInfo(
 89        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
 90        column: 0), boot(Continuation(result))))))
 91
 92  proc cps:foo() callback_553650079(o: O): Continuation {.
 93      cpsResult: cps:foo() recover_553650128, cpsReturnType: void.} =
 94    Continuation(cps:foo() whelp_553650074(o))
 95
 96  proc foo(o: O) {.used, nimcall, cpsBootstrap: cps:foo() whelp_553650074,
 97                   cpsCallbackShim: cps:foo() callback_553650079, cpsMustJump,
 98                   cpsEnvironment: cps:foo() env_553650071,
 99                   cpsResult: cps:foo() recover_553650128.} =
100    mixin stack
101    mixin boot
102    mixin alloc
103    var c_553650080: Continuation
104    c_553650080 = trace(Alloc, Continuation, cps:foo() env_553650071,
105                        fun = "cps:foo() env", info = LineInfo(
106        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
107        column: 22), alloc(Continuation, cps:foo() env_553650071))
108    cps:foo() env_553650071(c_553650080).o_553650072 = o
109    cps:foo() env_553650071(c_553650080).fn = foo_553650073
110    c_553650080 = trace(Head, nil, trace, fun = "trace", info = LineInfo(
111        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
112        column: 0), head(trace(Stack, TraceFrame(hook: Hook(9), info: LineInfo(
113        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
114        column: 0), fun: "foo"), trace, fun = "trace", info = LineInfo(
115        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
116        column: 0), stack(TraceFrame(hook: Hook(9), info: LineInfo(
117        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
118        column: 0), fun: "foo"), trace(Boot, nil, c_553650080, fun = "c", info = LineInfo(
119        filename: "/home/leorize/Documents/sources/cps/test.nim", line: 13,
120        column: 0), boot(c_553650080))))))
121    c_553650080 = trampoline(c_553650080)
122
123  {.pop.}

Nim version:

Nim Compiler Version 1.9.5 [Linux: amd64]
Compiled at 2023-07-06
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 7616e6ee2b48a3c3504684f3324a42e95bd73790
active boot switches: -d:release -d:danger