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

iterator with inner procs produces internal error: inconsistent environment type #21242

Open
dxxb opened this issue Jan 8, 2023 · 10 comments
Open

Comments

@dxxb
Copy link

dxxb commented Jan 8, 2023

Description

The following code will trigger the issue.

iterator iterSome(): int =

  proc inner1() =
    let something = 6
    proc inner2() =
      let othersomething = something
    inner2()

  for n in 0 .. 10:
    inner1()
    yield n

proc test() =
  proc test1() =
    for v in iterSome():
      discard
  test1()

test()

Nim Version

$ nim -v
Nim Compiler Version 1.9.1 [MacOSX: amd64]
Compiled at 2023-01-07
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: b34412ff0fb450278d8c93f6e5d7bf0e8d3f0a0b
active boot switches: -d:release

and

$ nim -v
Nim Compiler Version 1.6.10 [MacOSX: amd64]
Compiled at 2022-12-01
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release

Current Output

$ nim r iteratorEnv.nim
Hint: used config file '~/.choosenim/toolchains/nim-1.6.10/config/nim.cfg' [Conf]
Hint: used config file '~/.choosenim/toolchains/nim-1.6.10/config/config.nims' [Conf]
.........................................................
~/Documents/projects/nimbugreports/iteratorEnv.nim(7, 11) Hint: 'othersomething' is declared but not used [XDeclaredButNotUsed]
~/Documents/projects/nimbugreports/iteratorEnv.nim(6, 10) Error: internal error: inconsistent environment type

Expected Output

I expect the compiler to not error out :wink:

Possible Solution

No response

Additional Information

I believe I encountered this issue a few times in the last month or so but only found time now to distill a minimal test case to reproduce it. In this instance the issue appeared when using npeg (https://github.com/zevv/npeg) in an iterator like so:

iterator iter(path: string): Stuff =
  let parser = peg("line", s: Stuff):
    [...]
  for line in path.lines:
    [...]

I could not find an existing issue matching what I am seeing.

@dxxb
Copy link
Author

dxxb commented Jan 8, 2023

The following will also produce the same result.

iterator iterSome(): int =

  let something = 6
  proc inner1() =
    let othersomething = something
  inner1()

  for n in 0 .. 10:
    inner1()
    yield n

proc test() =
  proc test1() =
    for v in iterSome():
      discard
  test1()

test()

henridf referenced this issue in status-im/nimbus-eth2 Jun 5, 2023
@dxxb
Copy link
Author

dxxb commented Jul 9, 2023

Is there anything I can do to contribute to a solution for this issue? I do not know enough about Nim's compiler internals so I'd need some pointers.

Still happens with:

$ nim -v
Nim Compiler Version 1.9.5 [MacOSX: amd64]
Compiled at 2023-07-08
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 6ec10a4c9182c513fecd17fde4a81a3a007bb2e9
active boot switches: -d:release

@Araq
Copy link
Member

Araq commented Jul 9, 2023

Look into compiler/lambdalifting.nim

@juancarlospaco
Copy link
Collaborator

!nim c

iterator iterSome(): int =
  proc inner1() =
    let something = 6
    proc inner2() =
      let othersomething = something
    inner2()
  for n in 0 .. 1:
    inner1()
    yield n
proc test() =
  proc test1() =
    for v in iterSome(): discard
  test1()
test()

@github-actions
Copy link
Contributor

github-actions bot commented Jul 9, 2023

@juancarlospaco (contributor)

devel :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(4, 10) Error: internal error: inconsistent environment type

Stats

  • Created 2023-07-09T14:12:16Z
  • Started 2023-07-09T14:12:48
  • Finished 2023-07-09T14:12:48
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

AST

nnkStmtList.newTree(
  nnkIteratorDef.newTree(
    newIdentNode("iterSome"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("inner1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("something"),
              newEmptyNode(),
              newLit(6)
            )
          ),
          nnkProcDef.newTree(
            newIdentNode("inner2"),
            newEmptyNode(),
            newEmptyNode(),
            nnkFormalParams.newTree(
              newEmptyNode()
            ),
            newEmptyNode(),
            newEmptyNode(),
            nnkStmtList.newTree(
              nnkLetSection.newTree(
                nnkIdentDefs.newTree(
                  newIdentNode("othersomething"),
                  newEmptyNode(),
                  newIdentNode("something")
                )
              )
            )
          ),
          nnkCall.newTree(
            newIdentNode("inner2")
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("n"),
        nnkInfix.newTree(
          newIdentNode(".."),
          newLit(0),
          newLit(1)
        ),
        nnkStmtList.newTree(
          nnkCall.newTree(
            newIdentNode("inner1")
          ),
          nnkYieldStmt.newTree(
            newIdentNode("n")
          )
        )
      )
    )
  ),
  nnkProcDef.newTree(
    newIdentNode("test"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("test1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkForStmt.newTree(
            newIdentNode("v"),
            nnkCall.newTree(
              newIdentNode("iterSome")
            ),
            nnkStmtList.newTree(
              nnkDiscardStmt.newTree(
                newEmptyNode()
              )
            )
          )
        )
      ),
      nnkCall.newTree(
        newIdentNode("test1")
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("test")
  )
)
stable :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(4, 10) Error: internal error: inconsistent environment type

