Nim: Yield in try generate stack error

Created on 6 Jun 2018  路  10Comments  路  Source: nim-lang/Nim

The following code is extracted from the my project. I cannot re-produce the error with simple code.

      block:
         info "Collect data start", start_time = $$start_time, end_time = $$end_time
         let timer = Timer.start
         await collect_once(dsid, tag_infos, start_time, end_time)
         info "Collect data end", start_time = $$start_time, end_time = $$end_time, elpase = timer

The code compiles generate the following error:

Traceback (most recent call last)
nim.nim(114) nim
nim.nim(78) handleCmdLine
main.nim(169) mainCommand
main.nim(79) commandCompileToC
modules.nim(141) compileProject
modules.nim(78) compileModule
passes.nim(238) processModule
passes.nim(126) processTopLevelStmt
sem.nim(586) myProcess
sem.nim(554) semStmtAndGenerateGenerics
semstmts.nim(1875) semStmt
semexprs.nim(815) semExprNoType
semexprs.nim(2464) semExpr
importer.nim(189) evalImport
importer.nim(166) impMod
importer.nim(149) myImportModule
modules.nim(102) importModule
modules.nim(78) compileModule
passes.nim(238) processModule
passes.nim(126) processTopLevelStmt
sem.nim(586) myProcess
sem.nim(554) semStmtAndGenerateGenerics
semstmts.nim(1875) semStmt
semexprs.nim(815) semExprNoType
semexprs.nim(2449) semExpr
semstmts.nim(1672) semProc
semstmts.nim(1453) semProcAux
semstmts.nim(1188) semProcAnnotation
semexprs.nim(2318) semExpr
semexprs.nim(799) semDirectOp
semexprs.nim(695) afterCallActions
(1874 calls omitted) ...
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
closureiters.nim(255) hasYields
ast.nim(1640) hasYields
ast.nim safeLen
Stack overflow

Async

Most helpful comment

@yglukhov

Found the problem line.

import asyncdispatch

type
   Foo* = object
      id*: int
      y*: int

proc f2(): Future[Foo] {.async.} =
   return Foo()

proc f1(): Future[int] {.async.} =
   return (await f2()).y

The last line is the problem.
If I change to:

let f = await f2()
return f.y

Everything is fine.

All 10 comments

@slangmgh, is your project opensource? If not, can you ping me on gitter/irc/matrix/skype?

@yglukhov
It's not open source, I will try isolate the problem, if not, I can send the project to you through e-mail.

@yglukhov

Found the problem line.

import asyncdispatch

type
   Foo* = object
      id*: int
      y*: int

proc f2(): Future[Foo] {.async.} =
   return Foo()

proc f1(): Future[int] {.async.} =
   return (await f2()).y

The last line is the problem.
If I change to:

let f = await f2()
return f.y

Everything is fine.

@yglukhov

The following code quit the compiler:

proc f3(): Future[void] {.async} =
   let n = 3
   case n
   of 1,2:
      await sleepAsync(10)
   else:
      discard

when isMainModule:
   waitFor f3()

The problem line is 'of 1, 2:', if change to 'of 1:', compile ok.

@slangmgh pls check out #7971. Anything else? :)

@yglukhov

Everything is fine, thank you.
I am waiting for yield-in-try for long time. :)

Wait, there is still bugs. :(

When I edit some code irrelevant to the async, but the compiler quit with internal error.

The following code quit the compiler.

import chronicles, terminal, os, strformat

proc sleep_check_ctrl_c(t: int) =
   const sleep_time = 1000
   var t = t
   let pout = stderr
   if t > 0: sleep(t)

   pout.write(ansiResetCode)
   pout.write("\e[2K")
   #let stylePrefix = "\e["
   #pout.write(fmt"{stylePrefix}0G")
   pout.write("\e[?25h")

chronicles is needed to make the compiler crash. it is from status-im/chronicles.

And if we change the code a little bit, like uncomment the last two line, or delete the last line, or delete the line 'const sleep_time = 1000', compile is fine.

@slangmgh, that's not related to yield-in-try. Please file another issue for that.

@yglukhov

Fine. :)

Was this page helpful?
0 / 5 - 0 ratings