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

internal error: environment misses #9476

Closed
bluenote10 opened this issue Oct 23, 2018 · 4 comments

Comments

Projects
None yet
4 participants
@bluenote10
Copy link
Contributor

commented Oct 23, 2018

It looks like there was a recent regression causing an internal error: environment misses in the following code (code from kadro, simplified to a point where the code doesn't make much sense anymore). The code used to compile without problems ~1 week ago.

Is this a regression or was this never supposed to work?

Example

import macros
import tables


proc getTypeInfo*(T: typedesc): pointer =
  var dummy: T
  getTypeInfo(dummy)


macro implementUnary(op: untyped): untyped =
  result = newStmtList()

  template defineTable(tableSymbol) =
    var tableSymbol = initTable[pointer, pointer]()
  let tableSymbol = genSym(nskVar, "registeredProcs")
  result.add(getAst(defineTable(tableSymbol)))

  template defineRegisterInstantiation(tableSym, regTemplSym, instSym, op) =
    template regTemplSym*(T: typedesc) =
      let ti = getTypeInfo(T)

      proc instSym*(xOrig: int): int {.gensym.} =
        let x {.inject.} = xOrig
        op

      tableSym[ti] = cast[pointer](instSym)

  let regTemplSymbol = ident("registerInstantiation")
  let instSymbol = ident("instantiation")
  result.add(getAst(defineRegisterInstantiation(
    tableSymbol, regTemplSymbol, instSymbol, op
  )))

  echo result.repr


implementUnary(): x*x

registerInstantiation(int)
registerInstantiation(float)

Current Output

var registeredProcs243087 = initTable[pointer, pointer]()
template registerInstantiation*(T243089: typedesc) =
  let ti243091 = getTypeInfo(T243089)
  proc instantiation(xOrig243093: int): int {.gensym.} =
    let x {.inject.} = xOrig243093
    x * x

  []=(registeredProcs243087, ti243091, cast[pointer](instantiation))

p_columns_ops_untyped.nim(23, 28) Error: internal error: environment misses: xOrig

Expected Output

No error.

Additional Information

I'm getting the error with Nim version:

Compiled at 2018-10-21
Copyright (c) 2006-2018 by Andreas Rumpf

git hash: ce05a850a55a651bcdd01e7af9af9702c8af5caf

The code used to work with:

Compiled at 2018-10-12
Copyright (c) 2006-2018 by Andreas Rumpf

git hash: fcca59e415fe2f3ccbd5c4a977b65305e80f83e8

git bisect points to eaca5be:

eaca5be9d6e205e8aa7055306122a6c053ef35a6 is the first bad commit
commit eaca5be9d6e205e8aa7055306122a6c053ef35a6
Author: cooldome <cdome@bk.ru>
Date:   Thu Oct 18 19:21:25 2018 +0100

    Change the order of compilation passes, transformation is made lazy at code gen (#8489)
    
    * Ast no transformation
    * Add getImplNoTransform to the macros module
    * progress on delaying transf
    * Fix methods tranformation
    * Fix lazy lambdalifting
    * fix create thread wrapper
    * transform for lambda lifting
    * improve getImplTransformed
    * Fix destructor tests
    * try to fix nimprof for linux

:040000 040000 836f6523121d68eebe1fe6b6e7473f9a290226a5 33193e6df5b39fd1adcab3c74f1222118aa62887 M	compiler
:040000 040000 30e07ca878120a88c8bf230fb5dc8d66be82aabe 71233c3d231cec7240139302608b065f67dce517 M	lib
:040000 040000 8b7af2cf6bcfa886a5a5dd4d072a9447857c3898 a82028b03e6ead67ae51dd31b8fd20979e0aaf3e M	tests

Traceback

Traceback (most recent call last)
nim.nim(108)             nim
nim.nim(72)              handleCmdLine
cmdlinehelper.nim(91)    loadConfigsAndRunMainCommand
main.nim(163)            mainCommand
main.nim(74)             commandCompileToC
modules.nim(126)         compileProject
modules.nim(71)          compileModule
passes.nim(194)          processModule
passes.nim(86)           processTopLevelStmt
cgen.nim(1528)           myProcess
ccgstmts.nim(1160)       genStmts
ccgexprs.nim(2391)       expr
ccgexprs.nim(2173)       genStmtList
ccgstmts.nim(1160)       genStmts
ccgexprs.nim(2391)       expr
ccgexprs.nim(2184)       genStmtList
ccgstmts.nim(1160)       genStmts
ccgexprs.nim(2355)       expr
ccgcalls.nim(552)        genCall
ccgcalls.nim(191)        genPrefixCall
ccgcalls.nim(174)        genArg
cgen.nim(506)            initLocExprSingleUse
ccgexprs.nim(2294)       expr
cgen.nim(1026)           genProc
cgen.nim(991)            genProcNoForward
cgen.nim(848)            genProcAux
transf.nim(1043)         transformBody
lambdalifting.nim(776)   liftLambdas
lambdalifting.nim(717)   liftCapturedVars
lambdalifting.nim(717)   liftCapturedVars
lambdalifting.nim(717)   liftCapturedVars
lambdalifting.nim(717)   liftCapturedVars
lambdalifting.nim(669)   liftCapturedVars
lambdalifting.nim(498)   accessViaEnvParam
msgs.nim(519)            localError
msgs.nim(501)            liMessage
msgs.nim(329)            handleError
msgs.nim(314)            quit
FAILURE

@Araq Araq added the Regression label Oct 23, 2018

@Araq

This comment has been minimized.

Copy link
Member

commented Oct 23, 2018

Well as you noticed we did another big compiler refactoring for the better and are dealing with the fallout. :-)

@cooldome

This comment has been minimized.

Copy link
Member

commented Nov 8, 2018

Looks like lambda lifting kicked in while it should not. there is no closures in generated example above

@krux02 krux02 self-assigned this Dec 6, 2018

@krux02

This comment has been minimized.

Copy link
Contributor

commented Dec 6, 2018

While I was tweaking on it to find out wher the problem is introduced, I found a version of the same code that does work:

proc getTypeInfo*(T: typedesc): pointer =
  var dummy: T
  getTypeInfo(dummy)

macro implementUnary(op: untyped): untyped =
  result = newStmtList()

  let tableSymbol = genSym(nskVar, "registeredProcs")
  let instSymbol = genSym(nskProc, "instantiation")
  let regTemplSymbol = ident("registerInstantiation")

  result.add quote do:
    var `tableSymbol` = initTable[pointer, pointer]()

  result.add quote do:
    template `regTemplSymbol`(T: typedesc) =
      let ti = getTypeInfo(T)

      proc `instSymbol`(xOrig: int): int =
        let x {.inject.} = xOrig
        `op`

      `tableSymbol`[ti] = cast[pointer](`instSymbol`)

  echo result.repr

implementUnary():
    x*x

registerInstantiation(int)
registerInstantiation(float)

I basically replaced the local template/getAst construct with quote do and explicit injection via backticks. I also replaced the {.gensym.} pragma with an explicit call to genSym.

@krux02

This comment has been minimized.

Copy link
Contributor

commented Dec 6, 2018

I just tried to move the implementation to a version that does not rely on macros, but uses templates only. This is how far I got:

import macros, tables

proc getTypeInfo*(T: typedesc): pointer =
  var dummy: T
  getTypeInfo(dummy)

template defineTable(tableSymbol) =
  var tableSymbol = initTable[pointer, pointer]()

template defineRegisterInstantiation(tableSym, regTemplSym, op: untyped) =
  template regTemplSym(T: typedesc) =
    let ti = getTypeInfo(T)

    proc instSym(xOrig: int): int {.cdecl, genSym.} =
      let x {.inject.} = xOrig
      op

    tableSym[ti] = cast[pointer](instSym)

template implementUnary(op: untyped): untyped =
  defineTable(registeredProcs)
  defineRegisterInstantiation(registeredProcs, registerInstantiation, op)

implementUnary():
  x * x

registerInstantiation(int)
registerInstantiation(float)

But it doesn't compile:

scratch.nim(27, 22) template/generic instantiation of `registerInstantiation` from here
scratch.nim(18, 34) Error: expression 'instSym241230' has no type (or is ambiguous)

This could be a different bug.

@Araq Araq closed this in e874705 Dec 9, 2018

Araq added a commit that referenced this issue Dec 9, 2018

Merge pull request #9912 from nim-lang/araq-fixes-nested-gensym
fixes nested gensym'ed parameters; fixes #9476
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.