Stats

  • Created 2023-07-09T14:12:16Z
  • Started 2023-07-09T14:12:49
  • Finished 2023-07-09T14:12:49
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

AST

nnkStmtList.newTree(
  nnkIteratorDef.newTree(
    newIdentNode("iterSome"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("inner1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("something"),
              newEmptyNode(),
              newLit(6)
            )
          ),
          nnkProcDef.newTree(
            newIdentNode("inner2"),
            newEmptyNode(),
            newEmptyNode(),
            nnkFormalParams.newTree(
              newEmptyNode()
            ),
            newEmptyNode(),
            newEmptyNode(),
            nnkStmtList.newTree(
              nnkLetSection.newTree(
                nnkIdentDefs.newTree(
                  newIdentNode("othersomething"),
                  newEmptyNode(),
                  newIdentNode("something")
                )
              )
            )
          ),
          nnkCall.newTree(
            newIdentNode("inner2")
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("n"),
        nnkInfix.newTree(
          newIdentNode(".."),
          newLit(0),
          newLit(1)
        ),
        nnkStmtList.newTree(
          nnkCall.newTree(
            newIdentNode("inner1")
          ),
          nnkYieldStmt.newTree(
            newIdentNode("n")
          )
        )
      )
    )
  ),
  nnkProcDef.newTree(
    newIdentNode("test"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("test1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkForStmt.newTree(
            newIdentNode("v"),
            nnkCall.newTree(
              newIdentNode("iterSome")
            ),
            nnkStmtList.newTree(
              nnkDiscardStmt.newTree(
                newEmptyNode()
              )
            )
          )
        )
      ),
      nnkCall.newTree(
        newIdentNode("test1")
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("test")
  )
)
1.6.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(4, 10) Error: internal error: inconsistent environment type

Stats

  • Created 2023-07-09T14:12:16Z
  • Started 2023-07-09T14:12:52
  • Finished 2023-07-09T14:12:53
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

AST

nnkStmtList.newTree(
  nnkIteratorDef.newTree(
    newIdentNode("iterSome"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("inner1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("something"),
              newEmptyNode(),
              newLit(6)
            )
          ),
          nnkProcDef.newTree(
            newIdentNode("inner2"),
            newEmptyNode(),
            newEmptyNode(),
            nnkFormalParams.newTree(
              newEmptyNode()
            ),
            newEmptyNode(),
            newEmptyNode(),
            nnkStmtList.newTree(
              nnkLetSection.newTree(
                nnkIdentDefs.newTree(
                  newIdentNode("othersomething"),
                  newEmptyNode(),
                  newIdentNode("something")
                )
              )
            )
          ),
          nnkCall.newTree(
            newIdentNode("inner2")
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("n"),
        nnkInfix.newTree(
          newIdentNode(".."),
          newLit(0),
          newLit(1)
        ),
        nnkStmtList.newTree(
          nnkCall.newTree(
            newIdentNode("inner1")
          ),
          nnkYieldStmt.newTree(
            newIdentNode("n")
          )
        )
      )
    )
  ),
  nnkProcDef.newTree(
    newIdentNode("test"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("test1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkForStmt.newTree(
            newIdentNode("v"),
            nnkCall.newTree(
              newIdentNode("iterSome")
            ),
            nnkStmtList.newTree(
              nnkDiscardStmt.newTree(
                newEmptyNode()
              )
            )
          )
        )
      ),
      nnkCall.newTree(
        newIdentNode("test1")
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("test")
  )
)
1.4.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(4, 10) Error: internal error: inconsistent environment type

Stats

  • Created 2023-07-09T14:12:16Z
  • Started 2023-07-09T14:12:55
  • Finished 2023-07-09T14:12:56
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

AST

nnkStmtList.newTree(
  nnkIteratorDef.newTree(
    newIdentNode("iterSome"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("inner1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("something"),
              newEmptyNode(),
              newLit(6)
            )
          ),
          nnkProcDef.newTree(
            newIdentNode("inner2"),
            newEmptyNode(),
            newEmptyNode(),
            nnkFormalParams.newTree(
              newEmptyNode()
            ),
            newEmptyNode(),
            newEmptyNode(),
            nnkStmtList.newTree(
              nnkLetSection.newTree(
                nnkIdentDefs.newTree(
                  newIdentNode("othersomething"),
                  newEmptyNode(),
                  newIdentNode("something")
                )
              )
            )
          ),
          nnkCall.newTree(
            newIdentNode("inner2")
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("n"),
        nnkInfix.newTree(
          newIdentNode(".."),
          newLit(0),
          newLit(1)
        ),
        nnkStmtList.newTree(
          nnkCall.newTree(
            newIdentNode("inner1")
          ),
          nnkYieldStmt.newTree(
            newIdentNode("n")
          )
        )
      )
    )
  ),
  nnkProcDef.newTree(
    newIdentNode("test"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("test1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkForStmt.newTree(
            newIdentNode("v"),
            nnkCall.newTree(
              newIdentNode("iterSome")
            ),
            nnkStmtList.newTree(
              nnkDiscardStmt.newTree(
                newEmptyNode()
              )
            )
          )
        )
      ),
      nnkCall.newTree(
        newIdentNode("test1")
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("test")
  )
)
1.2.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(4, 10) Error: internal error: inconsistent environment type

Stats

  • Created 2023-07-09T14:12:16Z
  • Started 2023-07-09T14:13:11
  • Finished 2023-07-09T14:13:11
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

AST

nnkStmtList.newTree(
  nnkIteratorDef.newTree(
    newIdentNode("iterSome"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("inner1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("something"),
              newEmptyNode(),
              newLit(6)
            )
          ),
          nnkProcDef.newTree(
            newIdentNode("inner2"),
            newEmptyNode(),
            newEmptyNode(),
            nnkFormalParams.newTree(
              newEmptyNode()
            ),
            newEmptyNode(),
            newEmptyNode(),
            nnkStmtList.newTree(
              nnkLetSection.newTree(
                nnkIdentDefs.newTree(
                  newIdentNode("othersomething"),
                  newEmptyNode(),
                  newIdentNode("something")
                )
              )
            )
          ),
          nnkCall.newTree(
            newIdentNode("inner2")
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("n"),
        nnkInfix.newTree(
          newIdentNode(".."),
          newLit(0),
          newLit(1)
        ),
        nnkStmtList.newTree(
          nnkCall.newTree(
            newIdentNode("inner1")
          ),
          nnkYieldStmt.newTree(
            newIdentNode("n")
          )
        )
      )
    )
  ),
  nnkProcDef.newTree(
    newIdentNode("test"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("test1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkForStmt.newTree(
            newIdentNode("v"),
            nnkCall.newTree(
              newIdentNode("iterSome")
            ),
            nnkStmtList.newTree(
              nnkDiscardStmt.newTree(
                newEmptyNode()
              )
            )
          )
        )
      ),
      nnkCall.newTree(
        newIdentNode("test1")
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("test")
  )
)
1.0.0 :-1: FAIL

Output

Error: Command failed: nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off  --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim
/home/runner/work/Nim/Nim/temp.nim(4, 10) Error: internal error: inconsistent environment type

Stats

  • Created 2023-07-09T14:12:16Z
  • Started 2023-07-09T14:13:24
  • Finished 2023-07-09T14:13:24
  • Duration now
  • Commands nim c --run -d:strip -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --threads:off --verbosity:0 --hints:off --warnings:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

IR

AST

nnkStmtList.newTree(
  nnkIteratorDef.newTree(
    newIdentNode("iterSome"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newIdentNode("int")
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("inner1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkLetSection.newTree(
            nnkIdentDefs.newTree(
              newIdentNode("something"),
              newEmptyNode(),
              newLit(6)
            )
          ),
          nnkProcDef.newTree(
            newIdentNode("inner2"),
            newEmptyNode(),
            newEmptyNode(),
            nnkFormalParams.newTree(
              newEmptyNode()
            ),
            newEmptyNode(),
            newEmptyNode(),
            nnkStmtList.newTree(
              nnkLetSection.newTree(
                nnkIdentDefs.newTree(
                  newIdentNode("othersomething"),
                  newEmptyNode(),
                  newIdentNode("something")
                )
              )
            )
          ),
          nnkCall.newTree(
            newIdentNode("inner2")
          )
        )
      ),
      nnkForStmt.newTree(
        newIdentNode("n"),
        nnkInfix.newTree(
          newIdentNode(".."),
          newLit(0),
          newLit(1)
        ),
        nnkStmtList.newTree(
          nnkCall.newTree(
            newIdentNode("inner1")
          ),
          nnkYieldStmt.newTree(
            newIdentNode("n")
          )
        )
      )
    )
  ),
  nnkProcDef.newTree(
    newIdentNode("test"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkProcDef.newTree(
        newIdentNode("test1"),
        newEmptyNode(),
        newEmptyNode(),
        nnkFormalParams.newTree(
          newEmptyNode()
        ),
        newEmptyNode(),
        newEmptyNode(),
        nnkStmtList.newTree(
          nnkForStmt.newTree(
            newIdentNode("v"),
            nnkCall.newTree(
              newIdentNode("iterSome")
            ),
            nnkStmtList.newTree(
              nnkDiscardStmt.newTree(
                newEmptyNode()
              )
            )
          )
        )
      ),
      nnkCall.newTree(
        newIdentNode("test1")
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("test")
  )
)
🤖 Bug found in 39 minutes bisecting 6 commits at 0 commits per second.

@dxxb
Copy link
Author

dxxb commented Jul 9, 2023

Thank you @Araq. I guess I should have been more specific when I asked for pointers. I had found where the error came from (addClosureParam() in compiler/lambdalifting.nim) and figured the case of an inner function inside an iterator is not supported by the current implementation for some reason.

I see the environment for inner1() is an :envP@... and the environement for the iterator is iterSome@....

If I comment out the localError() call from addClosureParam() compilation succeeds and the resulting executable runs OK, but surely the solution cannot be that easy: localError() must have been there for a reason.

@Araq
Copy link
Member

Araq commented Jul 10, 2023

but surely the solution cannot be that easy

It can be that easy. However! We need to investigate why

  var cp = getEnvParam(fn)
  let owner = if fn.kind == skIterator: fn else: fn.skipGenericOwner
  let t = c.getEnvTypeForOwner(owner, info)

cp.typ and t might differ and if they do, which one to pick. Ideally there is only one type that should be used, always, consistently. But I don't remember the code well enough to say for sure.

@dxxb
Copy link
Author

dxxb commented Jul 10, 2023

FYI at the point where the error is emitted inner1() fn.kind == skProc

cp.typ:

kind: tyRef, callConv: nimcall, flags: {tfHasAsgn, tfCheckedForDestructor},
sons: @[
  (kind: tyObject, callConv: nimcall, flags: {tfCheckedForDestructor},
    sons: @[(kind: tyObject, callConv: nimcall, flags: {tfInheritable},
      sons: @[nil],
    owner: system@33554432, sym: RootObj@33555817, loc: ..., typeInst: nil, uniqueId: (module: 2, item: 768))],
  owner: iterSome@1056964609, sym: Env_innerprociter.nim_iterSome@1056964622, loc: ..., typeInst: nil, uniqueId: (module: 63, item: 19))],
owner: iterSome@1056964609, sym: nil, loc: ..., typeInst: nil, uniqueId: (module: 63, item: 18)

t:

kind: tyRef, callConv: nimcall, flags: {},
sons: @[
  (kind: tyObject, callConv: nimcall, flags: {},
    sons: @[(kind: tyObject, callConv: nimcall, flags: {tfInheritable},
      sons: @[nil],
    owner: system@33554432, sym: RootObj@33555817, loc: ..., typeInst: nil, uniqueId: (module: 2, item: 768))],
  owner: iterSome@1056964609, sym: Env_innerprociter.nim_iterSome@1056964717, loc: ..., typeInst: nil, uniqueId: (module: 63, item: 68))],
owner: iterSome@1056964609, sym: nil, loc: ..., typeInst: nil, uniqueId: (module: 63, item: 67)

Different TTypes same owner. Is t is supposed to be different in this case? The presence of cp.typ != t and fn.kind != skIterator suggests the asnwer is no. If so does the problem originate wherever the type of the environment for inner1() is decided/assigned?

@Araq
Copy link
Member

Araq commented Jul 10, 2023

If so does the problem originate wherever the type of the environment for inner1() is decided/assigned?

Seems like it.

@dxxb
Copy link
Author

dxxb commented Jul 10, 2023

Digging a bit more I found the following:

-> liftLambdas() on test()
   ...
   -> liftLambdas() on iterSome()
        ...
	addClosureParam() on inner1() skProc, cp is `nil` so a new cp is created and stored in the lookup table
   ...
   <- liftLambdas() on iterSome()
   ...
   addClosureParam() on inner1() skProc, cp is not `nil` but when looking uit up by ID the value is different.
   `Error: internal error: inconsistent environment type`

Note that liftLambdas() is called recursively via transformBody() and upon entering liftLambdas() a new DetectionPass variable is initialized (so the env type lookup table used by the inner liftLambdas() is not the same as the outer one).

Traceback (most recent call last)
Nim/compiler/nim.nim(164) nim
Nim/compiler/nim.nim(119) handleCmdLine
Nim/compiler/main.nim(307) mainCommand
Nim/compiler/main.nim(276) compileToBackend
Nim/compiler/main.nim(138) commandCompileToC
Nim/compiler/pipelines.nim(294) compilePipelineProject
Nim/compiler/pipelines.nim(224) compilePipelineModule
Nim/compiler/pipelines.nim(172) processPipelineModule
Nim/compiler/pipelines.nim(24) processPipeline
Nim/compiler/cgen.nim(2097) genTopLevelStmt
Nim/compiler/cgen.nim(1136) genProcBody
Nim/compiler/ccgstmts.nim(1650) genStmts
Nim/compiler/ccgexprs.nim(3094) expr
Nim/compiler/ccgexprs.nim(2788) genStmtList
Nim/compiler/ccgstmts.nim(1650) genStmts
Nim/compiler/ccgexprs.nim(3047) expr
Nim/compiler/ccgcalls.nim genCall
Nim/compiler/ccgcalls.nim(832) genAsgnCall
Nim/compiler/ccgcalls.nim(425) genPrefixCall
Nim/compiler/cgen.nim(740) initLocExpr
Nim/compiler/ccgexprs.nim(2966) expr
Nim/compiler/cgen.nim(1369) genProc
Nim/compiler/cgen.nim(1343) genProcNoForward
Nim/compiler/cgen.nim(1155) genProcAux
Nim/compiler/transf.nim(1197) transformBody
Nim/compiler/lambdalifting.nim(893) liftLambdas
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(458) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(527) detectCapturedVars
Nim/compiler/lambdalifting.nim(450) detectCapturedVars
Nim/compiler/lambdalifting.nim(439) addClosureParam
Nim/compiler/msgs.nim(581) liMessage
Nim/compiler/msgs.nim(440) handleError
Nim/compiler/msgs.nim(421) quit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants