Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-4683

DelayedInit crashes following $outer pointers

    Details

      Description

      [Elided, replaced.]

      class DelayedInitTest {
        def a = ()
        class B extends DelayedInit {
          a
          def delayedInit(body: => Unit) = ()
        }
      }
       
      scalac3 ./a.scala 
      error: java.lang.Error: symbol value $outer does not exist in DelayedInitTest$B$delayedInit$body.apply
      	at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:31)
      	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:1027)
      	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadQualifier(GenICode.scala:1175)
      	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:921)
      	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genStat(GenICode.scala:174)
      

        Attachments

          Issue Links

            Activity

            Hide
            retronym Jason Zaugg added a comment -

            One more example:

            class Entity extends DelayedInit {
             
              def delayedInit(x: => Unit) {x}
             
              class Field
             
              protected def EntityField[T <: Entity: Manifest] = new Field
             
              def find[T <: Entity: Manifest] {
                Nil.map(dbo => {
                  class EntityHolder extends Entity {
                    val entity = EntityField[T]
                  }
                })
              }
             
            }
            

            Show
            retronym Jason Zaugg added a comment - One more example: class Entity extends DelayedInit { def delayedInit(x: => Unit) {x} class Field protected def EntityField[T <: Entity: Manifest] = new Field def find[T <: Entity: Manifest] { Nil.map(dbo => { class EntityHolder extends Entity { val entity = EntityField[T] } }) } }
            Hide
            tchamberlain Thornton Chamberlain added a comment -

            The following looks like it may be yet another manifestation of the same problem:

            trait T extends DelayedInit {
              def delayedInit(body: => Unit) = {
                println("In delayedInit")
                body
              }
            }
            val f = {(p1: Int) => new T{println(p1)}}
            f(5)
            

            In 2.10.3, this fails with 'error: symbol value p1$1 does not exist in $anonfun$1$$anon$1$delayedInit$body.apply'

            I encountered this when trying to use a Specs2 After context with a data table.

            Show
            tchamberlain Thornton Chamberlain added a comment - The following looks like it may be yet another manifestation of the same problem: trait T extends DelayedInit { def delayedInit(body: => Unit) = { println("In delayedInit") body } } val f = {(p1: Int) => new T{println(p1)}} f(5) In 2.10.3, this fails with 'error: symbol value p1$1 does not exist in $anonfun$1$$anon$1$delayedInit$body.apply' I encountered this when trying to use a Specs2 After context with a data table.
            Hide
            retronym Jason Zaugg added a comment -

            The problem there is that the DelayedInit transformation happens in the 'constructors' compiler phase, by which point the prior 'lambdalift' phase has already decided that `p2` need not be retained in the anonymous subclass as `T` as a field. Looks mighty tricky to fix. I would recommend against building on top of DelayedInit.

            Show
            retronym Jason Zaugg added a comment - The problem there is that the DelayedInit transformation happens in the 'constructors' compiler phase, by which point the prior 'lambdalift' phase has already decided that `p2` need not be retained in the anonymous subclass as `T` as a field. Looks mighty tricky to fix. I would recommend against building on top of DelayedInit.
            Hide
            retronym Jason Zaugg added a comment -

            Another example:

                class C extends DelayedInit {
                  def delayedInit(body: => Unit) {}
                }
                class Injector {
                  def test = {
                    val name = ""
                    class crash extends C {
                      println(name)
                    }
                  }
                }
            

            Show
            retronym Jason Zaugg added a comment - Another example: class C extends DelayedInit { def delayedInit(body: => Unit) {} } class Injector { def test = { val name = "" class crash extends C { println(name) } } }
            Show
            rytz Lukas Rytz added a comment - https://github.com/scala/scala/pull/5423

              People

              • Assignee:
                rytz Lukas Rytz
                Reporter:
                fwbrasil Flávio W. Brasil
              • Votes:
                14 Vote for this issue
                Watchers:
                20 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: