Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{.compileTime.} tuple destructuring - crash on 0.20, bad codegen on 0.19 #11634

Closed
mratsim opened this issue Jul 1, 2019 · 5 comments · Fixed by #21146
Closed

{.compileTime.} tuple destructuring - crash on 0.20, bad codegen on 0.19 #11634

mratsim opened this issue Jul 1, 2019 · 5 comments · Fixed by #21146

Comments

@mratsim
Copy link
Collaborator

mratsim commented Jul 1, 2019

I'm encountering a couple of issues when experimenting with a deep learning compiler proof of concept in Nim.

Unfortunately the repro code is about 1000 lines but for my experiments purposes everything his kept in a single file so is reproducible with a simple nim c foo.nim.
Edit: Found a minimal repro code, see my 3rd comment

The following code works (e11), the only caveat is the API I highlighted which uses global {.compileTime.} variables.

So in another experiment (e12) I kept the backend procs but added a couple of procs to try another API, the extra generate macro generates a block with compile-time function evaluation that should be equivalent to e11.

# Output of generate in e12 according to `toStrLit`
block generated_foobar_286080:
  let a {.compileTime.} = input(0)
  let b {.compileTime.} = input(1)
  let c {.compileTime.} = input(2)
  let (bar {.compileTime.}, baz {.compileTime.}, buzz {.compileTime.}) = static(
      foobar(a, b, c))

The strange thing is that:

  • On 0.20.x the compiler crashes with SIGSEGV after toStrLit
  • On 0.19.6 compilation is successful but running the binary crashes at runtime with
Traceback (most recent call last)
e12_syntax_revamp.nim(1070) e12_syntax_revamp
gc.nim(186)              asgnRefNoCycle
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

The C code also includes the code for my AstNode variant type even though it is supposed to only exist at compile-time.

@mratsim
Copy link
Collaborator Author

mratsim commented Jul 2, 2019

Here is the compiler stacktrace on current devel

Hint: tables [Processing]
block generated_foobar_341131:
  let a {.compileTime.} = input(0)
  let b {.compileTime.} = input(1)
  let c {.compileTime.} = input(2)
  let (bar {.compileTime.}, baz {.compileTime.}, buzz {.compileTime.}) = static(
      foobar(a, b, c))
Traceback (most recent call last)
/home/beta/Programming/Nim/Nim/compiler/nim.nim(98) nim
/home/beta/Programming/Nim/Nim/compiler/nim.nim(75) handleCmdLine
/home/beta/Programming/Nim/Nim/compiler/cmdlinehelper.nim(92) loadConfigsAndRunMainCommand
/home/beta/Programming/Nim/Nim/compiler/main.nim(194) mainCommand
/home/beta/Programming/Nim/Nim/compiler/main.nim(90) commandCompileToC
/home/beta/Programming/Nim/Nim/compiler/modules.nim(147) compileProject
/home/beta/Programming/Nim/Nim/compiler/modules.nim(88) compileModule
/home/beta/Programming/Nim/Nim/compiler/passes.nim(197) processModule
/home/beta/Programming/Nim/Nim/compiler/passes.nim(86) processTopLevelStmt
/home/beta/Programming/Nim/Nim/compiler/sem.nim(603) myProcess
/home/beta/Programming/Nim/Nim/compiler/sem.nim(571) semStmtAndGenerateGenerics
/home/beta/Programming/Nim/Nim/compiler/semstmts.nim(2184) semStmt
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(980) semExprNoType
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(2712) semExpr
/home/beta/Programming/Nim/Nim/compiler/semstmts.nim(2124) semStmtList
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(2609) semExpr
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(962) semDirectOp
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(854) afterCallActions
/home/beta/Programming/Nim/Nim/compiler/sem.nim(468) semMacroExpr
/home/beta/Programming/Nim/Nim/compiler/sem.nim(411) semAfterMacroCall
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(2711) semExpr
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(2431) semBlock
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(2712) semExpr
/home/beta/Programming/Nim/Nim/compiler/semstmts.nim(2124) semStmtList
/home/beta/Programming/Nim/Nim/compiler/semexprs.nim(2715) semExpr
/home/beta/Programming/Nim/Nim/compiler/semstmts.nim(576) semVarOrLet
/home/beta/Programming/Nim/Nim/compiler/vm.nim(2022) setupCompileTimeVar
/home/beta/Programming/Nim/Nim/compiler/vm.nim(1996) evalConstExprAux
/home/beta/Programming/Nim/Nim/compiler/transf.nim(1159) transformExpr
/home/beta/Programming/Nim/Nim/compiler/transf.nim(1057) processTransf
/home/beta/Programming/Nim/Nim/compiler/transf.nim(1009) transform
/home/beta/Programming/Nim/Nim/compiler/transf.nim(123) transformSons
/home/beta/Programming/Nim/Nim/compiler/transf.nim(1037) transform
/home/beta/Programming/Nim/Nim/compiler/transf.nim(123) transformSons
/home/beta/Programming/Nim/Nim/compiler/transf.nim(909) transform
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
FAILURE

@mratsim
Copy link
Collaborator Author

mratsim commented Jul 2, 2019

Minimal repro code shows that it's the tuple destructuring of {.compileTime.} variables that causes the issues:

  • bad codegen (undeclared idents) on 0.19.6 (I don't have the asgnRefNoCycle with this minimal code)
  • crash on 0.20.x
type Foo = ref object
  val: int

proc divmod(a, b: Foo): (Foo, Foo) =
  (
    Foo(val: a.val div b.val),
    Foo(val: a.val mod b.val)
  )

block:
  let a {.compileTime.} = Foo(val: 2)
  let b {.compileTime.} = Foo(val: 3)
  let (c {.compileTime.}, d {.compileTime.}) = divmod(a, b)

@mratsim mratsim removed the Macros label Jul 2, 2019
@mratsim mratsim changed the title {.compileTime.} statements generated by macro - CT crash 0.20, GC crash 0.19 {.compileTime.} tuple destructuring - crash on 0.20, bad codegen on 0.19 Jul 2, 2019
mratsim added a commit to mratsim/compute-graph-optim that referenced this issue Jul 2, 2019
@mratsim mratsim added VM see also `const` label and removed Static[T] labels Jul 2, 2019
@mratsim
Copy link
Collaborator Author

mratsim commented Jul 2, 2019

Tagging low-priority as we can always assign and then destructure one by one as a workaround.

let cd {.compileTime.} = divmod(a, b)
let c = cd.c
let d = cd.d

@deech
Copy link
Contributor

deech commented Jul 3, 2019

Once I'm done with my PR mixing {.compileTime.} into tuple destructuring will be disallowed, semVarOrLet is a mess.

@wltsmrz
Copy link
Contributor

wltsmrz commented Apr 21, 2020

BTW, not sure if it's exactly the same error but I'm running into compileTime tuple unpacking error

Error: illformed AST: (a, b) = gorgeEx("make -C " & dep_path & " " & "lib")

Allow or disallow, the important thing is that a programmer can determine "Tuple unpacking is not allowed in compile time context" from error message IMO

bung87 added a commit to bung87/Nim that referenced this issue Dec 21, 2022
@bung87 bung87 mentioned this issue Dec 21, 2022
Araq pushed a commit that referenced this issue Dec 23, 2022
survivorm pushed a commit to survivorm/Nim that referenced this issue Feb 28, 2023
capocasa pushed a commit to capocasa/Nim that referenced this issue Mar 31, 2023
narimiran pushed a commit that referenced this issue Apr 26, 2023
(cherry picked from commit ca9c743)
narimiran pushed a commit that referenced this issue Apr 26, 2023
(cherry picked from commit ca9c743)
bung87 added a commit to bung87/Nim that referenced this issue Jul 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants